From: t_jeang Date: Tue, 6 Jan 2009 12:06:04 +0000 (+0000) Subject: Add a new ioctl to /proc/xen/privcmd which allows domctls to be performed X-Git-Tag: restricted-privcmd-dev X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=a825f957534c40fec0e11e949c3ab2d631bd6e4c;p=xenclient%2Fkernel.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 5f659567..c190f1da 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-i386/mach-xen/asm/hypercall.h b/include/asm-i386/mach-xen/asm/hypercall.h index db53073a..800fa7c1 100644 --- a/include/asm-i386/mach-xen/asm/hypercall.h +++ b/include/asm-i386/mach-xen/asm/hypercall.h @@ -404,6 +404,13 @@ HYPERVISOR_xenoprof_op( return _hypercall2(int, xenoprof_op, op, arg); } +static inline int __must_check +HYPERVISOR_domctl( + xen_domctl_t *xd) +{ + return _hypercall1(int, domctl, xd); +} + static inline int __must_check HYPERVISOR_kexec_op( unsigned long op, void *args) diff --git a/include/asm-i386/mach-xen/asm/hypervisor.h b/include/asm-i386/mach-xen/asm/hypervisor.h index 21a66248..202ad0a2 100644 --- a/include/asm-i386/mach-xen/asm/hypervisor.h +++ b/include/asm-i386/mach-xen/asm/hypervisor.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #if defined(__i386__) diff --git a/include/asm-x86_64/mach-xen/asm/hypercall.h b/include/asm-x86_64/mach-xen/asm/hypercall.h index 651b4496..26ffab35 100644 --- a/include/asm-x86_64/mach-xen/asm/hypercall.h +++ b/include/asm-x86_64/mach-xen/asm/hypercall.h @@ -405,6 +405,13 @@ HYPERVISOR_xenoprof_op( return _hypercall2(int, xenoprof_op, op, arg); } +static inline int __must_check +HYPERVISOR_domctl( + xen_domctl_t *xd) +{ + return _hypercall1(int, domctl, xd); +} + static inline int __must_check HYPERVISOR_kexec_op( unsigned long op, void *args) 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 6c800abd..676234ac 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 4b444b4c..3419fc43 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h @@ -616,16 +616,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__ */