aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/gaccess.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kvm/gaccess.c')
-rw-r--r--arch/s390/kvm/gaccess.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index a7559f7207df..d30db40437dc 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -259,10 +259,14 @@ struct aste {
259 259
260int ipte_lock_held(struct kvm_vcpu *vcpu) 260int ipte_lock_held(struct kvm_vcpu *vcpu)
261{ 261{
262 union ipte_control *ic = &vcpu->kvm->arch.sca->ipte_control; 262 if (vcpu->arch.sie_block->eca & 1) {
263 int rc;
263 264
264 if (vcpu->arch.sie_block->eca & 1) 265 read_lock(&vcpu->kvm->arch.sca_lock);
265 return ic->kh != 0; 266 rc = kvm_s390_get_ipte_control(vcpu->kvm)->kh != 0;
267 read_unlock(&vcpu->kvm->arch.sca_lock);
268 return rc;
269 }
266 return vcpu->kvm->arch.ipte_lock_count != 0; 270 return vcpu->kvm->arch.ipte_lock_count != 0;
267} 271}
268 272
@@ -274,16 +278,20 @@ static void ipte_lock_simple(struct kvm_vcpu *vcpu)
274 vcpu->kvm->arch.ipte_lock_count++; 278 vcpu->kvm->arch.ipte_lock_count++;
275 if (vcpu->kvm->arch.ipte_lock_count > 1) 279 if (vcpu->kvm->arch.ipte_lock_count > 1)
276 goto out; 280 goto out;
277 ic = &vcpu->kvm->arch.sca->ipte_control; 281retry:
282 read_lock(&vcpu->kvm->arch.sca_lock);
283 ic = kvm_s390_get_ipte_control(vcpu->kvm);
278 do { 284 do {
279 old = READ_ONCE(*ic); 285 old = READ_ONCE(*ic);
280 while (old.k) { 286 if (old.k) {
287 read_unlock(&vcpu->kvm->arch.sca_lock);
281 cond_resched(); 288 cond_resched();
282 old = READ_ONCE(*ic); 289 goto retry;
283 } 290 }
284 new = old; 291 new = old;
285 new.k = 1; 292 new.k = 1;
286 } while (cmpxchg(&ic->val, old.val, new.val) != old.val); 293 } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
294 read_unlock(&vcpu->kvm->arch.sca_lock);
287out: 295out:
288 mutex_unlock(&vcpu->kvm->arch.ipte_mutex); 296 mutex_unlock(&vcpu->kvm->arch.ipte_mutex);
289} 297}
@@ -296,12 +304,14 @@ static void ipte_unlock_simple(struct kvm_vcpu *vcpu)
296 vcpu->kvm->arch.ipte_lock_count--; 304 vcpu->kvm->arch.ipte_lock_count--;
297 if (vcpu->kvm->arch.ipte_lock_count) 305 if (vcpu->kvm->arch.ipte_lock_count)
298 goto out; 306 goto out;
299 ic = &vcpu->kvm->arch.sca->ipte_control; 307 read_lock(&vcpu->kvm->arch.sca_lock);
308 ic = kvm_s390_get_ipte_control(vcpu->kvm);
300 do { 309 do {
301 old = READ_ONCE(*ic); 310 old = READ_ONCE(*ic);
302 new = old; 311 new = old;
303 new.k = 0; 312 new.k = 0;
304 } while (cmpxchg(&ic->val, old.val, new.val) != old.val); 313 } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
314 read_unlock(&vcpu->kvm->arch.sca_lock);
305 wake_up(&vcpu->kvm->arch.ipte_wq); 315 wake_up(&vcpu->kvm->arch.ipte_wq);
306out: 316out:
307 mutex_unlock(&vcpu->kvm->arch.ipte_mutex); 317 mutex_unlock(&vcpu->kvm->arch.ipte_mutex);
@@ -311,24 +321,29 @@ static void ipte_lock_siif(struct kvm_vcpu *vcpu)
311{ 321{
312 union ipte_control old, new, *ic; 322 union ipte_control old, new, *ic;
313 323
314 ic = &vcpu->kvm->arch.sca->ipte_control; 324retry:
325 read_lock(&vcpu->kvm->arch.sca_lock);
326 ic = kvm_s390_get_ipte_control(vcpu->kvm);
315 do { 327 do {
316 old = READ_ONCE(*ic); 328 old = READ_ONCE(*ic);
317 while (old.kg) { 329 if (old.kg) {
330 read_unlock(&vcpu->kvm->arch.sca_lock);
318 cond_resched(); 331 cond_resched();
319 old = READ_ONCE(*ic); 332 goto retry;
320 } 333 }
321 new = old; 334 new = old;
322 new.k = 1; 335 new.k = 1;
323 new.kh++; 336 new.kh++;
324 } while (cmpxchg(&ic->val, old.val, new.val) != old.val); 337 } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
338 read_unlock(&vcpu->kvm->arch.sca_lock);
325} 339}
326 340
327static void ipte_unlock_siif(struct kvm_vcpu *vcpu) 341static void ipte_unlock_siif(struct kvm_vcpu *vcpu)
328{ 342{
329 union ipte_control old, new, *ic; 343 union ipte_control old, new, *ic;
330 344
331 ic = &vcpu->kvm->arch.sca->ipte_control; 345 read_lock(&vcpu->kvm->arch.sca_lock);
346 ic = kvm_s390_get_ipte_control(vcpu->kvm);
332 do { 347 do {
333 old = READ_ONCE(*ic); 348 old = READ_ONCE(*ic);
334 new = old; 349 new = old;
@@ -336,6 +351,7 @@ static void ipte_unlock_siif(struct kvm_vcpu *vcpu)
336 if (!new.kh) 351 if (!new.kh)
337 new.k = 0; 352 new.k = 0;
338 } while (cmpxchg(&ic->val, old.val, new.val) != old.val); 353 } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
354 read_unlock(&vcpu->kvm->arch.sca_lock);
339 if (!new.kh) 355 if (!new.kh)
340 wake_up(&vcpu->kvm->arch.ipte_wq); 356 wake_up(&vcpu->kvm->arch.ipte_wq);
341} 357}