@@ -3253,12 +3253,17 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
static int emulator_write_emulated_onepage(unsigned long addr,
const void *val,
unsigned int bytes,
- struct kvm_vcpu *vcpu)
+ struct kvm_vcpu *vcpu,
+ bool guest_initiated)
{
gpa_t gpa;
u32 error_code;
- gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, &error_code);
+
+ if (guest_initiated)
+ gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, &error_code);
+ else
+ gpa = kvm_mmu_gva_to_gpa_system(vcpu, addr, &error_code);
if (gpa == UNMAPPED_GVA) {
kvm_inject_page_fault(vcpu, addr, error_code);
@@ -3289,24 +3294,35 @@ mmio:
return X86EMUL_CONTINUE;
}
-int emulator_write_emulated(unsigned long addr,
+int __emulator_write_emulated(unsigned long addr,
const void *val,
unsigned int bytes,
- struct kvm_vcpu *vcpu)
+ struct kvm_vcpu *vcpu,
+ bool guest_initiated)
{
/* Crossing a page boundary? */
if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
int rc, now;
now = -addr & ~PAGE_MASK;
- rc = emulator_write_emulated_onepage(addr, val, now, vcpu);
+ rc = emulator_write_emulated_onepage(addr, val, now, vcpu,
+ guest_initiated);
if (rc != X86EMUL_CONTINUE)
return rc;
addr += now;
val += now;
bytes -= now;
}
- return emulator_write_emulated_onepage(addr, val, bytes, vcpu);
+ return emulator_write_emulated_onepage(addr, val, bytes, vcpu,
+ guest_initiated);
+}
+
+int emulator_write_emulated(unsigned long addr,
+ const void *val,
+ unsigned int bytes,
+ struct kvm_vcpu *vcpu)
+{
+ return __emulator_write_emulated(addr, val, bytes, vcpu, true);
}
EXPORT_SYMBOL_GPL(emulator_write_emulated);
@@ -3997,7 +4013,7 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
kvm_x86_ops->patch_hypercall(vcpu, instruction);
- return emulator_write_emulated(rip, instruction, 3, vcpu);
+ return __emulator_write_emulated(rip, instruction, 3, vcpu, false);
}
static u64 mk_cr_64(u64 curr_cr, u32 new_val)