aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Ackaouy <ack@xensource.com>2007-01-05 17:34:28 +0000
committerEmmanuel Ackaouy <ack@xensource.com>2007-01-05 17:34:28 +0000
commit6224725e9357f6056cff046ba5da4c52f0bace8c (patch)
tree9ad38da55854dcad3fa52415aaebdb711c59aa85
parentc1990f10a76daa10ea01dd11e9ca6fc92cf55716 (diff)
downloadxen-6224725e9357f6056cff046ba5da4c52f0bace8c.tar.gz
xen-6224725e9357f6056cff046ba5da4c52f0bace8c.tar.bz2
xen-6224725e9357f6056cff046ba5da4c52f0bace8c.zip
Add logic to generate headers reflecting the compatibility mode layout
of hypercall arguments. Provide infrastructure for accessing handles passed from compatibility mode guests. Vector those hypercalls not needing any translation to their native implementations. Signed-off-by: Jan Beulich <jbeulich@novell.com>
-rw-r--r--xen/Makefile2
-rw-r--r--xen/Rules.mk1
-rw-r--r--xen/arch/x86/x86_64/compat/entry.S39
-rw-r--r--xen/arch/x86/x86_64/compat/traps.c19
-rw-r--r--xen/common/Makefile2
-rw-r--r--xen/common/compat/Makefile4
-rw-r--r--xen/common/compat/kernel.c59
-rw-r--r--xen/common/kernel.c19
-rw-r--r--xen/include/Makefile57
-rw-r--r--xen/include/asm-x86/compat.h6
-rw-r--r--xen/include/asm-x86/x86_64/uaccess.h13
-rw-r--r--xen/include/xen/compat.h167
12 files changed, 341 insertions, 47 deletions
diff --git a/xen/Makefile b/xen/Makefile
index dcd1b0934e..b391513ccc 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -48,6 +48,7 @@ _debug:
.PHONY: _clean
_clean: delete-unfresh-files
$(MAKE) -C tools clean
+ $(MAKE) -f $(BASEDIR)/Rules.mk -C include clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean
@@ -69,6 +70,7 @@ $(TARGET): delete-unfresh-files
$(MAKE) -f $(BASEDIR)/Rules.mk include/xen/compile.h
$(MAKE) -f $(BASEDIR)/Rules.mk include/xen/acm_policy.h
[ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm
+ $(MAKE) -f $(BASEDIR)/Rules.mk -C include
$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) asm-offsets.s
$(MAKE) -f $(BASEDIR)/Rules.mk include/asm-$(TARGET_ARCH)/asm-offsets.h
$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) $(TARGET)
diff --git a/xen/Rules.mk b/xen/Rules.mk
index 08c26aca44..28ee66b64d 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -34,6 +34,7 @@ TARGET := $(BASEDIR)/xen
HDRS := $(wildcard $(BASEDIR)/include/xen/*.h)
HDRS += $(wildcard $(BASEDIR)/include/public/*.h)
+HDRS += $(wildcard $(BASEDIR)/include/compat/*.h)
HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/*.h)
HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/$(TARGET_SUBARCH)/*.h)
diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
index 98c184a051..0b79fd708f 100644
--- a/xen/arch/x86/x86_64/compat/entry.S
+++ b/xen/arch/x86/x86_64/compat/entry.S
@@ -281,28 +281,19 @@ CFIX14:
#define compat_set_trap_table domain_crash_synchronous
#define compat_mmu_update domain_crash_synchronous
#define compat_set_gdt domain_crash_synchronous
-#define compat_stack_switch domain_crash_synchronous
-#define compat_fpu_taskswitch domain_crash_synchronous
-#define compat_arch_sched_op_compat domain_crash_synchronous
#define compat_platform_op domain_crash_synchronous
-#define compat_set_debugreg domain_crash_synchronous
-#define compat_get_debugreg domain_crash_synchronous
#define compat_update_descriptor domain_crash_synchronous
#define compat_memory_op domain_crash_synchronous
#define compat_multicall domain_crash_synchronous
#define compat_update_va_mapping domain_crash_synchronous
#define compat_set_timer_op domain_crash_synchronous
#define compat_event_channel_op_compat domain_crash_synchronous
-#define compat_xen_version domain_crash_synchronous
-#define compat_console_io domain_crash_synchronous
#define compat_physdev_op_compat domain_crash_synchronous
#define compat_grant_table_op domain_crash_synchronous
-#define compat_vm_assist domain_crash_synchronous
#define compat_update_va_mapping_otherdomain domain_crash_synchronous
#define compat_vcpu_op domain_crash_synchronous
#define compat_mmuext_op domain_crash_synchronous
#define compat_acm_op domain_crash_synchronous
-#define compat_nmi_op domain_crash_synchronous
#define compat_arch_sched_op domain_crash_synchronous
#define compat_xenoprof_op domain_crash_synchronous
#define compat_event_channel_op domain_crash_synchronous
@@ -314,29 +305,29 @@ ENTRY(compat_hypercall_table)
.quad compat_set_trap_table /* 0 */
.quad compat_mmu_update
.quad compat_set_gdt
- .quad compat_stack_switch
+ .quad do_stack_switch
.quad compat_set_callbacks
- .quad compat_fpu_taskswitch /* 5 */
- .quad compat_arch_sched_op_compat
+ .quad do_fpu_taskswitch /* 5 */
+ .quad do_sched_op_compat
.quad compat_platform_op
- .quad compat_set_debugreg
- .quad compat_get_debugreg
+ .quad do_set_debugreg
+ .quad do_get_debugreg
.quad compat_update_descriptor /* 10 */
- .quad do_ni_hypercall
+ .quad compat_ni_hypercall
.quad compat_memory_op
.quad compat_multicall
.quad compat_update_va_mapping
.quad compat_set_timer_op /* 15 */
.quad compat_event_channel_op_compat
.quad compat_xen_version
- .quad compat_console_io
+ .quad do_console_io
.quad compat_physdev_op_compat
.quad compat_grant_table_op /* 20 */
.quad compat_vm_assist
.quad compat_update_va_mapping_otherdomain
.quad compat_iret
.quad compat_vcpu_op
- .quad do_ni_hypercall /* 25 */
+ .quad compat_ni_hypercall /* 25 */
.quad compat_mmuext_op
.quad compat_acm_op
.quad compat_nmi_op
@@ -345,11 +336,11 @@ ENTRY(compat_hypercall_table)
.quad compat_xenoprof_op
.quad compat_event_channel_op
.quad compat_physdev_op
- .quad do_ni_hypercall
+ .quad compat_ni_hypercall
.quad compat_sysctl /* 35 */
.quad compat_domctl
.rept NR_hypercalls-((.-compat_hypercall_table)/8)
- .quad do_ni_hypercall
+ .quad compat_ni_hypercall
.endr
ENTRY(compat_hypercall_args_table)
@@ -359,12 +350,12 @@ ENTRY(compat_hypercall_args_table)
.byte 2 /* compat_stack_switch */
.byte 4 /* compat_set_callbacks */
.byte 1 /* compat_fpu_taskswitch */ /* 5 */
- .byte 2 /* compat_arch_sched_op_compat */
+ .byte 2 /* compat_sched_op_compat */
.byte 1 /* compat_platform_op */
.byte 2 /* compat_set_debugreg */
.byte 1 /* compat_get_debugreg */
.byte 4 /* compat_update_descriptor */ /* 10 */
- .byte 0 /* do_ni_hypercall */
+ .byte 0 /* compat_ni_hypercall */
.byte 2 /* compat_memory_op */
.byte 2 /* compat_multicall */
.byte 4 /* compat_update_va_mapping */
@@ -378,7 +369,7 @@ ENTRY(compat_hypercall_args_table)
.byte 5 /* compat_update_va_mapping_otherdomain */
.byte 0 /* compat_iret */
.byte 3 /* compat_vcpu_op */
- .byte 0 /* do_ni_hypercall */ /* 25 */
+ .byte 0 /* compat_ni_hypercall */ /* 25 */
.byte 4 /* compat_mmuext_op */
.byte 1 /* compat_acm_op */
.byte 2 /* compat_nmi_op */
@@ -387,9 +378,9 @@ ENTRY(compat_hypercall_args_table)
.byte 2 /* compat_xenoprof_op */
.byte 2 /* compat_event_channel_op */
.byte 2 /* compat_physdev_op */
- .byte 0 /* do_ni_hypercall */
+ .byte 0 /* compat_ni_hypercall */
.byte 1 /* compat_sysctl */ /* 35 */
.byte 1 /* compat_domctl */
.rept NR_hypercalls-(.-compat_hypercall_args_table)
- .byte 0 /* do_ni_hypercall */
+ .byte 0 /* compat_ni_hypercall */
.endr
diff --git a/xen/arch/x86/x86_64/compat/traps.c b/xen/arch/x86/x86_64/compat/traps.c
index ca0d8b46b5..a368748b1a 100644
--- a/xen/arch/x86/x86_64/compat/traps.c
+++ b/xen/arch/x86/x86_64/compat/traps.c
@@ -1,25 +1,6 @@
#ifdef CONFIG_COMPAT
-#if 0 /* XXX */
#include <compat/callback.h>
-#else
-struct compat_xen_callback {
- unsigned int cs;
- unsigned int eip;
-};
-typedef struct compat_xen_callback xen_callback_compat_t;
-
-struct compat_callback_register {
- uint16_t type;
- uint16_t flags;
- xen_callback_compat_t address;
-};
-
-struct compat_callback_unregister {
- uint16_t type;
- uint16_t _unused;
-};
-#endif
void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines)
{
diff --git a/xen/common/Makefile b/xen/common/Makefile
index 017348e065..680fd60b8c 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -35,5 +35,7 @@ obj-$(xenoprof) += xenoprof.o
obj-$(CONFIG_XENCOMM) += xencomm.o
+subdir-$(CONFIG_COMPAT) += compat
+
# Object file contains changeset and compiler information.
version.o: $(BASEDIR)/include/xen/compile.h
diff --git a/xen/common/compat/Makefile b/xen/common/compat/Makefile
new file mode 100644
index 0000000000..39e1c8ee3d
--- /dev/null
+++ b/xen/common/compat/Makefile
@@ -0,0 +1,4 @@
+obj-y += kernel.o
+
+# extra dependencies
+kernel.o: ../kernel.c
diff --git a/xen/common/compat/kernel.c b/xen/common/compat/kernel.c
new file mode 100644
index 0000000000..0618dbe8ad
--- /dev/null
+++ b/xen/common/compat/kernel.c
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * kernel.c
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/version.h>
+#include <xen/sched.h>
+#include <xen/shadow.h>
+#include <xen/nmi.h>
+#include <xen/guest_access.h>
+#include <asm/current.h>
+#include <compat/xen.h>
+#include <compat/nmi.h>
+#include <compat/version.h>
+
+#define xen_extraversion compat_extraversion
+#define xen_extraversion_t compat_extraversion_t
+
+#define xen_compile_info compat_compile_info
+#define xen_compile_info_t compat_compile_info_t
+
+CHECK_TYPE(capabilities_info);
+
+#define xen_platform_parameters compat_platform_parameters
+#define xen_platform_parameters_t compat_platform_parameters_t
+#undef HYPERVISOR_VIRT_START
+#define HYPERVISOR_VIRT_START HYPERVISOR_COMPAT_VIRT_START
+
+#define xen_changeset_info compat_changeset_info
+#define xen_changeset_info_t compat_changeset_info_t
+
+#define xen_feature_info compat_feature_info
+#define xen_feature_info_t compat_feature_info_t
+
+CHECK_TYPE(domain_handle);
+
+#define xennmi_callback compat_nmi_callback
+#define xennmi_callback_t compat_nmi_callback_t
+
+#define DO(fn) int compat_##fn
+#define COMPAT
+
+#include "../kernel.c"
+
+int compat_disabled = 0;
+boolean_param("no-pv-compat", compat_disabled);
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 9dc321325e..bf46640526 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -11,11 +11,14 @@
#include <xen/version.h>
#include <xen/sched.h>
#include <xen/shadow.h>
+#include <xen/nmi.h>
#include <xen/guest_access.h>
#include <asm/current.h>
#include <public/nmi.h>
#include <public/version.h>
+#ifndef COMPAT
+
int tainted;
void cmdline_parse(char *cmdline)
@@ -116,11 +119,15 @@ void add_taint(unsigned flag)
tainted |= flag;
}
+# define DO(fn) long do_##fn
+
+#endif
+
/*
* Simple hypercalls.
*/
-long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg)
+DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg)
{
switch ( cmd )
{
@@ -230,6 +237,8 @@ long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg)
return -ENOSYS;
}
+#ifndef COMPAT
+
long register_guest_nmi_callback(unsigned long address)
{
struct vcpu *v = current;
@@ -260,7 +269,9 @@ long unregister_guest_nmi_callback(void)
return 0;
}
-long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
+#endif
+
+DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
{
struct xennmi_callback cb;
long rc = 0;
@@ -284,12 +295,12 @@ long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
return rc;
}
-long do_vm_assist(unsigned int cmd, unsigned int type)
+DO(vm_assist)(unsigned int cmd, unsigned int type)
{
return vm_assist(current->domain, cmd, type);
}
-long do_ni_hypercall(void)
+DO(ni_hypercall)(void)
{
/* No-op hypercall. */
return -ENOSYS;
diff --git a/xen/include/Makefile b/xen/include/Makefile
new file mode 100644
index 0000000000..1cc0d79baf
--- /dev/null
+++ b/xen/include/Makefile
@@ -0,0 +1,57 @@
+ifneq ($(CONFIG_COMPAT),)
+
+compat-arch-$(CONFIG_X86) := x86_32
+
+headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g')
+headers-y := $(filter-out %/dom0_ops.h,$(headers-y))
+headers-y += compat/arch-$(compat-arch-y).h
+
+cppflags-y := -include public/xen-compat.h
+cppflags-$(CONFIG_X86) += -m32
+
+# 8-byte types are 4-byte aligned on x86_32 ...
+prefix-$(CONFIG_X86) := \#pragma pack(push, 4)
+suffix-$(CONFIG_X86) := \#pragma pack(pop)
+
+endif
+
+.PHONY: all
+all: $(headers-y)
+
+compat/%.h: compat/%.i Makefile
+ id=_$$(echo $@ | sed 'y,abcdefghijklmnopqrstuvwxyz-/.,ABCDEFGHIJKLMNOPQRSTUVWXYZ___,'); \
+ echo "#ifndef $$id" >$@.new; \
+ echo "#define $$id" >>$@.new; \
+ echo "#include <xen/compat.h>" >>$@.new; \
+ $(if $(filter-out compat/arch-%.h,$@),echo "#include <$(patsubst compat/%,public/%,$@)>" >>$@.new;) \
+ $(if $(prefix-y),echo "$(prefix-y)" >>$@.new;) \
+ grep -v '^# [[:digit:]]' $< | \
+ sed -e 's,__InClUdE__,#include,' \
+ -e 's,"xen-compat.h",<public/xen-compat.h>,' \
+ -e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \
+ -e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \
+ -e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \
+ -e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \
+ -e 's,\(^\|[^[:alnum:]_]\)XEN_\?,\1COMPAT_,' \
+ -e 's,\(^\|[^[:alnum:]_]\)Xen_\?,\1Compat_,' \
+ -e 's,\(^\|[^[:alnum:]]\)long\([^[:alnum:]]\|$$\),\1int\2,g' | \
+ uniq >>$@.new; \
+ $(if $(suffix-y),echo "$(suffix-y)" >>$@.new;) \
+ echo "#endif /* $$id */" >>$@.new
+ mv -f $@.new $@
+
+compat/%.i: compat/%.c Makefile
+ $(CPP) $(CFLAGS) $(cppflags-y) -o $@ $<
+
+compat/%.c: public/%.h Makefile
+ mkdir -p $(@D)
+ grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \
+ sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \
+ -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \
+ -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \
+ -e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \
+ >$@.new
+ mv -f $@.new $@
+
+clean::
+ rm -rf compat
diff --git a/xen/include/asm-x86/compat.h b/xen/include/asm-x86/compat.h
new file mode 100644
index 0000000000..37a0cffdc2
--- /dev/null
+++ b/xen/include/asm-x86/compat.h
@@ -0,0 +1,6 @@
+/******************************************************************************
+ * compat.h
+ */
+
+typedef uint32_t compat_ptr_t;
+typedef unsigned long full_ptr_t;
diff --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h
index 4d5f65c890..c51e1a8739 100644
--- a/xen/include/asm-x86/x86_64/uaccess.h
+++ b/xen/include/asm-x86/x86_64/uaccess.h
@@ -15,6 +15,19 @@
#define array_access_ok(addr, count, size) (__addr_ok(addr))
+#ifdef CONFIG_COMPAT
+
+#define __compat_addr_ok(addr) \
+ ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START)
+
+#define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size))
+
+#define compat_array_access_ok(addr,count,size) \
+ (likely((count) < (~0U / (size))) && \
+ compat_access_ok(addr, (count) * (size)))
+
+#endif
+
#define __put_user_size(x,ptr,size,retval,errret) \
do { \
retval = 0; \
diff --git a/xen/include/xen/compat.h b/xen/include/xen/compat.h
new file mode 100644
index 0000000000..375ba39352
--- /dev/null
+++ b/xen/include/xen/compat.h
@@ -0,0 +1,167 @@
+/******************************************************************************
+ * compat.h
+ */
+
+#ifndef __XEN_COMPAT_H__
+#define __XEN_COMPAT_H__
+
+#include <xen/config.h>
+
+#ifdef CONFIG_COMPAT
+
+#include <xen/types.h>
+#include <asm/compat.h>
+#include <compat/xlat.h>
+
+#define __DEFINE_COMPAT_HANDLE(name, type) \
+ typedef struct { \
+ compat_ptr_t c; \
+ type *_[0] __attribute__((__packed__)); \
+ } __compat_handle_ ## name
+
+#define DEFINE_COMPAT_HANDLE(name) __DEFINE_COMPAT_HANDLE(name, name)
+#define COMPAT_HANDLE(name) __compat_handle_ ## name
+
+/* Is the compat handle a NULL reference? */
+#define compat_handle_is_null(hnd) ((hnd).c == 0)
+
+/* Offset the given compat handle into the array it refers to. */
+#define compat_handle_add_offset(hnd, nr) \
+ ((hnd).c += (nr) * sizeof(**(hnd)._))
+
+/* Cast a compat handle to the specified type of handle. */
+#define compat_handle_cast(chnd, type) ({ \
+ type *_x = (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c; \
+ (XEN_GUEST_HANDLE(type)) { _x }; \
+})
+
+#define guest_from_compat_handle(ghnd, chnd) \
+ set_xen_guest_handle(ghnd, \
+ (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c)
+
+/*
+ * Copy an array of objects to guest context via a compat handle,
+ * specifying an offset into the guest array.
+ */
+#define copy_to_compat_offset(hnd, off, ptr, nr) ({ \
+ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
+ const typeof(*(ptr)) *const _y = (ptr); \
+ copy_to_user(_x + (off), _y, sizeof(*_x) * (nr)); \
+})
+
+/*
+ * Copy an array of objects from guest context via a compat handle,
+ * specifying an offset into the guest array.
+ */
+#define copy_from_compat_offset(ptr, hnd, off, nr) ({ \
+ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
+ const typeof(ptr) _y = (ptr); \
+ copy_from_user(_y, _x + (off), sizeof(*_x) * (nr)); \
+})
+
+#define copy_to_compat(hnd, ptr, nr) \
+ copy_to_compat_offset(hnd, 0, ptr, nr)
+
+#define copy_from_compat(ptr, hnd, nr) \
+ copy_from_compat_offset(ptr, hnd, 0, nr)
+
+/* Copy sub-field of a structure to guest context via a compat handle. */
+#define copy_field_to_compat(hnd, ptr, field) ({ \
+ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
+ const typeof((ptr)->field) *const _y = &(ptr)->field; \
+ copy_to_user(_x, _y, sizeof(*_x)); \
+})
+
+/* Copy sub-field of a structure from guest context via a compat handle. */
+#define copy_field_from_compat(ptr, hnd, field) ({ \
+ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
+ typeof((ptr)->field) *const _y = &(ptr)->field; \
+ copy_from_user(_y, _x, sizeof(*_x)); \
+})
+
+/*
+ * Pre-validate a guest handle.
+ * Allows use of faster __copy_* functions.
+ */
+#define compat_handle_okay(hnd, nr) \
+ compat_array_access_ok((void *)(full_ptr_t)(hnd).c, (nr), sizeof(**(hnd)._))
+
+#define __copy_to_compat_offset(hnd, off, ptr, nr) ({ \
+ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
+ const typeof(*(ptr)) *const _y = (ptr); \
+ __copy_to_user(_x + (off), _y, sizeof(*_x) * (nr)); \
+})
+
+#define __copy_from_compat_offset(ptr, hnd, off, nr) ({ \
+ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
+ const typeof(ptr) _y = (ptr); \
+ __copy_from_user(_y, _x + (off), sizeof(*_x) * (nr)); \
+})
+
+#define __copy_to_compat(hnd, ptr, nr) \
+ __copy_to_compat_offset(hnd, 0, ptr, nr)
+
+#define __copy_from_compat(ptr, hnd, nr) \
+ __copy_from_compat_offset(ptr, hnd, 0, nr)
+
+#define __copy_field_to_compat(hnd, ptr, field) ({ \
+ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
+ const typeof((ptr)->field) *const _y = &(ptr)->field; \
+ __copy_to_user(_x, _y, sizeof(*_x)); \
+})
+
+#define __copy_field_from_compat(ptr, hnd, field) ({ \
+ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
+ typeof((ptr)->field) *const _y = &(ptr)->field; \
+ __copy_from_user(_y, _x, sizeof(*_x)); \
+})
+
+
+#define CHECK_TYPE(name) \
+ typedef int __checkT ## name[1 - ((xen_ ## name ## _t *)0 != \
+ (compat_ ## name ## _t *)0) * 2]
+#define CHECK_TYPE_(k, n) \
+ typedef int __checkT ## k ## _ ## n[1 - ((k xen_ ## n *)0 != \
+ (k compat_ ## n *)0) * 2]
+
+#define CHECK_SIZE(name) \
+ typedef int __checkS ## name[1 - (sizeof(xen_ ## name ## _t) != \
+ sizeof(compat_ ## name ## _t)) * 2]
+#define CHECK_SIZE_(k, n) \
+ typedef int __checkS ## k ## _ ## n[1 - (sizeof(k xen_ ## n) != \
+ sizeof(k compat_ ## n)) * 2]
+
+#define CHECK_FIELD(t, f) \
+ typedef int __checkF ## t ## __ ## f[1 - (&((xen_ ## t ## _t *)0)->f != \
+ &((compat_ ## t ## _t *)0)->f) * 2]
+#define CHECK_FIELD_(k, n, f) \
+ typedef int __checkF ## k ## _ ## n ## __ ## f[1 - (&((k xen_ ## n *)0)->f != \
+ &((k compat_ ## n *)0)->f) * 2]
+
+#define CHECK_SUBFIELD_1(t, f1, f2) \
+ typedef int __checkF1 ## t ## __ ## f1 ## __ ## f2 \
+ [1 - (&((xen_ ## t ## _t *)0)->f1.f2 != \
+ &((compat_ ## t ## _t *)0)->f1.f2) * 2]
+#define CHECK_SUBFIELD_1_(k, n, f1, f2) \
+ typedef int __checkF1 ## k ## _ ## n ## __ ## f1 ## __ ## f2 \
+ [1 - (&((k xen_ ## n *)0)->f1.f2 != \
+ &((k compat_ ## n *)0)->f1.f2) * 2]
+
+#define CHECK_SUBFIELD_2(t, f1, f2, f3) \
+ typedef int __checkF2 ## t ## __ ## f1 ## __ ## f2 ## __ ## f3 \
+ [1 - (&((xen_ ## t ## _t *)0)->f1.f2.f3 != \
+ &((compat_ ## t ## _t *)0)->f1.f2.f3) * 2]
+#define CHECK_SUBFIELD_2_(k, n, f1, f2, f3) \
+ typedef int __checkF2 ## k ## _ ## n ## __ ## f1 ## __ ## f2 ## __ ## f3 \
+ [1 - (&((k xen_ ## n *)0)->f1.f2.f3 != \
+ &((k compat_ ## n *)0)->f1.f2.f3) * 2]
+
+extern int compat_disabled;
+
+/* In-place translation functons: */
+struct start_info;
+void xlat_start_info(struct start_info *, enum XLAT_start_info_console);
+
+#endif
+
+#endif /* __XEN_COMPAT_H__ */