]> xenbits.xen.org Git - xenclient/kernel.git/commitdiff
Add a new ioctl to /proc/xen/privcmd which allows you to do certain privcmd_schedop
authort_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:06:04 +0000 (12:06 +0000)
committert_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:06:04 +0000 (12:06 +0000)
XENMEM operations on restricted fds.

drivers/xen/privcmd/privcmd.c
include/xen/public/privcmd.h

index 8d3b81ee857b32c05f6a1f47168e5e5759d69b7a..f97c9bfa62befb82b6cdd7ac986b1e2a20dac618 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
 #include <asm/hypervisor.h>
+#include <xen/interface/memory.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/hvm/hvm_op.h>
 #include <xen/public/privcmd.h>
@@ -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;
 
index 5b048f7b034fb6b18468c2f45708db7d637692a3..0c569af7a2090705e02af6a550081a154739950e 100644 (file)
 
 #include <linux/types.h>
 #ifdef __KERNEL__
-#include <xen/hvm.h>
+#include <xen/interface/hvm/hvm_op.h>
+#include <xen/interface/memory.h>
 #else
 #include <xen/hvm/hvm_op.h>
+#include <xen/memory.h>
 #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__ */