From: Steven Smith Date: Tue, 30 Jun 2009 11:55:48 +0000 (+0100) Subject: Add a new ioctl to /proc/xen/privcmd which allows domctls to be performed X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=4c268ef503bc8592d4bdc74cef843d90c1a147e0;p=people%2Fssmith%2Fnc2-2.6.27.git Add a new ioctl to /proc/xen/privcmd which allows domctls to be performed without using the generic hypercall interface, so that they are available on restricted fds. This requires an unfortunate amount of fiddling with headers so that XEN_GUEST_HANDLE_64 and uint64_aligned_t are available in kernel space. --- diff --git a/drivers/xen/privcmd/privcmd.c b/drivers/xen/privcmd/privcmd.c index 0ddb8d9f..dc32ae8b 100644 --- a/drivers/xen/privcmd/privcmd.c +++ b/drivers/xen/privcmd/privcmd.c @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include #include #include @@ -311,6 +311,22 @@ static long privcmd_ioctl(struct file *file, } break; + case IOCTL_PRIVCMD_DOMCTL: { + xen_domctl_t xd; + + if (copy_from_user(&xd, udata, sizeof(xd))) + return -EFAULT; + if (fdata->restrict_domid != UNRESTRICTED_DOMID && + xd.domain != fdata->restrict_domid) + return -EACCES; + ret = HYPERVISOR_domctl(&xd); + if (ret >= 0) { + if (copy_to_user(udata, &xd, sizeof(xd))) + ret = -EFAULT; + } + } + break; + default: ret = -EINVAL; break; diff --git a/include/asm-x86/mach-xen/asm/hypercall_32.h b/include/asm-x86/mach-xen/asm/hypercall_32.h index 3987b2ed..cff47009 100644 --- a/include/asm-x86/mach-xen/asm/hypercall_32.h +++ b/include/asm-x86/mach-xen/asm/hypercall_32.h @@ -60,3 +60,11 @@ HYPERVISOR_update_va_mapping_otherdomain( return _hypercall5(int, update_va_mapping_otherdomain, va, new_val.pte_low, pte_hi, flags, domid); } + +static inline int __must_check +HYPERVISOR_domctl( + xen_domctl_t *xd) +{ + return _hypercall1(int, domctl, xd); +} + diff --git a/include/asm-x86/mach-xen/asm/hypercall_64.h b/include/asm-x86/mach-xen/asm/hypercall_64.h index 97d94457..221a0318 100644 --- a/include/asm-x86/mach-xen/asm/hypercall_64.h +++ b/include/asm-x86/mach-xen/asm/hypercall_64.h @@ -52,3 +52,11 @@ HYPERVISOR_set_segment_base( { return _hypercall2(int, set_segment_base, reg, value); } + +static inline int __must_check +HYPERVISOR_domctl( + xen_domctl_t *xd) +{ + return _hypercall1(int, domctl, xd); +} + diff --git a/include/asm-x86/mach-xen/asm/hypervisor.h b/include/asm-x86/mach-xen/asm/hypervisor.h index aa0ea4db..9241bddb 100644 --- a/include/asm-x86/mach-xen/asm/hypervisor.h +++ b/include/asm-x86/mach-xen/asm/hypervisor.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/include/xen/interface/arch-x86/xen-x86_32.h b/include/xen/interface/arch-x86/xen-x86_32.h index 7cb6a017..64627ec5 100644 --- a/include/xen/interface/arch-x86/xen-x86_32.h +++ b/include/xen/interface/arch-x86/xen-x86_32.h @@ -100,10 +100,8 @@ #define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) #endif -/* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ -#if defined(__XEN__) || defined(__XEN_TOOLS__) #undef ___DEFINE_XEN_GUEST_HANDLE -#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ typedef struct { type *p; } \ __guest_handle_ ## name; \ typedef struct { union { type *p; uint64_aligned_t q; }; } \ @@ -116,7 +114,6 @@ #define uint64_aligned_t uint64_t __attribute__((aligned(8))) #define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name #define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name) -#endif #ifndef __ASSEMBLY__ diff --git a/include/xen/interface/arch-x86/xen-x86_64.h b/include/xen/interface/arch-x86/xen-x86_64.h index 1e54cf92..12e09935 100644 --- a/include/xen/interface/arch-x86/xen-x86_64.h +++ b/include/xen/interface/arch-x86/xen-x86_64.h @@ -97,6 +97,10 @@ #define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) #endif +#define uint64_aligned_t uint64_t +#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name) + + /* * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) * @which == SEGBASE_* ; @base == 64-bit base address diff --git a/include/xen/interface/domctl.h b/include/xen/interface/domctl.h index b7075ac4..67195c44 100644 --- a/include/xen/interface/domctl.h +++ b/include/xen/interface/domctl.h @@ -28,10 +28,6 @@ #ifndef __XEN_PUBLIC_DOMCTL_H__ #define __XEN_PUBLIC_DOMCTL_H__ -#if !defined(__XEN__) && !defined(__XEN_TOOLS__) -#error "domctl operations are intended for use by node control tools only" -#endif - #include "xen.h" #define XEN_DOMCTL_INTERFACE_VERSION 0x00000005 diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h index 6d232708..2d0498af 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h @@ -649,16 +649,6 @@ __DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t); #endif /* !__ASSEMBLY__ */ -/* Default definitions for macros used by domctl/sysctl. */ -#if defined(__XEN__) || defined(__XEN_TOOLS__) -#ifndef uint64_aligned_t -#define uint64_aligned_t uint64_t -#endif -#ifndef XEN_GUEST_HANDLE_64 -#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name) -#endif -#endif - #endif /* __XEN_PUBLIC_XEN_H__ */ /* diff --git a/include/xen/public/privcmd.h b/include/xen/public/privcmd.h index 1d196569..30773e19 100644 --- a/include/xen/public/privcmd.h +++ b/include/xen/public/privcmd.h @@ -81,5 +81,7 @@ typedef struct privcmd_restrict_domid { _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t)) #define IOCTL_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)) #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */