fleshing out the ioport support
cover fleshing out the ioport support
This patchset fleshes out the support for ioport access control, adding the following features:
* the ability to hide port ranges from dom0 at boot
* control over port permissions from libxc/Xc
* the ability to add port ranges to new domains from xend/xm
All of the above has been build-tested, but only the first item has been run-tested, as the really old udev on the system I'm testing this on doesn't want to work with a 2.6.12 kernel.
J
Signature · 2 lines
Jody Belka knew (at) pimb (dot) org
PATCH 1/4 ioports: disable ioports in dom0 at boot-time
1/3
Signature · 2 lines
Jody Belka knew (at) pimb (dot) org
# HG changeset patch
# User [email protected]
# Node ID 9e1a127dc366ec3359471feffb7e12a46bd16687 # Parent 0cae0c6436f5fa49ab42f72ea90373cc5884d93a Add boot-time support for disabling ioport ranges in dom0
This patch adds a new boot parameter, dom0_ioports_disable, which accepts a comma seperated list of hex ioports and/or ioport ranges (eg. dom0_ioports_disable=02f8-02ff,03f8-03ff), and applies them to dom0.
xen/arch/x86/domain_build.c +50 -0
@@ -56,6 +56,9 @@static unsigned int opt_dom0_translate =0 ;boolean_param ("dom0_translate" , opt_dom0_translate); +static char opt_dom0_ioports_disable[200 ] ="" ; +string_param ("dom0_ioports_disable" , opt_dom0_ioports_disable); +#if defined(__i386__)/* No ring-3 access in initial leaf page tables. */ #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
@@ -89,6 +92,51 @@if ( order-- ==0 )break ;return page; +} + +static void process_dom0_ioports_disable () +{ +unsigned long io_from, io_to, io_nr; +char *t, *u, *s = opt_dom0_ioports_disable; + +if (*s =='\0' )return ; +for (; (t =strsep (&s,"," )) !=NULL ;) + { +if ( *t =='\n' )continue ; + + io_from =simple_strtoul (t, &u,16 ); +if ( u == t || *u !='-' ) + { +printk ("Invalid ioport range <%s> " +"in dom0_ioports_disable, skipping\n" , t); +continue ; + } + +if ( u == s -1 ) + io_to = io_from; +else + io_to =simple_strtoul (u +1 , &u,16 ); + +if ( *u !='\0' || io_to < io_from ) + { +printk ("Invalid ioport range <%s> " +"in dom0_ioports_disable, skipping\n" , t); +continue ; + } + +if ( (io_from + io_to) >=65536 ) + { +printk ("Invalid ioport range <%s> " +"in dom0_ioports_disable, skipping\n" , t); +continue ; + } + +printk ("Disabling access to ioport range %04lx-%04lx from dom0\n" , + io_from, io_to); + + io_nr = io_to - io_from +1 ; +physdev_modify_ioport_access_range (dom0,0 , io_from, io_nr); + } } int construct_dom0(struct domain *d,
@@ -716,6 +764,8 @@physdev_modify_ioport_access_range (dom0,0 ,0x40 ,4 );/* PIT Channel 2 / PC Speaker Control. */ physdev_modify_ioport_access_range (dom0,0 ,0x61 ,1 ); +/* Command-line passed i/o ranges */ +process_dom0_ioports_disable ();return 0 ; }
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
PATCH 2/4 ioports: libxc support
In reply to [email protected]2/4
Signature · 2 lines
Jody Belka knew (at) pimb (dot) org
# HG changeset patch
# User [email protected]
# Node ID d8d62e726d8d217dde4fbc33962d9c4be115befc
# Parent 9e1a127dc366ec3359471feffb7e12a46bd16687
Added xc_domain_ioport_permission to libxc, which wraps the dom0 op
tools/libxc/xc_domain.c +17 -0
@@ -364,6 +364,23 @@return rc; } +int xc_domain_ioport_permission (int xc_handle, +uint32_t domid, +uint16_t first_port, +uint16_t nr_ports, +uint16_t allow_access) +{ +dom0_op_t op; + + op.cmd =DOM0_IOPORT_PERMISSION ; + op.u.ioport_permission.domain = (domid_t )domid; + op.u.ioport_permission.first_port = first_port; + op.u.ioport_permission.nr_ports = nr_ports; + op.u.ioport_permission.allow_access = allow_access; + +return do_dom0_op (xc_handle, &op); +} +/* * Local variables: * mode: C
tools/libxc/xenctrl.h +6 -0
@@ -371,6 +371,12 @@unsigned int extent_order, unsigned long *extent_start); +int xc_domain_ioport_permission (int xc_handle, +uint32_t domid, +uint16_t first_port, +uint16_t nr_ports, +uint16_t allow_access); +unsigned long xc_make_page_below_4G (int xc_handle,uint32_t domid,unsigned long mfn);
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
PATCH 3/4 ioports: xen.lowlevel.xc support
In reply to [email protected]3/4
Signature · 2 lines
Jody Belka knew (at) pimb (dot) org
# HG changeset patch
# User [email protected]
# Node ID 3acad8d6d0cf5c8a00833aea7fdbb20f9e73868e
# Parent d8d62e726d8d217dde4fbc33962d9c4be115befc
Added domain_ioport_permission to the python module xen.lowlevel.xc, wrapping the equivalent libxc call
tools/python/xen/lowlevel/xc/xc.c +33 -0
@@ -858,6 +858,29 @@return zero; } +static PyObject *pyxc_domain_ioport_permission (PyObject *self, +PyObject *args, +PyObject *kwds) +{ +XcObject *xc = (XcObject *)self; +uint32_t dom; +int first_port, nr_ports, allow_access, ret; + +static char *kwd_list[] = {"dom" ,"first_port" ,"nr_ports" ,"allow_access" ,NULL }; + +if ( !PyArg_ParseTupleAndKeywords (args, kwds,"iiii" , kwd_list, + &dom, &first_port, &nr_ports, &allow_access) ) +return NULL ; + + ret =xc_domain_ioport_permission ( + xc->xc_handle, dom, first_port, nr_ports, allow_access); +if ( ret !=0 ) +return PyErr_SetFromErrno (xc_error); + +Py_INCREF (zero); +return zero; +} +static PyMethodDef pyxc_methods[] = { {"handle" , (PyCFunction )pyxc_handle,
@@ -1127,6 +1150,16 @@ " mem_kb [long]: .\n" "Returns: [int] 0 on success; -1 on error.\n" }, + {"domain_ioport_permission" , + (PyCFunction )pyxc_domain_ioport_permission, +METH_VARARGS |METH_KEYWORDS ,"\n" +"Allow a domain access to a range of IO ports\n" +" dom [int]: Identifier of domain to be allowed access.\n" +" first_port [int]: First IO port\n" +" nr_ports [int]: Number of IO ports\n" +" allow_access [int]: Non-zero means enable access; else disable access\n\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + { NULL, NULL, 0, NULL } };
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
PATCH 4/4 ioports: xend/xm support
In reply to [email protected]4/4
Signature · 2 lines
Jody Belka knew (at) pimb (dot) org
# HG changeset patch
# User [email protected]
# Node ID e2b5c74938f64d55609a690c22a18c3875b21d04 # Parent 3acad8d6d0cf5c8a00833aea7fdbb20f9e73868e Add support for the ioport_permission dom0 op to xend and xm
xm now accepts a parameter 'ioports' that accepts a hex ioport or ioport range, in the form 02f8[-02ff]
tools/python/xen/xend/XendDomain.py +34 -0
@@ -492,6 +492,40 @@ except Exception, ex: raise XendError(str(ex)) + def domain_ioport_range_enable(self, domid, first, last): + """Enable access to a range of IO ports for a domain + + @param first: first IO port + @param last: last IO port + @return: 0 on success, -1 on error + """ + dominfo = self.domain_lookup(domid) + nr_ports = last - first + 1 + try: + return xc.domain_ioport_permission(dominfo.getDomid(), + first_port = first, + nr_ports = nr_ports, + allow_access = 1) + except Exception, ex: + raise XendError(str(ex)) + + def domain_ioport_range_disable(self, domid, first, last): + """Disable access to a range of IO ports for a domain + + @param first: first IO port + @param last: last IO port + @return: 0 on success, -1 on error + """ + dominfo = self.domain_lookup(domid) + nr_ports = last - first + 1 + try: + return xc.domain_ioport_permission(dominfo.getDomid(), + first_port = first, + nr_ports = nr_ports, + allow_access = 0) + except Exception, ex: + raise XendError(str(ex)) + def instance(): """Singleton constructor. Use this instead of the class constructor.
tools/python/xen/xend/XendDomainInfo.py +2 -1
@@ -1400,9 +1400,10 @@ controllerClasses[device_class] = cls -from xen.xend.server import blkif, netif, tpmif, pciif, usbif +from xen.xend.server import blkif, netif, tpmif, pciif, iopif, usbif addControllerClass('vbd', blkif.BlkifController) addControllerClass('vif', netif.NetifController) addControllerClass('vtpm', tpmif.TPMifController) addControllerClass('pci', pciif.PciController) +addControllerClass('ioports', iopif.IOPortsController) addControllerClass('usb', usbif.UsbifController)
tools/python/xen/xm/create.py +29 -0
@@ -241,6 +241,12 @@ For example '-pci c0,02,1a'. The option may be repeated to add more than one pci device.""") +gopts.var('ioports', val='FROM[-TO]', + fn=append_value, default=[], + use="""Add a legacy I/O range to a domain, using given params (in hex). + For example '-ioports 02f8-02ff'. + The option may be repeated to add more than one i/o range.""") + gopts.var('usb', val='PATH', fn=append_value, default=[], use="""Add a physical USB port to a domain, as specified by the path
@@ -438,6 +444,13 @@ for (bus, dev, func) in vals.pci: config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]] config_devs.append(['device', config_pci]) + +def configure_ioports(config_devs, vals): + """Create the config for legacy i/o ranges. + """ + for (io_from, io_to) in vals.ioports: + config_ioports = ['ioports', ['from', io_from], ['to', io_to]] + config_devs.append(['device', config_ioports]) def configure_usb(config_devs, vals): for path in vals.usb:
@@ -611,6 +624,7 @@ config_devs = [] configure_disks(config_devs, vals) configure_pci(config_devs, vals) + configure_ioports(config_devs, vals) configure_vifs(config_devs, vals) configure_usb(config_devs, vals) configure_vtpm(config_devs, vals)
@@ -645,6 +659,20 @@ pci.append(hexd) vals.pci = pci +def preprocess_ioports(vals): + if not vals.ioports: return + ioports = [] + for v in vals.ioports: + d = v.split('-') + if len(d) < 1 || len(d) > 2: + err('Invalid i/o port range specifier: ' + v) + if len(d) == 1: + d.append(d[0]) + # Components are in hex: add hex specifier. + hexd = map(lambda v: '0x'+v, d) + ioports.append(hexd) + vals.ioports = ioports + def preprocess_vifs(vals): if not vals.vif: return vifs = []
@@ -777,6 +805,7 @@ err("No kernel specified") preprocess_disk(vals) preprocess_pci(vals) + preprocess_ioports(vals) preprocess_vifs(vals) preprocess_ip(vals) preprocess_nfs(vals)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
[PATCH 5/4] ioports: iopif.py missing from last patch
In reply to [email protected]5/4
Possibly i shouldn't finish up patches and send them off in the early hours of the morning :)
Signature · 2 lines
Jody Belka knew (at) pimb (dot) org
# HG changeset patch
# User [email protected]
# Node ID 75f02d1da63baae6c51b6a51bb53034f639ec40a # Parent e2b5c74938f64d55609a690c22a18c3875b21d04 Somehow iopif.py got missed out of the previous commit. duh.
tools/python/xen/xend/server/iopif.py new file +86 -0
@@ -0,0 +1,86 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2004, 2005 Mike Wray <[email protected]> +# Copyright (C) 2005 XenSource Ltd +# Copyright (C) 2005 Jody Belka +#============================================================================ + + +import types + +import xen.lowlevel.xc; + +from xen.xend import sxp +from xen.xend.XendError import VmError + +from xen.xend.server.DevController import DevController + + +xc = xen.lowlevel.xc.new() + + +def parse_ioport(val): + """Parse an i/o port field. + """ + if isinstance(val, types.StringType): + radix = 10 + if val.startswith('0x') or val.startswith('0X'): + radix = 16 + v = int(val, radix) + else: + v = val + return v + + +class IOPortsController(DevController): + + def __init__(self, vm): + DevController.__init__(self, vm) + + + def getDeviceDetails(self, config): + """@see DevController.getDeviceDetails""" + + def get_param(field): + try: + val = sxp.child_value(config, field) + + if not val: + raise VmError('ioports: Missing %s config setting' % field) + + return parse_ioport(val) + except: + raise VmError('ioports: Invalid config setting %s: %s' % + (field, val)) + + io_from = get_param('from') + io_to = get_param('to') + + if io_to < io_from or io_to >= 65536: + raise VmError('ioports: Invalid i/o range: %s - %s' % + (io_from, io_to)) + + rc = xc.domain_ioport_permission(dom = self.getDomid(), + first_port = io_from, + nr_ports = io_to - io_from + 1, + allow_access = True) + + if rc < 0: + #todo non-fatal + raise VmError( + 'ioports: Failed to configure legacy i/o range: %s - %s' % + (io_from, io_to)) + + return (dev, {}, {})
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel