diff options
author | Avi Kivity <avi@qumranet.com> | 2007-11-22 04:30:47 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:53:00 -0500 |
commit | 1155f76a8166ae6fc88e7d73eb6817eb9012d476 (patch) | |
tree | becc954dacc6098f9c60bc52d572ca8179e070e4 /drivers | |
parent | 9c5623e3e42e94927d02a6693875badf15692970 (diff) |
KVM: VMX: Read & store IDT_VECTORING_INFO_FIELD
We'll want to write to it in order to fix real-mode irq injection problems,
but it is a read-only field. Storing it in a variable solves that issue.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/kvm/vmx.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index d2c25e25d3a..f045f4005ea 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -48,6 +48,7 @@ struct vcpu_vmx { | |||
48 | struct kvm_vcpu vcpu; | 48 | struct kvm_vcpu vcpu; |
49 | int launched; | 49 | int launched; |
50 | u8 fail; | 50 | u8 fail; |
51 | u32 idt_vectoring_info; | ||
51 | struct kvm_msr_entry *guest_msrs; | 52 | struct kvm_msr_entry *guest_msrs; |
52 | struct kvm_msr_entry *host_msrs; | 53 | struct kvm_msr_entry *host_msrs; |
53 | int nmsrs; | 54 | int nmsrs; |
@@ -863,9 +864,10 @@ static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) | |||
863 | 864 | ||
864 | static int vmx_get_irq(struct kvm_vcpu *vcpu) | 865 | static int vmx_get_irq(struct kvm_vcpu *vcpu) |
865 | { | 866 | { |
867 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
866 | u32 idtv_info_field; | 868 | u32 idtv_info_field; |
867 | 869 | ||
868 | idtv_info_field = vmcs_read32(IDT_VECTORING_INFO_FIELD); | 870 | idtv_info_field = vmx->idt_vectoring_info; |
869 | if (idtv_info_field & INTR_INFO_VALID_MASK) { | 871 | if (idtv_info_field & INTR_INFO_VALID_MASK) { |
870 | if (is_external_interrupt(idtv_info_field)) | 872 | if (is_external_interrupt(idtv_info_field)) |
871 | return idtv_info_field & VECTORING_INFO_VECTOR_MASK; | 873 | return idtv_info_field & VECTORING_INFO_VECTOR_MASK; |
@@ -1817,12 +1819,13 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, | |||
1817 | 1819 | ||
1818 | static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 1820 | static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
1819 | { | 1821 | { |
1822 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
1820 | u32 intr_info, error_code; | 1823 | u32 intr_info, error_code; |
1821 | unsigned long cr2, rip; | 1824 | unsigned long cr2, rip; |
1822 | u32 vect_info; | 1825 | u32 vect_info; |
1823 | enum emulation_result er; | 1826 | enum emulation_result er; |
1824 | 1827 | ||
1825 | vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); | 1828 | vect_info = vmx->idt_vectoring_info; |
1826 | intr_info = vmcs_read32(VM_EXIT_INTR_INFO); | 1829 | intr_info = vmcs_read32(VM_EXIT_INTR_INFO); |
1827 | 1830 | ||
1828 | if ((vect_info & VECTORING_INFO_VALID_MASK) && | 1831 | if ((vect_info & VECTORING_INFO_VALID_MASK) && |
@@ -2171,9 +2174,9 @@ static const int kvm_vmx_max_exit_handlers = | |||
2171 | */ | 2174 | */ |
2172 | static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | 2175 | static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) |
2173 | { | 2176 | { |
2174 | u32 vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); | ||
2175 | u32 exit_reason = vmcs_read32(VM_EXIT_REASON); | 2177 | u32 exit_reason = vmcs_read32(VM_EXIT_REASON); |
2176 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 2178 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
2179 | u32 vectoring_info = vmx->idt_vectoring_info; | ||
2177 | 2180 | ||
2178 | if (unlikely(vmx->fail)) { | 2181 | if (unlikely(vmx->fail)) { |
2179 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; | 2182 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; |
@@ -2228,6 +2231,7 @@ static void enable_irq_window(struct kvm_vcpu *vcpu) | |||
2228 | 2231 | ||
2229 | static void vmx_intr_assist(struct kvm_vcpu *vcpu) | 2232 | static void vmx_intr_assist(struct kvm_vcpu *vcpu) |
2230 | { | 2233 | { |
2234 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
2231 | u32 idtv_info_field, intr_info_field; | 2235 | u32 idtv_info_field, intr_info_field; |
2232 | int has_ext_irq, interrupt_window_open; | 2236 | int has_ext_irq, interrupt_window_open; |
2233 | int vector; | 2237 | int vector; |
@@ -2236,7 +2240,7 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu) | |||
2236 | 2240 | ||
2237 | has_ext_irq = kvm_cpu_has_interrupt(vcpu); | 2241 | has_ext_irq = kvm_cpu_has_interrupt(vcpu); |
2238 | intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD); | 2242 | intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD); |
2239 | idtv_info_field = vmcs_read32(IDT_VECTORING_INFO_FIELD); | 2243 | idtv_info_field = vmx->idt_vectoring_info; |
2240 | if (intr_info_field & INTR_INFO_VALID_MASK) { | 2244 | if (intr_info_field & INTR_INFO_VALID_MASK) { |
2241 | if (idtv_info_field & INTR_INFO_VALID_MASK) { | 2245 | if (idtv_info_field & INTR_INFO_VALID_MASK) { |
2242 | /* TODO: fault when IDT_Vectoring */ | 2246 | /* TODO: fault when IDT_Vectoring */ |
@@ -2396,6 +2400,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2396 | #endif | 2400 | #endif |
2397 | ); | 2401 | ); |
2398 | 2402 | ||
2403 | vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); | ||
2404 | |||
2399 | vcpu->interrupt_window_open = | 2405 | vcpu->interrupt_window_open = |
2400 | (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; | 2406 | (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; |
2401 | 2407 | ||
@@ -2413,7 +2419,8 @@ static void vmx_inject_page_fault(struct kvm_vcpu *vcpu, | |||
2413 | unsigned long addr, | 2419 | unsigned long addr, |
2414 | u32 err_code) | 2420 | u32 err_code) |
2415 | { | 2421 | { |
2416 | u32 vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); | 2422 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
2423 | u32 vect_info = vmx->idt_vectoring_info; | ||
2417 | 2424 | ||
2418 | ++vcpu->stat.pf_guest; | 2425 | ++vcpu->stat.pf_guest; |
2419 | 2426 | ||