aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2014-06-18 15:56:55 -0400
committerAlexander Graf <agraf@suse.de>2014-07-28 12:30:18 -0400
commit8de12015ff75967b16f70e5938b151390dac9b77 (patch)
tree8b934668765b6a2fa4a9eb9ffc9f6389d02e3bfb /arch/powerpc
parentd69614a295aef72f8fb22da8e3ccf1a8f19a7ffc (diff)
KVM: PPC: Expose helper functions for data/inst faults
We're going to implement guest code interpretation in KVM for some rare corner cases. This code needs to be able to inject data and instruction faults into the guest when it encounters them. Expose generic APIs to do this in a reasonably subarch agnostic fashion. Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h8
-rw-r--r--arch/powerpc/kvm/book3s.c17
-rw-r--r--arch/powerpc/kvm/booke.c16
3 files changed, 35 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 2214ee61f668..cbee4538307f 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -132,6 +132,14 @@ extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
132extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, 132extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
133 struct kvm_interrupt *irq); 133 struct kvm_interrupt *irq);
134extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu); 134extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu);
135extern void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, ulong dear_flags,
136 ulong esr_flags);
137extern void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu,
138 ulong dear_flags,
139 ulong esr_flags);
140extern void kvmppc_core_queue_itlb_miss(struct kvm_vcpu *vcpu);
141extern void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu,
142 ulong esr_flags);
135extern void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu); 143extern void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu);
136extern int kvmppc_core_check_requests(struct kvm_vcpu *vcpu); 144extern int kvmppc_core_check_requests(struct kvm_vcpu *vcpu);
137 145
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index de8da3387e90..dd03f6b299ba 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -230,6 +230,23 @@ void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu)
230 kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL_LEVEL); 230 kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL_LEVEL);
231} 231}
232 232
233void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, ulong dar,
234 ulong flags)
235{
236 kvmppc_set_dar(vcpu, dar);
237 kvmppc_set_dsisr(vcpu, flags);
238 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE);
239}
240
241void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong flags)
242{
243 u64 msr = kvmppc_get_msr(vcpu);
244 msr &= ~(SRR1_ISI_NOPT | SRR1_ISI_N_OR_G | SRR1_ISI_PROT);
245 msr |= flags & (SRR1_ISI_NOPT | SRR1_ISI_N_OR_G | SRR1_ISI_PROT);
246 kvmppc_set_msr_fast(vcpu, msr);
247 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE);
248}
249
233int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) 250int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
234{ 251{
235 int deliver = 1; 252 int deliver = 1;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 2f697b49073b..f30948a17c03 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -185,24 +185,28 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu,
185 set_bit(priority, &vcpu->arch.pending_exceptions); 185 set_bit(priority, &vcpu->arch.pending_exceptions);
186} 186}
187 187
188static void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu, 188void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu,
189 ulong dear_flags, ulong esr_flags) 189 ulong dear_flags, ulong esr_flags)
190{ 190{
191 vcpu->arch.queued_dear = dear_flags; 191 vcpu->arch.queued_dear = dear_flags;
192 vcpu->arch.queued_esr = esr_flags; 192 vcpu->arch.queued_esr = esr_flags;
193 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); 193 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
194} 194}
195 195
196static void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, 196void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu,
197 ulong dear_flags, ulong esr_flags) 197 ulong dear_flags, ulong esr_flags)
198{ 198{
199 vcpu->arch.queued_dear = dear_flags; 199 vcpu->arch.queued_dear = dear_flags;
200 vcpu->arch.queued_esr = esr_flags; 200 vcpu->arch.queued_esr = esr_flags;
201 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE); 201 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
202} 202}
203 203
204static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, 204void kvmppc_core_queue_itlb_miss(struct kvm_vcpu *vcpu)
205 ulong esr_flags) 205{
206 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ITLB_MISS);
207}
208
209void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong esr_flags)
206{ 210{
207 vcpu->arch.queued_esr = esr_flags; 211 vcpu->arch.queued_esr = esr_flags;
208 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE); 212 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);