aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-11-25 06:41:11 -0500
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:53:18 -0500
commit298101da2f507c13eaf179ee4507a7c0fe3e7b06 (patch)
tree2c0808964e5bc04812f0379b945fb187aaf901eb /drivers/kvm/x86.c
parent4bf8ed8dd2781a5e7603a83f8ee1d4f5aa04ebc4 (diff)
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)
133 kvm_x86_ops->inject_gp(vcpu, 0); 133 kvm_x86_ops->inject_gp(vcpu, 0);
134} 134}
135 135
136void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr)
137{
138 WARN_ON(vcpu->exception.pending);
139 vcpu->exception.pending = true;
140 vcpu->exception.has_error_code = false;
141 vcpu->exception.nr = nr;
142}
143EXPORT_SYMBOL_GPL(kvm_queue_exception);
144
145void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
146{
147 WARN_ON(vcpu->exception.pending);
148 vcpu->exception.pending = true;
149 vcpu->exception.has_error_code = true;
150 vcpu->exception.nr = nr;
151 vcpu->exception.error_code = error_code;
152}
153EXPORT_SYMBOL_GPL(kvm_queue_exception_e);
154
155static void __queue_exception(struct kvm_vcpu *vcpu)
156{
157 kvm_x86_ops->queue_exception(vcpu, vcpu->exception.nr,
158 vcpu->exception.has_error_code,
159 vcpu->exception.error_code);
160}
161
136/* 162/*
137 * Load the pae pdptrs. Return true is they are all valid. 163 * Load the pae pdptrs. Return true is they are all valid.
138 */ 164 */
@@ -2370,7 +2396,9 @@ again:
2370 goto out; 2396 goto out;
2371 } 2397 }
2372 2398
2373 if (irqchip_in_kernel(vcpu->kvm)) 2399 if (vcpu->exception.pending)
2400 __queue_exception(vcpu);
2401 else if (irqchip_in_kernel(vcpu->kvm))
2374 kvm_x86_ops->inject_pending_irq(vcpu); 2402 kvm_x86_ops->inject_pending_irq(vcpu);
2375 else 2403 else
2376 kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run); 2404 kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);
@@ -2409,6 +2437,9 @@ again:
2409 profile_hit(KVM_PROFILING, (void *)vcpu->rip); 2437 profile_hit(KVM_PROFILING, (void *)vcpu->rip);
2410 } 2438 }
2411 2439
2440 if (vcpu->exception.pending && kvm_x86_ops->exception_injected(vcpu))
2441 vcpu->exception.pending = false;
2442
2412 r = kvm_x86_ops->handle_exit(kvm_run, vcpu); 2443 r = kvm_x86_ops->handle_exit(kvm_run, vcpu);
2413 2444
2414 if (r > 0) { 2445 if (r > 0) {