aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-11-22 04:30:47 -0500
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:53:00 -0500
commit1155f76a8166ae6fc88e7d73eb6817eb9012d476 (patch)
treebecc954dacc6098f9c60bc52d572ca8179e070e4 /drivers
parent9c5623e3e42e94927d02a6693875badf15692970 (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.c17
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
864static int vmx_get_irq(struct kvm_vcpu *vcpu) 865static 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
1818static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1820static 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 */
2172static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) 2175static 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
2229static void vmx_intr_assist(struct kvm_vcpu *vcpu) 2232static 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