Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 80810
b: refs/heads/master
c: 298101d
h: refs/heads/master
v: v3
  • Loading branch information
Avi Kivity committed Jan 30, 2008
1 parent 755653d commit 162cbf6
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4bf8ed8dd2781a5e7603a83f8ee1d4f5aa04ebc4
refs/heads/master: 298101da2f507c13eaf179ee4507a7c0fe3e7b06
21 changes: 21 additions & 0 deletions trunk/drivers/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,25 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
vcpu->shadow_efer = efer;
}

static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
bool has_error_code, u32 error_code)
{
struct vcpu_svm *svm = to_svm(vcpu);

svm->vmcb->control.event_inj = nr
| SVM_EVTINJ_VALID
| (has_error_code ? SVM_EVTINJ_VALID_ERR : 0)
| SVM_EVTINJ_TYPE_EXEPT;
svm->vmcb->control.event_inj_err = error_code;
}

static bool svm_exception_injected(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);

return !(svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID);
}

static void svm_inject_gp(struct kvm_vcpu *vcpu, unsigned error_code)
{
struct vcpu_svm *svm = to_svm(vcpu);
Expand Down Expand Up @@ -1712,6 +1731,8 @@ static struct kvm_x86_ops svm_x86_ops = {
.patch_hypercall = svm_patch_hypercall,
.get_irq = svm_get_irq,
.set_irq = svm_set_irq,
.queue_exception = svm_queue_exception,
.exception_injected = svm_exception_injected,
.inject_pending_irq = svm_intr_assist,
.inject_pending_vectors = do_interrupt_requests,

Expand Down
20 changes: 20 additions & 0 deletions trunk/drivers/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,24 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
vcpu->interrupt_window_open = 1;
}

static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
bool has_error_code, u32 error_code)
{
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
nr | INTR_TYPE_EXCEPTION
| (has_error_code ? INTR_INFO_DELIEVER_CODE_MASK : 0)
| INTR_INFO_VALID_MASK);
if (has_error_code)
vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
}

static bool vmx_exception_injected(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);

return !(vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK);
}

static void vmx_inject_gp(struct kvm_vcpu *vcpu, unsigned error_code)
{
printk(KERN_DEBUG "inject_general_protection: rip 0x%lx\n",
Expand Down Expand Up @@ -2641,6 +2659,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
.patch_hypercall = vmx_patch_hypercall,
.get_irq = vmx_get_irq,
.set_irq = vmx_inject_irq,
.queue_exception = vmx_queue_exception,
.exception_injected = vmx_exception_injected,
.inject_pending_irq = vmx_intr_assist,
.inject_pending_vectors = do_interrupt_requests,

Expand Down
33 changes: 32 additions & 1 deletion trunk/drivers/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -2370,7 +2396,9 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
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);
Expand Down Expand Up @@ -2409,6 +2437,9 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
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) {
Expand Down
13 changes: 13 additions & 0 deletions trunk/drivers/kvm/x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ struct kvm_vcpu {
struct kvm_pio_request pio;
void *pio_data;

struct kvm_queued_exception {
bool pending;
bool has_error_code;
u8 nr;
u32 error_code;
} exception;

struct {
int active;
u8 save_iopl;
Expand Down Expand Up @@ -224,6 +231,9 @@ struct kvm_x86_ops {
unsigned char *hypercall_addr);
int (*get_irq)(struct kvm_vcpu *vcpu);
void (*set_irq)(struct kvm_vcpu *vcpu, int vec);
void (*queue_exception)(struct kvm_vcpu *vcpu, unsigned nr,
bool has_error_code, u32 error_code);
bool (*exception_injected)(struct kvm_vcpu *vcpu);
void (*inject_pending_irq)(struct kvm_vcpu *vcpu);
void (*inject_pending_vectors)(struct kvm_vcpu *vcpu,
struct kvm_run *run);
Expand Down Expand Up @@ -294,6 +304,9 @@ void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l);
int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);

void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);

void fx_init(struct kvm_vcpu *vcpu);

int emulator_read_std(unsigned long addr,
Expand Down

0 comments on commit 162cbf6

Please sign in to comment.