KVM: x86: Allow deflecting unknown MSR accesses to user space
[sfrench/cifs-2.6.git] / arch / x86 / kvm / emulate.c
index 85111cd0adcd0bae3ba808440bad4af1cf01188d..0cc0db500f718f554e7f111aea36f0e1db32da8a 100644 (file)
@@ -3701,11 +3701,18 @@ static int em_dr_write(struct x86_emulate_ctxt *ctxt)
 
 static int em_wrmsr(struct x86_emulate_ctxt *ctxt)
 {
+       u64 msr_index = reg_read(ctxt, VCPU_REGS_RCX);
        u64 msr_data;
+       int r;
 
        msr_data = (u32)reg_read(ctxt, VCPU_REGS_RAX)
                | ((u64)reg_read(ctxt, VCPU_REGS_RDX) << 32);
-       if (ctxt->ops->set_msr(ctxt, reg_read(ctxt, VCPU_REGS_RCX), msr_data))
+       r = ctxt->ops->set_msr(ctxt, msr_index, msr_data);
+
+       if (r == X86EMUL_IO_NEEDED)
+               return r;
+
+       if (r)
                return emulate_gp(ctxt, 0);
 
        return X86EMUL_CONTINUE;
@@ -3713,9 +3720,16 @@ static int em_wrmsr(struct x86_emulate_ctxt *ctxt)
 
 static int em_rdmsr(struct x86_emulate_ctxt *ctxt)
 {
+       u64 msr_index = reg_read(ctxt, VCPU_REGS_RCX);
        u64 msr_data;
+       int r;
+
+       r = ctxt->ops->get_msr(ctxt, msr_index, &msr_data);
+
+       if (r == X86EMUL_IO_NEEDED)
+               return r;
 
-       if (ctxt->ops->get_msr(ctxt, reg_read(ctxt, VCPU_REGS_RCX), &msr_data))
+       if (r)
                return emulate_gp(ctxt, 0);
 
        *reg_write(ctxt, VCPU_REGS_RAX) = (u32)msr_data;