invlpg shouldn't fetch the "src" address, since it may not be valid,
however SVM's "solution" which neuters emulation of all group 7
instruction is horrible and breaks kvm-lite.  The simplest fix is to
put a special check in for invlpg.

Also, remove the unused invlpg member of struct kvm_arch_ops.

Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>

diff -r 01dea2154ac6 drivers/kvm/kvm.h
--- a/drivers/kvm/kvm.h Tue Aug 21 10:11:26 2007 +1000
+++ b/drivers/kvm/kvm.h Thu Aug 30 11:17:45 2007 +1000
@@ -459,7 +460,6 @@ struct kvm_arch_ops {
        unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
        void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
 
-       void (*invlpg)(struct kvm_vcpu *vcpu, gva_t addr);
        void (*tlb_flush)(struct kvm_vcpu *vcpu);
        void (*inject_page_fault)(struct kvm_vcpu *vcpu,
                                  unsigned long addr, u32 err_code);
@@ -509,8 +513,6 @@ static inline int is_error_hpa(hpa_t hpa
 static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; }
 hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva);
 struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva);
-
-void kvm_emulator_want_group7_invlpg(void);
 
 extern hpa_t bad_page_address;
 
diff -r 01dea2154ac6 drivers/kvm/svm.c
--- a/drivers/kvm/svm.c Tue Aug 21 10:11:26 2007 +1000
+++ b/drivers/kvm/svm.c Thu Aug 30 11:16:34 2007 +1000
@@ -817,11 +809,6 @@ static void new_asid(struct vcpu_svm *sv
        svm->vcpu.cpu = svm_data->cpu;
        svm->asid_generation = svm_data->asid_generation;
        svm->vmcb->control.asid = svm_data->next_asid++;
-}
-
-static void svm_invlpg(struct kvm_vcpu *vcpu, gva_t address)
-{
-       invlpga(address, to_svm(vcpu)->vmcb->control.asid); // is needed?
 }
 
 static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
@@ -1668,7 +1655,6 @@ static struct kvm_arch_ops svm_arch_ops 
        .get_rflags = svm_get_rflags,
        .set_rflags = svm_set_rflags,
 
-       .invlpg = svm_invlpg,
        .tlb_flush = svm_flush_tlb,
        .inject_page_fault = svm_inject_page_fault,
 
diff -r 01dea2154ac6 drivers/kvm/x86_emulate.c
--- a/drivers/kvm/x86_emulate.c Tue Aug 21 10:11:26 2007 +1000
+++ b/drivers/kvm/x86_emulate.c Thu Aug 30 11:17:33 2007 +1000
@@ -212,19 +212,6 @@ static u16 twobyte_table[256] = {
        /* 0xF0 - 0xFF */
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
-
-/*
- * Tell the emulator that of the Group 7 instructions (sgdt, lidt, etc.) we
- * are interested only in invlpg and not in any of the rest.
- *
- * invlpg is a special instruction in that the data it references may not
- * be mapped.
- */
-void kvm_emulator_want_group7_invlpg(void)
-{
-       twobyte_table[1] &= ~SrcMem;
-}
-EXPORT_SYMBOL_GPL(kvm_emulator_want_group7_invlpg);
 
 /* Type, address-of, and value of an instruction's operand. */
 struct operand {
@@ -791,6 +778,9 @@ done_prefixes:
                goto srcmem_common;
        case SrcMem:
                src.bytes = (d & ByteOp) ? 1 : op_bytes;
+               /* Invlpg: don't fetch the address it could be crap. */
+               if (twobyte && b == 0x01 && modrm_reg == 7)
+                       break;
              srcmem_common:
                src.type = OP_MEM;
                src.ptr = (unsigned long *)cr2;



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to