@@ -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, &hvmctl);
}
int xc_livepatch_upload(xc_interface *xch,
@@ -41,6 +41,7 @@
#include <xenctrl.h>
#include <xenevtchn.h>
#include <xen/vm_event.h>
+#include <xen/hvm/control.h>
#if defined(__arm__) || defined(__aarch64__)
#include <xen/arch-arm.h>
@@ -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);
@@ -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, &op.u.set_mem_type, &op.opaque);
break;
+ case XEN_HVMCTL_inject_trap:
+ rc = inject_trap(d, &op.u.inject_trap);
+ break;
+
default:
rc = -EOPNOTSUPP;
break;
@@ -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(&tr, arg, 1 ) )
- return -EFAULT;
-
- rc = rcu_lock_remote_domain_by_id(tr.domid, &d);
- 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();
@@ -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 of it. Note that the caller should know enough of the
+ * state of the CPU before injecting, to know what the effect of
+ * injecting the trap will be.
+ */
+struct xen_hvm_inject_trap {
+ /* VCPU */
+ uint32_t vcpuid;
+ /* Trap type (XEN_HVMCTL_TRAP_*). */
+ uint8_t type;
+/* NB. This enumeration precisely matches hvm.h:X86_EVENTTYPE_*. */
+#define XEN_HVMCTL_TRAP_ext_int 0 /* external interrupt */
+#define XEN_HVMCTL_TRAP_nmi 2 /* NMI */
+#define XEN_HVMCTL_TRAP_hw_exc 3 /* hardware exception */
+#define XEN_HVMCTL_TRAP_sw_int 4 /* software interrupt (CD nn) */
+#define XEN_HVMCTL_TRAP_pri_sw_exc 5 /* ICEBP (F1) */
+#define XEN_HVMCTL_TRAP_sw_exc 6 /* INT3 (CC), INTO (CE) */
+ /* Vector number. */
+ uint8_t vector;
+ /* Instruction length. */
+ uint8_t insn_len;
+ uint8_t rsvd8;
+ /* Error code, or ~0u to skip. */
+ uint32_t error_code;
+ uint32_t rsvd32;
+ /* CR2 for page faults. */
+ uint64_aligned_t cr2;
+};
+
struct xen_hvmctl {
uint16_t interface_version; /* XEN_HVMCTL_INTERFACE_VERSION */
domid_t domain;
@@ -99,6 +130,7 @@ struct xen_hvmctl {
#define XEN_HVMCTL_track_dirty_vram 4
#define XEN_HVMCTL_modified_memory 5
#define XEN_HVMCTL_set_mem_type 6
+#define XEN_HVMCTL_inject_trap 7
uint64_t opaque; /* Must be zero on initial invocation. */
union {
struct xen_hvm_set_pci_intx_level set_pci_intx_level;
@@ -107,6 +139,7 @@ struct xen_hvmctl {
struct xen_hvm_track_dirty_vram track_dirty_vram;
struct xen_hvm_modified_memory modified_memory;
struct xen_hvm_set_mem_type set_mem_type;
+ struct xen_hvm_inject_trap inject_trap;
uint8_t pad[120];
} u;
};
@@ -123,49 +123,6 @@ struct xen_hvm_xentrace {
typedef struct xen_hvm_xentrace xen_hvm_xentrace_t;
DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t);
-/* Following tools-only interfaces may change in future. */
-#if defined(__XEN__) || defined(__XEN_TOOLS__)
-
-/* Deprecated by XENMEM_access_op_set_access */
-#define HVMOP_set_mem_access 12
-
-/* Deprecated by XENMEM_access_op_get_access */
-#define HVMOP_get_mem_access 13
-
-#define HVMOP_inject_trap 14
-/* Inject a trap into a VCPU, which will get taken up on the next
- * scheduling of it. Note that the caller should know enough of the
- * state of the CPU before injecting, to know what the effect of
- * injecting the trap will be.
- */
-struct xen_hvm_inject_trap {
- /* Domain to be queried. */
- domid_t domid;
- /* VCPU */
- uint32_t vcpuid;
- /* Vector number */
- uint32_t vector;
- /* Trap type (HVMOP_TRAP_*) */
- uint32_t type;
-/* NB. This enumeration precisely matches hvm.h:X86_EVENTTYPE_* */
-# define HVMOP_TRAP_ext_int 0 /* external interrupt */
-# define HVMOP_TRAP_nmi 2 /* nmi */
-# define HVMOP_TRAP_hw_exc 3 /* hardware exception */
-# define HVMOP_TRAP_sw_int 4 /* software interrupt (CD nn) */
-# define HVMOP_TRAP_pri_sw_exc 5 /* ICEBP (F1) */
-# define HVMOP_TRAP_sw_exc 6 /* INT3 (CC), INTO (CE) */
- /* Error code, or ~0u to skip */
- uint32_t error_code;
- /* Intruction length */
- uint32_t insn_len;
- /* CR2 for page faults */
- uint64_aligned_t cr2;
-};
-typedef struct xen_hvm_inject_trap xen_hvm_inject_trap_t;
-DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_trap_t);
-
-#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
-
#define HVMOP_get_mem_type 15
/* Return hvmmem_type_t for the specified pfn. */
struct xen_hvm_get_mem_type {
@@ -273,8 +273,7 @@ class hvm
# XEN_HVMCTL_track_dirty_vram
trackdirtyvram
# XEN_HVMCTL_modified_memory, HVMOP_get_mem_type, XEN_HVMCTL_set_mem_type,
-# HVMOP_set_mem_access, HVMOP_get_mem_access, HVMOP_pagetable_dying,
-# HVMOP_inject_trap
+# HVMOP_pagetable_dying, XEN_HVMCTL_inject_trap
hvmctl
# XEN_DOMCTL_mem_sharing_op and XENMEM_sharing_op_{share,add_physmap} with:
# source = the domain making the hypercall