{
kvmppc_unfixup_split_real(vcpu);
kvmppc_set_srr0(vcpu, kvmppc_get_pc(vcpu));
- kvmppc_set_srr1(vcpu, kvmppc_get_msr(vcpu) | flags);
+ kvmppc_set_srr1(vcpu, (kvmppc_get_msr(vcpu) & ~0x783f0000ul) | flags);
kvmppc_set_pc(vcpu, kvmppc_interrupt_offset(vcpu) + vec);
vcpu->arch.mmu.reset_msr(vcpu);
}
{
kvmppc_set_dar(vcpu, dar);
kvmppc_set_dsisr(vcpu, flags);
- kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE);
+ kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE, 0);
}
-EXPORT_SYMBOL_GPL(kvmppc_core_queue_data_storage); /* used by kvm_hv */
+EXPORT_SYMBOL_GPL(kvmppc_core_queue_data_storage);
void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong flags)
{
- u64 msr = kvmppc_get_msr(vcpu);
- msr &= ~(SRR1_ISI_NOPT | SRR1_ISI_N_OR_G | SRR1_ISI_PROT);
- msr |= flags & (SRR1_ISI_NOPT | SRR1_ISI_N_OR_G | SRR1_ISI_PROT);
- kvmppc_set_msr_fast(vcpu, msr);
- kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE);
+ kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_INST_STORAGE, flags);
}
+EXPORT_SYMBOL_GPL(kvmppc_core_queue_inst_storage);
static int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu,
unsigned int priority)
pte.may_execute = !data;
}
- if (page_found == -ENOENT) {
- /* Page not found in guest PTE entries */
- u64 ssrr1 = vcpu->arch.shadow_srr1;
- u64 msr = kvmppc_get_msr(vcpu);
- kvmppc_set_dar(vcpu, kvmppc_get_fault_dar(vcpu));
- kvmppc_set_dsisr(vcpu, vcpu->arch.fault_dsisr);
- kvmppc_set_msr_fast(vcpu, msr | (ssrr1 & 0xf8000000ULL));
- kvmppc_book3s_queue_irqprio(vcpu, vec);
- } else if (page_found == -EPERM) {
- /* Storage protection */
- u32 dsisr = vcpu->arch.fault_dsisr;
- u64 ssrr1 = vcpu->arch.shadow_srr1;
- u64 msr = kvmppc_get_msr(vcpu);
- kvmppc_set_dar(vcpu, kvmppc_get_fault_dar(vcpu));
- dsisr = (dsisr & ~DSISR_NOHPTE) | DSISR_PROTFAULT;
- kvmppc_set_dsisr(vcpu, dsisr);
- kvmppc_set_msr_fast(vcpu, msr | (ssrr1 & 0xf8000000ULL));
- kvmppc_book3s_queue_irqprio(vcpu, vec);
+ if (page_found == -ENOENT || page_found == -EPERM) {
+ /* Page not found in guest PTE entries, or protection fault */
+ u64 flags;
+
+ if (page_found == -EPERM)
+ flags = DSISR_PROTFAULT;
+ else
+ flags = DSISR_NOHPTE;
+ if (data) {
+ flags |= vcpu->arch.fault_dsisr & DSISR_ISSTORE;
+ kvmppc_core_queue_data_storage(vcpu, eaddr, flags);
+ } else {
+ kvmppc_core_queue_inst_storage(vcpu, flags);
+ }
} else if (page_found == -EINVAL) {
/* Page not found in guest SLB */
kvmppc_set_dar(vcpu, kvmppc_get_fault_dar(vcpu));
kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFUL);
r = RESUME_GUEST;
} else {
- u64 msr = kvmppc_get_msr(vcpu);
- msr |= shadow_srr1 & 0x58000000;
- kvmppc_set_msr_fast(vcpu, msr);
- kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+ kvmppc_core_queue_inst_storage(vcpu,
+ shadow_srr1 & 0x58000000);
r = RESUME_GUEST;
}
break;
r = kvmppc_handle_pagefault(run, vcpu, dar, exit_nr);
srcu_read_unlock(&vcpu->kvm->srcu, idx);
} else {
- kvmppc_set_dar(vcpu, dar);
- kvmppc_set_dsisr(vcpu, fault_dsisr);
- kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+ kvmppc_core_queue_data_storage(vcpu, dar, fault_dsisr);
r = RESUME_GUEST;
}
break;