]> xenbits.xensource.com Git - people/ssmith/nc2-2.6.27.bak/.git/commitdiff
Add a new ioctl to /proc/xen/privcmd which allows HVM operations to be
authorSteven Smith <ssmith@weybridge.uk.xensource.com>
Thu, 28 May 2009 10:54:20 +0000 (11:54 +0100)
committerSteven Smith <ssmith@weybridge.uk.xensource.com>
Thu, 28 May 2009 10:54:20 +0000 (11:54 +0100)
performed on restricted domains.

drivers/xen/privcmd/privcmd.c
include/asm-x86/mach-xen/asm/hypercall_32.h
include/asm-x86/mach-xen/asm/hypercall_64.h
include/xen/public/privcmd.h

index dc32ae8bf056d49b6f323d692b3386121d049b6d..e78beacb5d3a7065734b2eae173b77534bbb601b 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/tlb.h>
 #include <asm/hypervisor.h>
 #include <xen/interface/xen.h>
+#include <xen/interface/hvm/hvm_op.h>
 #include <xen/public/privcmd.h>
 #include <xen/xen_proc.h>
 #include <xen/features.h>
@@ -327,6 +328,64 @@ static long privcmd_ioctl(struct file *file,
         }
         break;
 
+        case IOCTL_PRIVCMD_HVMOP: {
+                privcmd_hvmop_t pht;
+
+                if (copy_from_user(&pht, udata, sizeof(pht)))
+                        return -EFAULT;
+
+                if (fdata->restrict_domid != UNRESTRICTED_DOMID) {
+                        switch (pht.cmd) {
+                        case HVMOP_set_param:
+                        case HVMOP_get_param:
+                                if (pht.u.param.domid !=
+                                    fdata->restrict_domid)
+                                        return -EACCES;
+                                break;
+                        case HVMOP_set_pci_intx_level:
+                                if (pht.u.set_pci_intx_level.domid !=
+                                    fdata->restrict_domid)
+                                        return -EACCES;
+                                break;
+                        case HVMOP_set_isa_irq_level:
+                                if (pht.u.set_isa_irq_level.domid !=
+                                    fdata->restrict_domid)
+                                        return -EACCES;
+                                break;
+                        case HVMOP_set_pci_link_route:
+                                if (pht.u.set_isa_irq_level.domid !=
+                                    fdata->restrict_domid)
+                                        return -EACCES;
+                                break;
+                       case HVMOP_modified_memory:
+                                if (pht.u.modified_memory.domid !=
+                                    fdata->restrict_domid)
+                                        return -EACCES;
+                                break;
+                       case HVMOP_set_mem_type:
+                                if (pht.u.set_mem_type.domid !=
+                                    fdata->restrict_domid)
+                                        return -EACCES;
+                                break;
+                       case HVMOP_track_dirty_vram:
+                                if (pht.u.track_dirty_vram.domid !=
+                                    fdata->restrict_domid)
+                                        return -EACCES;
+                                break;
+                        default:
+                                return -EACCES;
+                        }
+                }
+
+                ret = HYPERVISOR_hvm_op(pht.cmd, &pht.u);
+                if (ret >= 0) {
+                        if (copy_to_user(udata, &pht, sizeof(pht)))
+                                ret = -EFAULT;
+                }
+                break;
+        }
+        break;
+
        default:
                ret = -EINVAL;
                break;
index cff47009481f33e2cd2fb182e31714048fca1642..ce801fa9d23abfc0e3b490d0e2b3e110988e9613 100644 (file)
@@ -68,3 +68,9 @@ HYPERVISOR_domctl(
         return _hypercall1(int, domctl, xd);
 }
 
+static inline unsigned long __must_check
+HYPERVISOR_hvm_op(
+       int op, void *arg)
+{
+       return _hypercall2(unsigned long, hvm_op, op, arg);
+}
index 221a0318aaaffd340ed262cca40f9d024719d615..f55c9101ae392b538901085d1b58aedd2ef88479 100644 (file)
@@ -60,3 +60,9 @@ HYPERVISOR_domctl(
        return _hypercall1(int, domctl, xd);
 }
 
+static inline unsigned long __must_check
+HYPERVISOR_hvm_op(
+       int op, void *arg)
+{
+       return _hypercall2(unsigned long, hvm_op, op, arg);
+}
index 30773e196fd95394f67ab2620b3eda1ab25fcf09..20d2e27afb3ced6f75e5d1340195977a41d6e229 100644 (file)
 #define __LINUX_PUBLIC_PRIVCMD_H__
 
 #include <linux/types.h>
+#ifdef __KERNEL__
+#include <xen/hvm.h>
+#else
+#include <xen/hvm/hvm_op.h>
+#endif
 
 #ifndef __user
 #define __user
@@ -68,6 +73,19 @@ typedef struct privcmd_restrict_domid {
        domid_t domid;
 } privcmd_restrict_domid_t;
 
+typedef struct privcmd_hvmop {
+        unsigned cmd;
+        union {
+                xen_hvm_param_t param;
+                xen_hvm_set_pci_intx_level_t set_pci_intx_level;
+                xen_hvm_set_isa_irq_level_t set_isa_irq_level;
+                xen_hvm_set_pci_link_route_t set_pci_link_route;
+                xen_hvm_modified_memory_t modified_memory;
+                xen_hvm_set_mem_type_t set_mem_type;
+                xen_hvm_track_dirty_vram_t track_dirty_vram;
+        } u;
+} privcmd_hvmop_t;
+
 /*
  * @cmd: IOCTL_PRIVCMD_HYPERCALL
  * @arg: &privcmd_hypercall_t
@@ -83,5 +101,7 @@ typedef struct privcmd_restrict_domid {
        _IOC(_IOC_NONE, 'P', 4, sizeof(privcmd_restrict_domid_t))
 #define IOCTL_PRIVCMD_DOMCTL                           \
        _IOC(_IOC_NONE, 'P', 5, sizeof(xen_domctl_t))
+#define IOCTL_PRIVCMD_HVMOP                                    \
+       _IOC(_IOC_NONE, 'P', 6, sizeof(privcmd_hvmop_t))
 
 #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */