aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2011-11-17 05:00:41 -0500
committerAvi Kivity <avi@redhat.com>2011-11-17 09:25:43 -0500
commit9e6dabeffd1d0ec2aa19aa076c4886067238d442 (patch)
tree6f5f2a06184a0e4ec0b8cff8db912ce6013c5056 /arch
parent3439a8da16bcad6b0982ece938c9f8299bb53584 (diff)
KVM: s390: Fix RUNNING flag misinterpretation
CPUSTAT_RUNNING was implemented signifying that a vcpu is not stopped. This is not, however, what the architecture says: RUNNING should be set when the host is acting on the behalf of the guest operating system. CPUSTAT_RUNNING has been changed to be set in kvm_arch_vcpu_load() and to be unset in kvm_arch_vcpu_put(). For signifying stopped state of a vcpu, a host-controlled bit has been used and is set/unset basically on the reverse as the old CPUSTAT_RUNNING bit (including pushing it down into stop handling proper in handle_stop()). Cc: stable@kernel.org Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Carsten Otte <cotte@de.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/kvm_host.h2
-rw-r--r--arch/s390/kvm/diag.c2
-rw-r--r--arch/s390/kvm/intercept.c3
-rw-r--r--arch/s390/kvm/interrupt.c1
-rw-r--r--arch/s390/kvm/kvm-s390.c10
-rw-r--r--arch/s390/kvm/sigp.c6
6 files changed, 15 insertions, 9 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 24e18473d926..20f9068cd6b5 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -47,7 +47,7 @@ struct sca_block {
47#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1)) 47#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1))
48#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE) 48#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
49 49
50#define CPUSTAT_HOST 0x80000000 50#define CPUSTAT_STOPPED 0x80000000
51#define CPUSTAT_WAIT 0x10000000 51#define CPUSTAT_WAIT 0x10000000
52#define CPUSTAT_ECALL_PEND 0x08000000 52#define CPUSTAT_ECALL_PEND 0x08000000
53#define CPUSTAT_STOP_INT 0x04000000 53#define CPUSTAT_STOP_INT 0x04000000
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index 87cedd61be04..8943e82cd4d9 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -70,7 +70,7 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
70 return -EOPNOTSUPP; 70 return -EOPNOTSUPP;
71 } 71 }
72 72
73 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); 73 atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
74 vcpu->run->s390_reset_flags |= KVM_S390_RESET_SUBSYSTEM; 74 vcpu->run->s390_reset_flags |= KVM_S390_RESET_SUBSYSTEM;
75 vcpu->run->s390_reset_flags |= KVM_S390_RESET_IPL; 75 vcpu->run->s390_reset_flags |= KVM_S390_RESET_IPL;
76 vcpu->run->s390_reset_flags |= KVM_S390_RESET_CPU_INIT; 76 vcpu->run->s390_reset_flags |= KVM_S390_RESET_CPU_INIT;
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index c7c51898984e..02434543eabb 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -132,7 +132,6 @@ static int handle_stop(struct kvm_vcpu *vcpu)
132 int rc = 0; 132 int rc = 0;
133 133
134 vcpu->stat.exit_stop_request++; 134 vcpu->stat.exit_stop_request++;
135 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
136 spin_lock_bh(&vcpu->arch.local_int.lock); 135 spin_lock_bh(&vcpu->arch.local_int.lock);
137 if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) { 136 if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) {
138 vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP; 137 vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP;
@@ -149,6 +148,8 @@ static int handle_stop(struct kvm_vcpu *vcpu)
149 } 148 }
150 149
151 if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { 150 if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
151 atomic_set_mask(CPUSTAT_STOPPED,
152 &vcpu->arch.sie_block->cpuflags);
152 vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP; 153 vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
153 VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); 154 VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
154 rc = -EOPNOTSUPP; 155 rc = -EOPNOTSUPP;
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 87c16705b381..278ee009ce65 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -252,6 +252,7 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
252 offsetof(struct _lowcore, restart_psw), sizeof(psw_t)); 252 offsetof(struct _lowcore, restart_psw), sizeof(psw_t));
253 if (rc == -EFAULT) 253 if (rc == -EFAULT)
254 exception = 1; 254 exception = 1;
255 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
255 break; 256 break;
256 257
257 case KVM_S390_PROGRAM_INT: 258 case KVM_S390_PROGRAM_INT:
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 0bd3bea1e4cd..630ab65b488b 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -270,10 +270,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
270 restore_fp_regs(&vcpu->arch.guest_fpregs); 270 restore_fp_regs(&vcpu->arch.guest_fpregs);
271 restore_access_regs(vcpu->arch.guest_acrs); 271 restore_access_regs(vcpu->arch.guest_acrs);
272 gmap_enable(vcpu->arch.gmap); 272 gmap_enable(vcpu->arch.gmap);
273 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
273} 274}
274 275
275void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) 276void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
276{ 277{
278 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
277 gmap_disable(vcpu->arch.gmap); 279 gmap_disable(vcpu->arch.gmap);
278 save_fp_regs(&vcpu->arch.guest_fpregs); 280 save_fp_regs(&vcpu->arch.guest_fpregs);
279 save_access_regs(vcpu->arch.guest_acrs); 281 save_access_regs(vcpu->arch.guest_acrs);
@@ -301,7 +303,9 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
301 303
302int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) 304int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
303{ 305{
304 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM); 306 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
307 CPUSTAT_SM |
308 CPUSTAT_STOPPED);
305 vcpu->arch.sie_block->ecb = 6; 309 vcpu->arch.sie_block->ecb = 6;
306 vcpu->arch.sie_block->eca = 0xC1002001U; 310 vcpu->arch.sie_block->eca = 0xC1002001U;
307 vcpu->arch.sie_block->fac = (int) (long) facilities; 311 vcpu->arch.sie_block->fac = (int) (long) facilities;
@@ -428,7 +432,7 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
428{ 432{
429 int rc = 0; 433 int rc = 0;
430 434
431 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING) 435 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
432 rc = -EBUSY; 436 rc = -EBUSY;
433 else { 437 else {
434 vcpu->run->psw_mask = psw.mask; 438 vcpu->run->psw_mask = psw.mask;
@@ -501,7 +505,7 @@ rerun_vcpu:
501 if (vcpu->sigset_active) 505 if (vcpu->sigset_active)
502 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); 506 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
503 507
504 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); 508 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
505 509
506 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL); 510 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
507 511
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index f815118835f3..4a488a98d7f8 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -57,8 +57,8 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
57 spin_lock(&fi->lock); 57 spin_lock(&fi->lock);
58 if (fi->local_int[cpu_addr] == NULL) 58 if (fi->local_int[cpu_addr] == NULL)
59 rc = 3; /* not operational */ 59 rc = 3; /* not operational */
60 else if (atomic_read(fi->local_int[cpu_addr]->cpuflags) 60 else if (!(atomic_read(fi->local_int[cpu_addr]->cpuflags)
61 & CPUSTAT_RUNNING) { 61 & CPUSTAT_STOPPED)) {
62 *reg &= 0xffffffff00000000UL; 62 *reg &= 0xffffffff00000000UL;
63 rc = 1; /* status stored */ 63 rc = 1; /* status stored */
64 } else { 64 } else {
@@ -251,7 +251,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
251 251
252 spin_lock_bh(&li->lock); 252 spin_lock_bh(&li->lock);
253 /* cpu must be in stopped state */ 253 /* cpu must be in stopped state */
254 if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) { 254 if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
255 rc = 1; /* incorrect state */ 255 rc = 1; /* incorrect state */
256 *reg &= SIGP_STAT_INCORRECT_STATE; 256 *reg &= SIGP_STAT_INCORRECT_STATE;
257 kfree(inti); 257 kfree(inti);