@@ -7027,11 +7027,14 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
{
unsigned long nr, a0, a1, a2, a3, ret;
int op_64_bit;
+ bool kvmi_hc;
- if (kvm_hv_hypercall_enabled(vcpu->kvm))
+ nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ kvmi_hc = (u32)nr == KVM_HC_XEN_HVM_OP;
+
+ if (kvm_hv_hypercall_enabled(vcpu->kvm) && !kvmi_hc)
return kvm_hv_hypercall(vcpu);
- nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
a0 = kvm_register_read(vcpu, VCPU_REGS_RBX);
a1 = kvm_register_read(vcpu, VCPU_REGS_RCX);
a2 = kvm_register_read(vcpu, VCPU_REGS_RDX);
@@ -7048,7 +7051,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
a3 &= 0xFFFFFFFF;
}
- if (kvm_x86_ops->get_cpl(vcpu) != 0) {
+ if (kvm_x86_ops->get_cpl(vcpu) != 0 && !kvmi_hc) {
ret = -KVM_EPERM;
goto out;
}
@@ -7069,6 +7072,19 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
ret = kvm_pv_send_ipi(vcpu->kvm, a0, a1, a2, a3, op_64_bit);
break;
#endif
+#ifdef CONFIG_KVM_INTROSPECTION
+ case KVM_HC_MEM_MAP:
+ ret = kvmi_host_mem_map(vcpu, (gva_t)a0, (gpa_t)a1, (gpa_t)a2);
+ break;
+ case KVM_HC_MEM_UNMAP:
+ ret = kvmi_host_mem_unmap(vcpu, (gpa_t)a0);
+ break;
+ case KVM_HC_XEN_HVM_OP:
+ ret = 0;
+ if (!kvmi_hypercall_event(vcpu))
+ ret = -KVM_ENOSYS;
+ break;
+#endif /* CONFIG_KVM_INTROSPECTION */
default:
ret = -KVM_ENOSYS;
break;