aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
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
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')
-rw-r--r--arch/powerpc/include/asm/kvm_para.h1
-rw-r--r--arch/powerpc/kvm/book3s.c18
-rw-r--r--arch/powerpc/kvm/booke.c15
3 files changed, 32 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h
index 556fd59ee0f1..4577e7b6dff1 100644
--- a/arch/powerpc/include/asm/kvm_para.h
+++ b/arch/powerpc/include/asm/kvm_para.h
@@ -24,6 +24,7 @@
24#include <linux/of.h> 24#include <linux/of.h>
25 25
26struct kvm_vcpu_arch_shared { 26struct kvm_vcpu_arch_shared {
27 __u64 critical; /* Guest may not get interrupts if == r1 */
27 __u64 sprg0; 28 __u64 sprg0;
28 __u64 sprg1; 29 __u64 sprg1;
29 __u64 sprg2; 30 __u64 sprg2;
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:
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 13e0747178e3..104d0ee8c8aa 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -147,6 +147,20 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
147 int allowed = 0; 147 int allowed = 0;
148 ulong uninitialized_var(msr_mask); 148 ulong uninitialized_var(msr_mask);
149 bool update_esr = false, update_dear = false; 149 bool update_esr = false, update_dear = false;
150 ulong crit_raw = vcpu->arch.shared->critical;
151 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
152 bool crit;
153
154 /* Truncate crit indicators in 32 bit mode */
155 if (!(vcpu->arch.shared->msr & MSR_SF)) {
156 crit_raw &= 0xffffffff;
157 crit_r1 &= 0xffffffff;
158 }
159
160 /* Critical section when crit == r1 */
161 crit = (crit_raw == crit_r1);
162 /* ... and we're in supervisor mode */
163 crit = crit && !(vcpu->arch.shared->msr & MSR_PR);
150 164
151 switch (priority) { 165 switch (priority) {
152 case BOOKE_IRQPRIO_DTLB_MISS: 166 case BOOKE_IRQPRIO_DTLB_MISS:
@@ -181,6 +195,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
181 case BOOKE_IRQPRIO_DECREMENTER: 195 case BOOKE_IRQPRIO_DECREMENTER:
182 case BOOKE_IRQPRIO_FIT: 196 case BOOKE_IRQPRIO_FIT:
183 allowed = vcpu->arch.shared->msr & MSR_EE; 197 allowed = vcpu->arch.shared->msr & MSR_EE;
198 allowed = allowed && !crit;
184 msr_mask = MSR_CE|MSR_ME|MSR_DE; 199 msr_mask = MSR_CE|MSR_ME|MSR_DE;
185 break; 200 break;
186 case BOOKE_IRQPRIO_DEBUG: 201 case BOOKE_IRQPRIO_DEBUG: