From: t_jeang Date: Tue, 6 Jan 2009 12:06:04 +0000 (+0000) Subject: Add a new ioctl to /proc/xen/privcmd which allows you to do certain X-Git-Tag: privcmd_schedop X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=669fbfd8b12063e4d7308a6e435566e952773337;p=xenclient%2Fkernel.git Add a new ioctl to /proc/xen/privcmd which allows you to do certain XENMEM operations on restricted fds. --- diff --git a/drivers/xen/privcmd/privcmd.c b/drivers/xen/privcmd/privcmd.c index 8d3b81ee..f97c9bfa 100644 --- a/drivers/xen/privcmd/privcmd.c +++ b/drivers/xen/privcmd/privcmd.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -328,6 +329,73 @@ static long privcmd_ioctl(struct file *file, } break; + case IOCTL_PRIVCMD_MEMOP: { + privcmd_memop_t pmt; + + if (copy_from_user(&pmt, udata, sizeof(pmt))) + return -EFAULT; + + if (fdata->restrict_domid != UNRESTRICTED_DOMID) { + switch (pmt.cmd) { + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + case XENMEM_populate_physmap: + if (pmt.u.reservation.domid != + fdata->restrict_domid) + return -EACCES; + break; + case XENMEM_exchange: + /* This is checked by Xen, but do it + here as well for sanity. */ + if (pmt.u.exchange.in.domid != + pmt.u.exchange.out.domid) + return -EINVAL; + if (pmt.u.exchange.in.domid != + fdata->restrict_domid) + return -EACCES; + break; + case XENMEM_maximum_ram_page: + case XENMEM_machphys_mfn_list: + case XENMEM_machphys_mapping: + case XENMEM_memory_map: + case XENMEM_machine_memory_map: + return -EACCES; + case XENMEM_current_reservation: + case XENMEM_maximum_reservation: + case XENMEM_maximum_gpfn: + if (pmt.u.domid != + fdata->restrict_domid) + return -EACCES; + break; + case XENMEM_add_to_physmap: + if (pmt.u.add_to_physmap.domid != + fdata->restrict_domid) + return -EACCES; + break; + case XENMEM_translate_gpfn_list: + if (pmt.u.translate_gpfn.domid != + fdata->restrict_domid) + return -EACCES; + break; + case XENMEM_set_memory_map: + if (pmt.u.foreign_memory_map.domid != + fdata->restrict_domid) + return -EACCES; + break; + default: + return -EACCES; + } + } + + ret = HYPERVISOR_memory_op(pmt.cmd, &pmt.u); + if (ret >= 0) { + if (copy_to_user(udata, &pmt, sizeof(pmt))) + ret = -EFAULT; + } + break; + } + break; + case IOCTL_PRIVCMD_HVMOP: { privcmd_hvmop_t pht; diff --git a/include/xen/public/privcmd.h b/include/xen/public/privcmd.h index 5b048f7b..0c569af7 100644 --- a/include/xen/public/privcmd.h +++ b/include/xen/public/privcmd.h @@ -35,9 +35,11 @@ #include #ifdef __KERNEL__ -#include +#include +#include #else #include +#include #endif #ifndef __user @@ -73,6 +75,21 @@ typedef struct privcmd_restrict_domid { domid_t domid; } privcmd_restrict_domid_t; +typedef struct privcmd_memop { + unsigned cmd; + union { + xen_memory_reservation_t reservation; + xen_memory_exchange_t exchange; + domid_t domid; + xen_add_to_physmap_t add_to_physmap; + xen_translate_gpfn_list_t translate_gpfn; + xen_foreign_memory_map_t foreign_memory_map; + xen_machphys_mfn_list_t machphys_mfn_list; + xen_machphys_mapping_t machphys_mapping; + xen_memory_map_t memory_map; + } u; +} privcmd_memop_t; + typedef struct privcmd_hvmop { unsigned cmd; union { @@ -105,5 +122,7 @@ typedef struct privcmd_hvmop { _IOC(_IOC_NONE, 'P', 6, sizeof(privcmd_hvmop_t)) #define IOCTL_PRIVCMD_SHUTDOWN \ _IOC(_IOC_NONE, 'P', 7, sizeof(sched_remote_shutdown_t)) +#define IOCTL_PRIVCMD_MEMOP \ + _IOC(_IOC_NONE, 'P', 8, sizeof(privcmd_memop_t)) #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */