Clean up unloved invlpg: remove kvm_arch_ops.invlpg and tweak emulator. 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. Signed-off-by: Rusty Russell 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 @@ -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/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; + /* Don't fetch the address for invlpg: it could be unmapped. */ + if (twobyte && b == 0x01 && modrm_reg == 7) + break; srcmem_common: src.type = OP_MEM; src.ptr = (unsigned long *)cr2;