aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2013-01-31 08:17:38 -0500
committerAlexander Graf <agraf@suse.de>2013-02-13 06:56:45 -0500
commit011da8996263f799a469a761ee15c998d7ef1acb (patch)
treee4912b9655ba73ccf175176efd8bba44a21e4595 /arch/powerpc/kvm
parentee53e560a8f52cbc1fba877fdf4acffb0c163f29 (diff)
KVM: PPC: BookE: Handle alignment interrupts
When the guest triggers an alignment interrupt, we don't handle it properly today and instead BUG_ON(). This really shouldn't happen. Instead, we should just pass the interrupt back into the guest so it can deal with it. Reported-by: Gao Guanhua-B22826 <B22826@freescale.com> Tested-by: Gao Guanhua-B22826 <B22826@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/booke.c16
-rw-r--r--arch/powerpc/kvm/booke_interrupts.S6
2 files changed, 19 insertions, 3 deletions
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index d2f502d209ff..020923e43134 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -182,6 +182,14 @@ static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu,
182 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); 182 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
183} 183}
184 184
185static void kvmppc_core_queue_alignment(struct kvm_vcpu *vcpu, ulong dear_flags,
186 ulong esr_flags)
187{
188 vcpu->arch.queued_dear = dear_flags;
189 vcpu->arch.queued_esr = esr_flags;
190 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ALIGNMENT);
191}
192
185void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags) 193void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags)
186{ 194{
187 vcpu->arch.queued_esr = esr_flags; 195 vcpu->arch.queued_esr = esr_flags;
@@ -345,6 +353,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
345 switch (priority) { 353 switch (priority) {
346 case BOOKE_IRQPRIO_DTLB_MISS: 354 case BOOKE_IRQPRIO_DTLB_MISS:
347 case BOOKE_IRQPRIO_DATA_STORAGE: 355 case BOOKE_IRQPRIO_DATA_STORAGE:
356 case BOOKE_IRQPRIO_ALIGNMENT:
348 update_dear = true; 357 update_dear = true;
349 /* fall through */ 358 /* fall through */
350 case BOOKE_IRQPRIO_INST_STORAGE: 359 case BOOKE_IRQPRIO_INST_STORAGE:
@@ -358,7 +367,6 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
358 case BOOKE_IRQPRIO_SPE_FP_DATA: 367 case BOOKE_IRQPRIO_SPE_FP_DATA:
359 case BOOKE_IRQPRIO_SPE_FP_ROUND: 368 case BOOKE_IRQPRIO_SPE_FP_ROUND:
360 case BOOKE_IRQPRIO_AP_UNAVAIL: 369 case BOOKE_IRQPRIO_AP_UNAVAIL:
361 case BOOKE_IRQPRIO_ALIGNMENT:
362 allowed = 1; 370 allowed = 1;
363 msr_mask = MSR_CE | MSR_ME | MSR_DE; 371 msr_mask = MSR_CE | MSR_ME | MSR_DE;
364 int_class = INT_CLASS_NONCRIT; 372 int_class = INT_CLASS_NONCRIT;
@@ -971,6 +979,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
971 r = RESUME_GUEST; 979 r = RESUME_GUEST;
972 break; 980 break;
973 981
982 case BOOKE_INTERRUPT_ALIGNMENT:
983 kvmppc_core_queue_alignment(vcpu, vcpu->arch.fault_dear,
984 vcpu->arch.fault_esr);
985 r = RESUME_GUEST;
986 break;
987
974#ifdef CONFIG_KVM_BOOKE_HV 988#ifdef CONFIG_KVM_BOOKE_HV
975 case BOOKE_INTERRUPT_HV_SYSCALL: 989 case BOOKE_INTERRUPT_HV_SYSCALL:
976 if (!(vcpu->arch.shared->msr & MSR_PR)) { 990 if (!(vcpu->arch.shared->msr & MSR_PR)) {
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index eae848376440..f4bb55c96517 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -45,12 +45,14 @@
45 (1<<BOOKE_INTERRUPT_DEBUG)) 45 (1<<BOOKE_INTERRUPT_DEBUG))
46 46
47#define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ 47#define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \
48 (1<<BOOKE_INTERRUPT_DTLB_MISS)) 48 (1<<BOOKE_INTERRUPT_DTLB_MISS) | \
49 (1<<BOOKE_INTERRUPT_ALIGNMENT))
49 50
50#define NEED_ESR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ 51#define NEED_ESR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \
51 (1<<BOOKE_INTERRUPT_INST_STORAGE) | \ 52 (1<<BOOKE_INTERRUPT_INST_STORAGE) | \
52 (1<<BOOKE_INTERRUPT_PROGRAM) | \ 53 (1<<BOOKE_INTERRUPT_PROGRAM) | \
53 (1<<BOOKE_INTERRUPT_DTLB_MISS)) 54 (1<<BOOKE_INTERRUPT_DTLB_MISS) | \
55 (1<<BOOKE_INTERRUPT_ALIGNMENT))
54 56
55.macro KVM_HANDLER ivor_nr scratch srr0 57.macro KVM_HANDLER ivor_nr scratch srr0
56_GLOBAL(kvmppc_handler_\ivor_nr) 58_GLOBAL(kvmppc_handler_\ivor_nr)