Signed-off-by: Jan Beulich
Reviewed-by: Wei Liu
Reviewed-by: Andrew Cooper
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -584,31 +584,15 @@ int xc_hvm_inject_trap(
uint32_t type, uint32_t error_code, uint32_t insn_len,
uint64_t cr2)
{
-DECLARE_HYPERCALL_BUFFER(struct xen_hvm_inject_trap, arg);
-int rc;
+DECLARE_HVMCTL(inject_trap, dom,
+ .vcpuid = vcpu,
+ .type = type,
+ .vector = vector,
+ .insn_len = insn_len,
+ .error_code = error_code,
+ .cr2= cr2);
-arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
-if ( arg == NULL )
-{
-PERROR("Could not allocate memory for xc_hvm_inject_trap hypercall");
-return -1;
-}
-
-arg->domid = dom;
-arg->vcpuid = vcpu;
-arg->vector = vector;
-arg->type= type;
-arg->error_code = error_code;
-arg->insn_len= insn_len;
-arg->cr2 = cr2;
-
-rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
- HVMOP_inject_trap,
- HYPERCALL_BUFFER_AS_ARG(arg));
-
-xc_hypercall_buffer_free(xch, arg);
-
-return rc;
+return do_hvmctl(xch, );
}
int xc_livepatch_upload(xc_interface *xch,
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#if defined(__arm__) || defined(__aarch64__)
#include
@@ -643,7 +644,7 @@ int main(int argc, char *argv[])
/* Reinject */
rc = xc_hvm_inject_trap(
xch, domain_id, req.vcpu_id, 3,
-HVMOP_TRAP_sw_exc, -1, 0, 0);
+XEN_HVMCTL_TRAP_sw_exc, -1, 0, 0);
if (rc < 0)
{
ERROR("Error %d injecting breakpoint\n", rc);
--- a/xen/arch/x86/hvm/control.c
+++ b/xen/arch/x86/hvm/control.c
@@ -200,6 +200,32 @@ static int set_mem_type(struct domain *d
return 0;
}
+static int inject_trap(struct domain *d,
+ const struct xen_hvm_inject_trap *op)
+{
+struct vcpu *v;
+
+if ( !is_hvm_domain(d) )
+return -EINVAL;
+
+if ( op->rsvd8 || op->rsvd32 )
+return -EINVAL;
+
+if ( op->vcpuid >= d->max_vcpus || (v = d->vcpu[op->vcpuid]) == NULL )
+return -ENOENT;
+
+if ( v->arch.hvm_vcpu.inject_trap.vector != -1 )
+return -EBUSY;
+
+v->arch.hvm_vcpu.inject_trap.vector = op->vector;
+v->arch.hvm_vcpu.inject_trap.type = op->type;
+v->arch.hvm_vcpu.inject_trap.error_code = op->error_code;
+v->arch.hvm_vcpu.inject_trap.insn_len = op->insn_len;
+v->arch.hvm_vcpu.inject_trap.cr2= op->cr2;
+
+return 0;
+}
+
long do_hvmctl(XEN_GUEST_HANDLE_PARAM(xen_hvmctl_t) u_hvmctl)
{
xen_hvmctl_t op;
@@ -258,6 +284,10 @@ long do_hvmctl(XEN_GUEST_HANDLE_PARAM(xe
rc = set_mem_type(d, _mem_type, );
break;
+case XEN_HVMCTL_inject_trap:
+rc = inject_trap(d, _trap);
+break;
+
default:
rc = -EOPNOTSUPP;
break;
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -5366,48 +5366,6 @@ long do_hvm_op(unsigned long op, XEN_GUE
break;
}
-case HVMOP_inject_trap:
-{
-xen_hvm_inject_trap_t tr;
-struct domain *d;
-struct vcpu *v;
-
-if ( copy_from_guest(, arg, 1 ) )
-return -EFAULT;
-
-rc = rcu_lock_remote_domain_by_id(tr.domid, );
-if ( rc != 0 )
-return rc;
-
-rc = -EINVAL;
-if ( !is_hvm_domain(d) )
-goto injtrap_fail;
-
-rc = xsm_hvm_control(XSM_DM_PRIV, d, op);
-if ( rc )
-goto injtrap_fail;
-
-rc = -ENOENT;
-if ( tr.vcpuid >= d->max_vcpus || (v = d->vcpu[tr.vcpuid]) == NULL )
-goto injtrap_fail;
-
-if ( v->arch.hvm_vcpu.inject_trap.vector != -1 )
-rc = -EBUSY;
-else
-{
-v->arch.hvm_vcpu.inject_trap.vector = tr.vector;
-v->arch.hvm_vcpu.inject_trap.type = tr.type;
-v->arch.hvm_vcpu.inject_trap.error_code = tr.error_code;
-v->arch.hvm_vcpu.inject_trap.insn_len = tr.insn_len;
-v->arch.hvm_vcpu.inject_trap.cr2 = tr.cr2;
-rc = 0;
-}
-
-injtrap_fail:
-rcu_unlock_domain(d);
-break;
-}
-
case HVMOP_guest_request_vm_event:
if ( guest_handle_is_null(arg) )
vm_event_monitor_guest_request();
--- a/xen/include/public/hvm/control.h
+++ b/xen/include/public/hvm/control.h
@@ -89,6 +89,37 @@ struct xen_hvm_set_mem_type {
uint64_aligned_t first_gfn;
};
+/* XEN_HVMCTL_inject_trap */
+/*
+ * Inject a trap into a VCPU, which will get taken up on the next
+ * scheduling