617 lines
23 KiB
Diff
617 lines
23 KiB
Diff
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.
|
|
|
|
Index: 2007-01-08/xen/Makefile
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/Makefile 2007-01-08 15:17:24.000000000 +0100
|
|
+++ 2007-01-08/xen/Makefile 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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)
|
|
Index: 2007-01-08/xen/Rules.mk
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/Rules.mk 2007-01-08 15:17:24.000000000 +0100
|
|
+++ 2007-01-08/xen/Rules.mk 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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)
|
|
|
|
Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:17:24.000000000 +0100
|
|
+++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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
|
|
Index: 2007-01-08/xen/arch/x86/x86_64/compat/traps.c
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:17:24.000000000 +0100
|
|
+++ 2007-01-08/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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)
|
|
{
|
|
Index: 2007-01-08/xen/common/Makefile
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/common/Makefile 2007-01-08 15:17:24.000000000 +0100
|
|
+++ 2007-01-08/xen/common/Makefile 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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
|
|
Index: 2007-01-08/xen/common/compat/Makefile
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -0,0 +1,4 @@
|
|
+obj-y += kernel.o
|
|
+
|
|
+# extra dependencies
|
|
+kernel.o: ../kernel.c
|
|
Index: 2007-01-08/xen/common/compat/kernel.c
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-01-08/xen/common/compat/kernel.c 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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:
|
|
+ */
|
|
Index: 2007-01-08/xen/common/kernel.c
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/common/kernel.c 2007-01-08 15:17:24.000000000 +0100
|
|
+++ 2007-01-08/xen/common/kernel.c 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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_H
|
|
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_GUE
|
|
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;
|
|
Index: 2007-01-08/xen/include/Makefile
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-01-08/xen/include/Makefile 2007-01-08 15:18:26.000000000 +0100
|
|
@@ -0,0 +1,60 @@
|
|
+ifneq ($(CONFIG_COMPAT),)
|
|
+
|
|
+compat-subarch-$(CONFIG_X86) := x86_32
|
|
+compat-arch-$(CONFIG_X86) := x86
|
|
+
|
|
+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-subarch-y).h
|
|
+headers-y += compat/arch-$(compat-arch-y)/xen.h
|
|
+headers-y += compat/arch-$(compat-arch-y)/xen-$(compat-subarch-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
|
|
Index: 2007-01-08/xen/include/asm-x86/compat.h
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-01-08/xen/include/asm-x86/compat.h 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -0,0 +1,6 @@
|
|
+/******************************************************************************
|
|
+ * compat.h
|
|
+ */
|
|
+
|
|
+typedef uint32_t compat_ptr_t;
|
|
+typedef unsigned long full_ptr_t;
|
|
Index: 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h
|
|
===================================================================
|
|
--- 2007-01-08.orig/xen/include/asm-x86/x86_64/uaccess.h 2007-01-08 15:17:24.000000000 +0100
|
|
+++ 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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; \
|
|
Index: 2007-01-08/xen/include/xen/compat.h
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 15:17:29.000000000 +0100
|
|
@@ -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__ */
|