Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b85b9ee9 authored by Rusty Russell's avatar Rusty Russell Committed by Avi Kivity
Browse files

KVM: Clean up unloved invlpg emulation



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: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent c9a1185c
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -539,8 +539,6 @@ 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;

struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
+0 −2
Original line number Diff line number Diff line
@@ -376,8 +376,6 @@ static __init int svm_hardware_setup(void)
	void *iopm_va, *msrpm_va;
	int r;

	kvm_emulator_want_group7_invlpg();

	iopm_pages = alloc_pages(GFP_KERNEL, IOPM_ALLOC_ORDER);

	if (!iopm_pages)
+3 −13
Original line number Diff line number Diff line
@@ -213,19 +213,6 @@ static u16 twobyte_table[256] = {
	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 {
	enum { OP_REG, OP_MEM, OP_IMM } type;
@@ -791,6 +778,9 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
		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;