@@ -76,6 +76,8 @@ static void set_status32(CPUARCState *env, target_ulong value)
76
76
#endif
77
77
}
78
78
79
+ static pthread_t last_thread_access ;
80
+
79
81
target_ulong helper_llock (CPUARCState * env , target_ulong addr )
80
82
{
81
83
assert ((addr & 0x3 ) == 0 );
@@ -94,6 +96,11 @@ target_ulong helper_llock(CPUARCState *env, target_ulong addr)
94
96
entry -> lpa_lf = (haddr & (~LPA_LFS_ALIGNEMENT_MASK ));
95
97
entry -> lpa_lf += 1 ; /* least significant bit is LF flag */
96
98
entry -> read_value = ret ;
99
+
100
+ #ifdef CONFIG_USER_ONLY
101
+ last_thread_access = pthread_self ();
102
+ #endif
103
+
97
104
qemu_mutex_unlock (& entry -> mutex );
98
105
return ret ;
99
106
}
@@ -114,6 +121,15 @@ target_ulong helper_scond(CPUARCState *env, target_ulong addr, target_ulong valu
114
121
(target_ulong ) haddr , (int ) LPA_LFS_ENTRY_FOR_PA (haddr ));
115
122
qemu_mutex_lock (env -> arconnect .locked_mutex );
116
123
struct lpa_lf_entry * entry = env -> arconnect .lpa_lf ;
124
+
125
+ // usermode interrupts don't clear Lock Flag, so we must do so ourselves
126
+ #ifdef CONFIG_USER_ONLY
127
+ pthread_t current_thread = pthread_self ();
128
+ if (last_thread_access != current_thread ) {
129
+ entry -> lpa_lf &= -2 ;
130
+ }
131
+ #endif
132
+
117
133
haddr = (haddr & (~LPA_LFS_ALIGNEMENT_MASK ));
118
134
target_ulong ret = 1 ;
119
135
target_ulong rvalue = cpu_ldl_data_ra (env , addr , GETPC ());
@@ -151,6 +167,11 @@ target_ulong helper_llockl(CPUARCState *env, target_ulong addr)
151
167
entry -> lpa_lf = (haddr & (~LPA_LFS_ALIGNEMENT_MASK ));
152
168
entry -> lpa_lf += 1 ; /* least significant bit is LF flag */
153
169
entry -> read_value = ret ;
170
+
171
+ #ifdef CONFIG_USER_ONLY
172
+ last_thread_access = pthread_self ();
173
+ #endif
174
+
154
175
qemu_mutex_unlock (& entry -> mutex );
155
176
return ret ;
156
177
}
@@ -163,8 +184,17 @@ target_ulong helper_scondl(CPUARCState *env, target_ulong addr, target_ulong val
163
184
qemu_log_mask (LOG_UNIMP , "0x" TARGET_FMT_lx "SCONDL at addr 0x" TARGET_FMT_lx " at index %d\n" ,
164
185
env -> pc ,
165
186
(target_ulong ) haddr , (int ) LPA_LFS_ENTRY_FOR_PA (haddr ));
166
- struct lpa_lf_entry * entry = env -> arconnect .lpa_lf ;
167
187
qemu_mutex_lock (env -> arconnect .locked_mutex );
188
+ struct lpa_lf_entry * entry = env -> arconnect .lpa_lf ;
189
+
190
+ // usermode interrupts don't clear Lock Flag, so we must do so ourselves
191
+ #ifdef CONFIG_USER_ONLY
192
+ pthread_t current_thread = pthread_self ();
193
+ if (last_thread_access != current_thread ) {
194
+ entry -> lpa_lf &= -2 ;
195
+ }
196
+ #endif
197
+
168
198
target_ulong ret = 1 ;
169
199
haddr = (haddr & (~LPA_LFS_ALIGNEMENT_MASK ));
170
200
target_ulong rvalue = cpu_ldq_data_ra (env , addr , GETPC ());
@@ -197,6 +227,10 @@ uint64_t helper_llockd(CPUARCState *env, target_ulong addr)
197
227
entry -> lpa_lf += 1 ; /* least significant bit is LF flag */
198
228
entry -> read_value = ret ;
199
229
230
+ #ifdef CONFIG_USER_ONLY
231
+ last_thread_access = pthread_self ();
232
+ #endif
233
+
200
234
qemu_mutex_unlock (& entry -> mutex );
201
235
202
236
return ret ;
@@ -207,8 +241,17 @@ target_ulong helper_scondd(CPUARCState *env, target_ulong addr, uint64_t value)
207
241
hwaddr haddr ;
208
242
CPUState * cs = env_cpu (env );
209
243
arc_get_physical_addr (cs , & haddr , addr , MMU_MEM_WRITE , false, GETPC ());
210
- struct lpa_lf_entry * entry = env -> arconnect .lpa_lf ;
211
244
qemu_mutex_lock (env -> arconnect .locked_mutex );
245
+ struct lpa_lf_entry * entry = env -> arconnect .lpa_lf ;
246
+
247
+ // usermode interrupts don't clear Lock Flag, so we must do so ourselves
248
+ #ifdef CONFIG_USER_ONLY
249
+ pthread_t current_thread = pthread_self ();
250
+ if (last_thread_access != current_thread ) {
251
+ entry -> lpa_lf &= -2 ;
252
+ }
253
+ #endif
254
+
212
255
target_ulong ret = 1 ;
213
256
addr = (addr & (~LPA_LFS_ALIGNEMENT_MASK ));
214
257
0 commit comments