summaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86.c
diff options
context:
space:
mode:
authorAvi Kivity2007-11-25 12:41:11 +0100
committerAvi Kivity2008-01-30 16:53:18 +0100
commit298101da2f507c13eaf179ee4507a7c0fe3e7b06 (patch)
tree2c0808964e5bc04812f0379b945fb187aaf901eb /drivers/kvm/x86.c
parentKVM: MMU: Remove unused prev_shadow_ent variable from fetch() (diff)
downloadkernel-qcow2-linux-298101da2f507c13eaf179ee4507a7c0fe3e7b06.tar.gz
kernel-qcow2-linux-298101da2f507c13eaf179ee4507a7c0fe3e7b06.tar.xz
kernel-qcow2-linux-298101da2f507c13eaf179ee4507a7c0fe3e7b06.zip
KVM: Generalize exception injection mechanism
Instead of each subarch doing its own thing, add an API for queuing an injection, and manage failed exception injection centerally (i.e., if an inject failed due to a shadow page fault, we need to requeue it). Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86.c')
-rw-r--r--drivers/kvm/x86.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
index c9e4b67bfb1b..11440d12a2d3 100644
--- a/drivers/kvm/x86.c
+++ b/drivers/kvm/x86.c
@@ -133,6 +133,32 @@ static void inject_gp(struct kvm_vcpu *vcpu)
kvm_x86_ops->inject_gp(vcpu, 0);
}
+void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr)
+{
+ WARN_ON(vcpu->exception.pending);
+ vcpu->exception.pending = true;
+ vcpu->exception.has_error_code = false;
+ vcpu->exception.nr = nr;
+}
+EXPORT_SYMBOL_GPL(kvm_queue_exception);
+
+void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
+{
+ WARN_ON(vcpu->exception.pending);
+ vcpu->exception.pending = true;
+ vcpu->exception.has_error_code = true;
+ vcpu->exception.nr = nr;
+ vcpu->exception.error_code = error_code;
+}
+EXPORT_SYMBOL_GPL(kvm_queue_exception_e);
+
+static void __queue_exception(struct kvm_vcpu *vcpu)
+{
+ kvm_x86_ops->queue_exception(vcpu, vcpu->exception.nr,
+ vcpu->exception.has_error_code,
+ vcpu->exception.error_code);
+}
+
/*
* Load the pae pdptrs. Return true is they are all valid.
*/
@@ -2370,7 +2396,9 @@ again:
goto out;
}
- if (irqchip_in_kernel(vcpu->kvm))
+ if (vcpu->exception.pending)
+ __queue_exception(vcpu);
+ else if (irqchip_in_kernel(vcpu->kvm))
kvm_x86_ops->inject_pending_irq(vcpu);
else
kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);
@@ -2409,6 +2437,9 @@ again:
profile_hit(KVM_PROFILING, (void *)vcpu->rip);
}
+ if (vcpu->exception.pending && kvm_x86_ops->exception_injected(vcpu))
+ vcpu->exception.pending = false;
+
r = kvm_x86_ops->handle_exit(kvm_run, vcpu);
if (r > 0) {