@@ -488,27 +488,11 @@ int xc_hvm_set_isa_irq_level(
uint8_t isa_irq,
unsigned int level)
{
- DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_isa_irq_level, arg);
- int rc;
+ DECLARE_HVMCTL(set_isa_irq_level, dom,
+ .isa_irq = isa_irq,
+ .level = level);
- arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
- if ( arg == NULL )
- {
- PERROR("Could not allocate memory for xc_hvm_set_isa_irq_level hypercall");
- return -1;
- }
-
- arg->domid = dom;
- arg->isa_irq = isa_irq;
- arg->level = level;
-
- rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
- HVMOP_set_isa_irq_level,
- HYPERCALL_BUFFER_AS_ARG(arg));
-
- xc_hypercall_buffer_free(xch, arg);
-
- return rc;
+ return do_hvmctl(xch, &hvmctl);
}
int xc_hvm_set_pci_link_route(
@@ -43,6 +43,30 @@ static int set_pci_intx_level(struct dom
return 0;
}
+static int set_isa_irq_level(struct domain *d,
+ const struct xen_hvm_set_isa_irq_level *op)
+{
+ if ( op->isa_irq > 15 )
+ return -EINVAL;
+
+ if ( !is_hvm_domain(d) )
+ return -EINVAL;
+
+ switch ( op->level )
+ {
+ case 0:
+ hvm_isa_irq_deassert(d, op->isa_irq);
+ break;
+ case 1:
+ hvm_isa_irq_assert(d, op->isa_irq);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
long do_hvmctl(XEN_GUEST_HANDLE_PARAM(xen_hvmctl_t) u_hvmctl)
{
xen_hvmctl_t op;
@@ -80,6 +104,10 @@ long do_hvmctl(XEN_GUEST_HANDLE_PARAM(xe
rc = set_pci_intx_level(d, &op.u.set_pci_intx_level);
break;
+ case XEN_HVMCTL_set_isa_irq_level:
+ rc = set_isa_irq_level(d, &op.u.set_isa_irq_level);
+ break;
+
default:
rc = -EOPNOTSUPP;
break;
@@ -4446,50 +4446,6 @@ static void hvm_s3_resume(struct domain
}
}
-static int hvmop_set_isa_irq_level(
- XEN_GUEST_HANDLE_PARAM(xen_hvm_set_isa_irq_level_t) uop)
-{
- struct xen_hvm_set_isa_irq_level op;
- struct domain *d;
- int rc;
-
- if ( copy_from_guest(&op, uop, 1) )
- return -EFAULT;
-
- if ( op.isa_irq > 15 )
- return -EINVAL;
-
- rc = rcu_lock_remote_domain_by_id(op.domid, &d);
- if ( rc != 0 )
- return rc;
-
- rc = -EINVAL;
- if ( !is_hvm_domain(d) )
- goto out;
-
- rc = xsm_hvm_set_isa_irq_level(XSM_DM_PRIV, d);
- if ( rc )
- goto out;
-
- rc = 0;
- switch ( op.level )
- {
- case 0:
- hvm_isa_irq_deassert(d, op.isa_irq);
- break;
- case 1:
- hvm_isa_irq_assert(d, op.isa_irq);
- break;
- default:
- rc = -EINVAL;
- break;
- }
-
- out:
- rcu_unlock_domain(d);
- return rc;
-}
-
static int hvmop_set_pci_link_route(
XEN_GUEST_HANDLE_PARAM(xen_hvm_set_pci_link_route_t) uop)
{
@@ -5364,11 +5320,6 @@ long do_hvm_op(unsigned long op, XEN_GUE
guest_handle_cast(arg, xen_hvm_param_t));
break;
- case HVMOP_set_isa_irq_level:
- rc = hvmop_set_isa_irq_level(
- guest_handle_cast(arg, xen_hvm_set_isa_irq_level_t));
- break;
-
case HVMOP_inject_msi:
rc = hvmop_inject_msi(
guest_handle_cast(arg, xen_hvm_inject_msi_t));
@@ -38,14 +38,25 @@ struct xen_hvm_set_pci_intx_level {
uint8_t level;
};
+/* XEN_HVMCTL_set_isa_irq_level */
+/* Set the logical level of one of a domain's ISA IRQ wires. */
+struct xen_hvm_set_isa_irq_level {
+ /* ISA device identification, by ISA IRQ (0-15). */
+ uint8_t isa_irq;
+ /* Assertion level (0 = unasserted, 1 = asserted). */
+ uint8_t level;
+};
+
struct xen_hvmctl {
uint16_t interface_version; /* XEN_HVMCTL_INTERFACE_VERSION */
domid_t domain;
uint32_t cmd;
#define XEN_HVMCTL_set_pci_intx_level 1
+#define XEN_HVMCTL_set_isa_irq_level 2
uint64_t opaque; /* Must be zero on initial invocation. */
union {
struct xen_hvm_set_pci_intx_level set_pci_intx_level;
+ struct xen_hvm_set_isa_irq_level set_isa_irq_level;
uint8_t pad[120];
} u;
};
@@ -53,8 +53,6 @@ struct xen_hvm_set_pci_intx_level {
typedef struct xen_hvm_set_pci_intx_level xen_hvm_set_pci_intx_level_t;
DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t);
-#endif
-
/* Set the logical level of one of a domain's ISA IRQ wires. */
#define HVMOP_set_isa_irq_level 3
struct xen_hvm_set_isa_irq_level {
@@ -68,6 +66,8 @@ struct xen_hvm_set_isa_irq_level {
typedef struct xen_hvm_set_isa_irq_level xen_hvm_set_isa_irq_level_t;
DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t);
+#endif
+
#define HVMOP_set_pci_link_route 4
struct xen_hvm_set_pci_link_route {
/* Domain to be updated. */
@@ -609,12 +609,6 @@ static XSM_INLINE int xsm_shadow_control
return xsm_default_action(action, current->domain, d);
}
-static XSM_INLINE int xsm_hvm_set_isa_irq_level(XSM_DEFAULT_ARG struct domain *d)
-{
- XSM_ASSERT_ACTION(XSM_DM_PRIV);
- return xsm_default_action(action, current->domain, d);
-}
-
static XSM_INLINE int xsm_hvm_set_pci_link_route(XSM_DEFAULT_ARG struct domain *d)
{
XSM_ASSERT_ACTION(XSM_DM_PRIV);
@@ -173,7 +173,6 @@ struct xsm_operations {
#ifdef CONFIG_X86
int (*do_mca) (void);
int (*shadow_control) (struct domain *d, uint32_t op);
- int (*hvm_set_isa_irq_level) (struct domain *d);
int (*hvm_set_pci_link_route) (struct domain *d);
int (*hvm_inject_msi) (struct domain *d);
int (*hvm_ioreq_server) (struct domain *d, int op);
@@ -645,11 +644,6 @@ static inline int xsm_shadow_control (xs
return xsm_ops->shadow_control(d, op);
}
-static inline int xsm_hvm_set_isa_irq_level (xsm_default_t def, struct domain *d)
-{
- return xsm_ops->hvm_set_isa_irq_level(d);
-}
-
static inline int xsm_hvm_set_pci_link_route (xsm_default_t def, struct domain *d)
{
return xsm_ops->hvm_set_pci_link_route(d);
@@ -145,7 +145,6 @@ void xsm_fixup_ops (struct xsm_operation
#ifdef CONFIG_X86
set_to_dummy_if_null(ops, do_mca);
set_to_dummy_if_null(ops, shadow_control);
- set_to_dummy_if_null(ops, hvm_set_isa_irq_level);
set_to_dummy_if_null(ops, hvm_set_pci_link_route);
set_to_dummy_if_null(ops, hvm_inject_msi);
set_to_dummy_if_null(ops, hvm_ioreq_server);
@@ -1193,6 +1193,9 @@ static int flask_hvm_control(struct doma
case XEN_HVMCTL_set_pci_intx_level:
perm = HVM__PCILEVEL;
break;
+ case XEN_HVMCTL_set_isa_irq_level:
+ perm = HVM__IRQLEVEL;
+ break;
default:
perm = HVM__HVMCTL;
break;
@@ -1517,11 +1520,6 @@ static int flask_ioport_mapping(struct d
return flask_ioport_permission(d, start, end, access);
}
-static int flask_hvm_set_isa_irq_level(struct domain *d)
-{
- return current_has_perm(d, SECCLASS_HVM, HVM__IRQLEVEL);
-}
-
static int flask_hvm_set_pci_link_route(struct domain *d)
{
return current_has_perm(d, SECCLASS_HVM, HVM__PCIROUTE);
@@ -1805,7 +1803,6 @@ static struct xsm_operations flask_ops =
#ifdef CONFIG_X86
.do_mca = flask_do_mca,
.shadow_control = flask_shadow_control,
- .hvm_set_isa_irq_level = flask_hvm_set_isa_irq_level,
.hvm_set_pci_link_route = flask_hvm_set_pci_link_route,
.hvm_inject_msi = flask_hvm_inject_msi,
.hvm_ioreq_server = flask_hvm_ioreq_server,
@@ -263,7 +263,7 @@ class hvm
getparam
# XEN_HVMCTL_set_pci_intx_level
pcilevel
-# HVMOP_set_isa_irq_level
+# XEN_HVMCTL_set_isa_irq_level
irqlevel
# HVMOP_set_pci_link_route
pciroute