aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s.c
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-07-29 08:47:49 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:50:46 -0400
commit5c6cedf488a1144ac4f683f3ea1a642533d1dcd2 (patch)
tree658f90bfde8dfef9c53675d5b114d9761869822c /arch/powerpc/kvm/book3s.c
parent2a342ed57756ad5d8af5456959433884367e5ab2 (diff)
KVM: PPC: Add PV guest critical sections
When running in hooked code we need a way to disable interrupts without clobbering any interrupts or exiting out to the hypervisor. To achieve this, we have an additional critical field in the shared page. If that field is equal to the r1 register of the guest, it tells the hypervisor that we're in such a critical section and thus may not receive any interrupts. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm/book3s.c')
-rw-r--r--arch/powerpc/kvm/book3s.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 5cb5f0d9381f..d6227ff0ceae 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -251,14 +251,28 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
251 int deliver = 1; 251 int deliver = 1;
252 int vec = 0; 252 int vec = 0;
253 ulong flags = 0ULL; 253 ulong flags = 0ULL;
254 ulong crit_raw = vcpu->arch.shared->critical;
255 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
256 bool crit;
257
258 /* Truncate crit indicators in 32 bit mode */
259 if (!(vcpu->arch.shared->msr & MSR_SF)) {
260 crit_raw &= 0xffffffff;
261 crit_r1 &= 0xffffffff;
262 }
263
264 /* Critical section when crit == r1 */
265 crit = (crit_raw == crit_r1);
266 /* ... and we're in supervisor mode */
267 crit = crit && !(vcpu->arch.shared->msr & MSR_PR);
254 268
255 switch (priority) { 269 switch (priority) {
256 case BOOK3S_IRQPRIO_DECREMENTER: 270 case BOOK3S_IRQPRIO_DECREMENTER:
257 deliver = vcpu->arch.shared->msr & MSR_EE; 271 deliver = (vcpu->arch.shared->msr & MSR_EE) && !crit;
258 vec = BOOK3S_INTERRUPT_DECREMENTER; 272 vec = BOOK3S_INTERRUPT_DECREMENTER;
259 break; 273 break;
260 case BOOK3S_IRQPRIO_EXTERNAL: 274 case BOOK3S_IRQPRIO_EXTERNAL:
261 deliver = vcpu->arch.shared->msr & MSR_EE; 275 deliver = (vcpu->arch.shared->msr & MSR_EE) && !crit;
262 vec = BOOK3S_INTERRUPT_EXTERNAL; 276 vec = BOOK3S_INTERRUPT_EXTERNAL;
263 break; 277 break;
264 case BOOK3S_IRQPRIO_SYSTEM_RESET: 278 case BOOK3S_IRQPRIO_SYSTEM_RESET: