Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: s390: get rid of local_int array

We can use kvm_get_vcpu() now and don't need the
local_int array in the floating_int struct anymore.
This also means we don't have to hold the float_int.lock
in some places.

Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>

authored by

Jens Freimann and committed by
Christian Borntraeger
1ee0bc55 13b191ae

+56 -80
-1
arch/s390/include/asm/kvm_host.h
··· 215 215 int next_rr_cpu; 216 216 unsigned long idle_mask[(KVM_MAX_VCPUS + sizeof(long) - 1) 217 217 / sizeof(long)]; 218 - struct kvm_s390_local_interrupt *local_int[KVM_MAX_VCPUS]; 219 218 unsigned int irq_count; 220 219 }; 221 220
+4 -2
arch/s390/kvm/interrupt.c
··· 692 692 struct kvm_s390_local_interrupt *li; 693 693 struct kvm_s390_float_interrupt *fi; 694 694 struct kvm_s390_interrupt_info *iter; 695 + struct kvm_vcpu *dst_vcpu = NULL; 695 696 int sigcpu; 696 697 int rc = 0; 697 698 ··· 727 726 sigcpu = fi->next_rr_cpu++; 728 727 if (sigcpu == KVM_MAX_VCPUS) 729 728 sigcpu = fi->next_rr_cpu = 0; 730 - } while (fi->local_int[sigcpu] == NULL); 729 + } while (kvm_get_vcpu(kvm, sigcpu) == NULL); 731 730 } 732 - li = fi->local_int[sigcpu]; 731 + dst_vcpu = kvm_get_vcpu(kvm, sigcpu); 732 + li = &dst_vcpu->arch.local_int; 733 733 spin_lock_bh(&li->lock); 734 734 atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); 735 735 if (waitqueue_active(li->wq))
+1 -4
arch/s390/kvm/kvm-s390.c
··· 460 460 spin_lock_init(&vcpu->arch.local_int.lock); 461 461 INIT_LIST_HEAD(&vcpu->arch.local_int.list); 462 462 vcpu->arch.local_int.float_int = &kvm->arch.float_int; 463 - spin_lock(&kvm->arch.float_int.lock); 464 - kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int; 465 463 vcpu->arch.local_int.wq = &vcpu->wq; 466 464 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags; 467 - spin_unlock(&kvm->arch.float_int.lock); 468 465 469 466 rc = kvm_vcpu_init(vcpu, kvm, id); 470 467 if (rc) ··· 949 952 950 953 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags); 951 954 952 - BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL); 955 + BUG_ON(kvm_get_vcpu(vcpu->kvm, vcpu->vcpu_id) == NULL); 953 956 954 957 switch (kvm_run->exit_reason) { 955 958 case KVM_EXIT_S390_SIEIC:
+51 -73
arch/s390/kvm/sigp.c
··· 23 23 static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, 24 24 u64 *reg) 25 25 { 26 - struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 26 + struct kvm_s390_local_interrupt *li; 27 + struct kvm_vcpu *dst_vcpu = NULL; 28 + int cpuflags; 27 29 int rc; 28 30 29 31 if (cpu_addr >= KVM_MAX_VCPUS) 30 32 return SIGP_CC_NOT_OPERATIONAL; 31 33 32 - spin_lock(&fi->lock); 33 - if (fi->local_int[cpu_addr] == NULL) 34 - rc = SIGP_CC_NOT_OPERATIONAL; 35 - else if (!(atomic_read(fi->local_int[cpu_addr]->cpuflags) 36 - & (CPUSTAT_ECALL_PEND | CPUSTAT_STOPPED))) 34 + dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 35 + if (!dst_vcpu) 36 + return SIGP_CC_NOT_OPERATIONAL; 37 + li = &dst_vcpu->arch.local_int; 38 + 39 + cpuflags = atomic_read(li->cpuflags); 40 + if (!(cpuflags & (CPUSTAT_ECALL_PEND | CPUSTAT_STOPPED))) 37 41 rc = SIGP_CC_ORDER_CODE_ACCEPTED; 38 42 else { 39 43 *reg &= 0xffffffff00000000UL; 40 - if (atomic_read(fi->local_int[cpu_addr]->cpuflags) 41 - & CPUSTAT_ECALL_PEND) 44 + if (cpuflags & CPUSTAT_ECALL_PEND) 42 45 *reg |= SIGP_STATUS_EXT_CALL_PENDING; 43 - if (atomic_read(fi->local_int[cpu_addr]->cpuflags) 44 - & CPUSTAT_STOPPED) 46 + if (cpuflags & CPUSTAT_STOPPED) 45 47 *reg |= SIGP_STATUS_STOPPED; 46 48 rc = SIGP_CC_STATUS_STORED; 47 49 } 48 - spin_unlock(&fi->lock); 49 50 50 51 VCPU_EVENT(vcpu, 4, "sensed status of cpu %x rc %x", cpu_addr, rc); 51 52 return rc; ··· 54 53 55 54 static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) 56 55 { 57 - struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 58 56 struct kvm_s390_local_interrupt *li; 59 57 struct kvm_s390_interrupt_info *inti; 60 - int rc; 58 + struct kvm_vcpu *dst_vcpu = NULL; 61 59 62 60 if (cpu_addr >= KVM_MAX_VCPUS) 63 61 return SIGP_CC_NOT_OPERATIONAL; ··· 68 68 inti->type = KVM_S390_INT_EMERGENCY; 69 69 inti->emerg.code = vcpu->vcpu_id; 70 70 71 - spin_lock(&fi->lock); 72 - li = fi->local_int[cpu_addr]; 73 - if (li == NULL) { 74 - rc = SIGP_CC_NOT_OPERATIONAL; 75 - kfree(inti); 76 - goto unlock; 77 - } 71 + dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 72 + if (!dst_vcpu) 73 + return SIGP_CC_NOT_OPERATIONAL; 74 + li = &dst_vcpu->arch.local_int; 78 75 spin_lock_bh(&li->lock); 79 76 list_add_tail(&inti->list, &li->list); 80 77 atomic_set(&li->active, 1); ··· 79 82 if (waitqueue_active(li->wq)) 80 83 wake_up_interruptible(li->wq); 81 84 spin_unlock_bh(&li->lock); 82 - rc = SIGP_CC_ORDER_CODE_ACCEPTED; 83 85 VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", cpu_addr); 84 - unlock: 85 - spin_unlock(&fi->lock); 86 - return rc; 86 + 87 + return SIGP_CC_ORDER_CODE_ACCEPTED; 87 88 } 88 89 89 90 static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr, ··· 117 122 118 123 static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) 119 124 { 120 - struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 121 125 struct kvm_s390_local_interrupt *li; 122 126 struct kvm_s390_interrupt_info *inti; 123 - int rc; 127 + struct kvm_vcpu *dst_vcpu = NULL; 124 128 125 129 if (cpu_addr >= KVM_MAX_VCPUS) 126 130 return SIGP_CC_NOT_OPERATIONAL; ··· 131 137 inti->type = KVM_S390_INT_EXTERNAL_CALL; 132 138 inti->extcall.code = vcpu->vcpu_id; 133 139 134 - spin_lock(&fi->lock); 135 - li = fi->local_int[cpu_addr]; 136 - if (li == NULL) { 137 - rc = SIGP_CC_NOT_OPERATIONAL; 138 - kfree(inti); 139 - goto unlock; 140 - } 140 + dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 141 + if (!dst_vcpu) 142 + return SIGP_CC_NOT_OPERATIONAL; 143 + li = &dst_vcpu->arch.local_int; 141 144 spin_lock_bh(&li->lock); 142 145 list_add_tail(&inti->list, &li->list); 143 146 atomic_set(&li->active, 1); ··· 142 151 if (waitqueue_active(li->wq)) 143 152 wake_up_interruptible(li->wq); 144 153 spin_unlock_bh(&li->lock); 145 - rc = SIGP_CC_ORDER_CODE_ACCEPTED; 146 154 VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", cpu_addr); 147 - unlock: 148 - spin_unlock(&fi->lock); 149 - return rc; 155 + 156 + return SIGP_CC_ORDER_CODE_ACCEPTED; 150 157 } 151 158 152 159 static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) ··· 178 189 179 190 static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) 180 191 { 181 - struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 182 192 struct kvm_s390_local_interrupt *li; 193 + struct kvm_vcpu *dst_vcpu = NULL; 183 194 int rc; 184 195 185 196 if (cpu_addr >= KVM_MAX_VCPUS) 186 197 return SIGP_CC_NOT_OPERATIONAL; 187 198 188 - spin_lock(&fi->lock); 189 - li = fi->local_int[cpu_addr]; 190 - if (li == NULL) { 191 - rc = SIGP_CC_NOT_OPERATIONAL; 192 - goto unlock; 193 - } 199 + dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 200 + if (!dst_vcpu) 201 + return SIGP_CC_NOT_OPERATIONAL; 202 + li = &dst_vcpu->arch.local_int; 194 203 195 204 rc = __inject_sigp_stop(li, action); 196 205 197 - unlock: 198 - spin_unlock(&fi->lock); 199 206 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); 200 207 201 208 if ((action & ACTION_STORE_ON_STOP) != 0 && rc == -ESHUTDOWN) { 202 209 /* If the CPU has already been stopped, we still have 203 210 * to save the status when doing stop-and-store. This 204 211 * has to be done after unlocking all spinlocks. */ 205 - struct kvm_vcpu *dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 206 212 rc = kvm_s390_store_status_unloaded(dst_vcpu, 207 213 KVM_S390_STORE_STATUS_NOADDR); 208 214 } ··· 317 333 static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, 318 334 u64 *reg) 319 335 { 336 + struct kvm_s390_local_interrupt *li; 337 + struct kvm_vcpu *dst_vcpu = NULL; 320 338 int rc; 321 - struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 322 339 323 340 if (cpu_addr >= KVM_MAX_VCPUS) 324 341 return SIGP_CC_NOT_OPERATIONAL; 325 342 326 - spin_lock(&fi->lock); 327 - if (fi->local_int[cpu_addr] == NULL) 328 - rc = SIGP_CC_NOT_OPERATIONAL; 329 - else { 330 - if (atomic_read(fi->local_int[cpu_addr]->cpuflags) 331 - & CPUSTAT_RUNNING) { 332 - /* running */ 333 - rc = SIGP_CC_ORDER_CODE_ACCEPTED; 334 - } else { 335 - /* not running */ 336 - *reg &= 0xffffffff00000000UL; 337 - *reg |= SIGP_STATUS_NOT_RUNNING; 338 - rc = SIGP_CC_STATUS_STORED; 339 - } 343 + dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 344 + if (!dst_vcpu) 345 + return SIGP_CC_NOT_OPERATIONAL; 346 + li = &dst_vcpu->arch.local_int; 347 + if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) { 348 + /* running */ 349 + rc = SIGP_CC_ORDER_CODE_ACCEPTED; 350 + } else { 351 + /* not running */ 352 + *reg &= 0xffffffff00000000UL; 353 + *reg |= SIGP_STATUS_NOT_RUNNING; 354 + rc = SIGP_CC_STATUS_STORED; 340 355 } 341 - spin_unlock(&fi->lock); 342 356 343 357 VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x", cpu_addr, 344 358 rc); ··· 347 365 /* Test whether the destination CPU is available and not busy */ 348 366 static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr) 349 367 { 350 - struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 351 368 struct kvm_s390_local_interrupt *li; 352 369 int rc = SIGP_CC_ORDER_CODE_ACCEPTED; 370 + struct kvm_vcpu *dst_vcpu = NULL; 353 371 354 372 if (cpu_addr >= KVM_MAX_VCPUS) 355 373 return SIGP_CC_NOT_OPERATIONAL; 356 374 357 - spin_lock(&fi->lock); 358 - li = fi->local_int[cpu_addr]; 359 - if (li == NULL) { 360 - rc = SIGP_CC_NOT_OPERATIONAL; 361 - goto out; 362 - } 363 - 375 + dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 376 + if (!dst_vcpu) 377 + return SIGP_CC_NOT_OPERATIONAL; 378 + li = &dst_vcpu->arch.local_int; 364 379 spin_lock_bh(&li->lock); 365 380 if (li->action_bits & ACTION_STOP_ON_STOP) 366 381 rc = SIGP_CC_BUSY; 367 382 spin_unlock_bh(&li->lock); 368 - out: 369 - spin_unlock(&fi->lock); 383 + 370 384 return rc; 371 385 } 372 386