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