+obj-y += hypercall_page.o
obj-y += xen.o
obj-bin-$(CONFIG_PVH_GUEST) += pvh-boot.init.o
--- /dev/null
+#include <asm/page.h>
+#include <asm/asm_defns.h>
+#include <public/xen.h>
+
+ .section ".text.page_aligned", "ax", @progbits
+ .p2align PAGE_SHIFT
+
+GLOBAL(hypercall_page)
+ /* Poisoned with `ret` for safety before hypercalls are set up. */
+ .fill PAGE_SIZE, 1, 0xc3
+ .type hypercall_page, STT_OBJECT
+ .size hypercall_page, PAGE_SIZE
+
+/*
+ * Identify a specific hypercall in the hypercall page
+ * @param name Hypercall name.
+ */
+#define DECLARE_HYPERCALL(name) \
+ .globl HYPERCALL_ ## name; \
+ .set HYPERCALL_ ## name, hypercall_page + __HYPERVISOR_ ## name * 32; \
+ .type HYPERCALL_ ## name, STT_FUNC; \
+ .size HYPERCALL_ ## name, 32
+
+DECLARE_HYPERCALL(set_trap_table)
+DECLARE_HYPERCALL(mmu_update)
+DECLARE_HYPERCALL(set_gdt)
+DECLARE_HYPERCALL(stack_switch)
+DECLARE_HYPERCALL(set_callbacks)
+DECLARE_HYPERCALL(fpu_taskswitch)
+DECLARE_HYPERCALL(sched_op_compat)
+DECLARE_HYPERCALL(platform_op)
+DECLARE_HYPERCALL(set_debugreg)
+DECLARE_HYPERCALL(get_debugreg)
+DECLARE_HYPERCALL(update_descriptor)
+DECLARE_HYPERCALL(memory_op)
+DECLARE_HYPERCALL(multicall)
+DECLARE_HYPERCALL(update_va_mapping)
+DECLARE_HYPERCALL(set_timer_op)
+DECLARE_HYPERCALL(event_channel_op_compat)
+DECLARE_HYPERCALL(xen_version)
+DECLARE_HYPERCALL(console_io)
+DECLARE_HYPERCALL(physdev_op_compat)
+DECLARE_HYPERCALL(grant_table_op)
+DECLARE_HYPERCALL(vm_assist)
+DECLARE_HYPERCALL(update_va_mapping_otherdomain)
+DECLARE_HYPERCALL(iret)
+DECLARE_HYPERCALL(vcpu_op)
+DECLARE_HYPERCALL(set_segment_base)
+DECLARE_HYPERCALL(mmuext_op)
+DECLARE_HYPERCALL(xsm_op)
+DECLARE_HYPERCALL(nmi_op)
+DECLARE_HYPERCALL(sched_op)
+DECLARE_HYPERCALL(callback_op)
+DECLARE_HYPERCALL(xenoprof_op)
+DECLARE_HYPERCALL(event_channel_op)
+DECLARE_HYPERCALL(physdev_op)
+DECLARE_HYPERCALL(hvm_op)
+DECLARE_HYPERCALL(sysctl)
+DECLARE_HYPERCALL(domctl)
+DECLARE_HYPERCALL(kexec_op)
+DECLARE_HYPERCALL(tmem_op)
+DECLARE_HYPERCALL(xc_reserved_op)
+DECLARE_HYPERCALL(xenpmu_op)
+
+DECLARE_HYPERCALL(arch_0)
+DECLARE_HYPERCALL(arch_1)
+DECLARE_HYPERCALL(arch_2)
+DECLARE_HYPERCALL(arch_3)
+DECLARE_HYPERCALL(arch_4)
+DECLARE_HYPERCALL(arch_5)
+DECLARE_HYPERCALL(arch_6)
+DECLARE_HYPERCALL(arch_7)
+
+/*
+ * Local variables:
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
#include <xen/types.h>
#include <asm/guest.h>
+#include <asm/msr.h>
#include <asm/processor.h>
#include <public/arch-x86/cpuid.h>
bool __read_mostly xen_guest;
static __read_mostly uint32_t xen_cpuid_base;
+extern char hypercall_page[];
static void __init find_xen_leaves(void)
{
if ( !xen_cpuid_base )
return;
+ /* Fill the hypercall page. */
+ wrmsrl(cpuid_ebx(xen_cpuid_base + 2), __pa(hypercall_page));
+
xen_guest = true;
}
DECL_SECTION(.text) {
_stext = .; /* Text and read-only data */
*(.text)
+ *(.text.page_aligned)
*(.text.cold)
*(.text.unlikely)
*(.fixup)
#ifndef __X86_GUEST_H__
#define __X86_GUEST_H__
+#include <asm/guest/hypercall.h>
#include <asm/guest/pvh-boot.h>
#include <asm/guest/xen.h>
--- /dev/null
+/******************************************************************************
+ * asm-x86/guest/hypercall.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2017 Citrix Systems Ltd.
+ */
+
+#ifndef __X86_XEN_HYPERCALL_H__
+#define __X86_XEN_HYPERCALL_H__
+
+#ifdef CONFIG_XEN_GUEST
+
+/*
+ * Hypercall primatives for 64bit
+ *
+ * Inputs: %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6)
+ */
+
+#define _hypercall64_1(type, hcall, a1) \
+ ({ \
+ long res, tmp__; \
+ asm volatile ( \
+ "call hypercall_page + %c[offset]" \
+ : "=a" (res), "=D" (tmp__) \
+ : [offset] "i" (hcall * 32), \
+ "1" ((long)(a1)) \
+ : "memory" ); \
+ (type)res; \
+ })
+
+#define _hypercall64_2(type, hcall, a1, a2) \
+ ({ \
+ long res, tmp__; \
+ asm volatile ( \
+ "call hypercall_page + %c[offset]" \
+ : "=a" (res), "=D" (tmp__), "=S" (tmp__) \
+ : [offset] "i" (hcall * 32), \
+ "1" ((long)(a1)), "2" ((long)(a2)) \
+ : "memory" ); \
+ (type)res; \
+ })
+
+#define _hypercall64_3(type, hcall, a1, a2, a3) \
+ ({ \
+ long res, tmp__; \
+ asm volatile ( \
+ "call hypercall_page + %c[offset]" \
+ : "=a" (res), "=D" (tmp__), "=S" (tmp__), "=d" (tmp__) \
+ : [offset] "i" (hcall * 32), \
+ "1" ((long)(a1)), "2" ((long)(a2)), "3" ((long)(a3)) \
+ : "memory" ); \
+ (type)res; \
+ })
+
+#define _hypercall64_4(type, hcall, a1, a2, a3, a4) \
+ ({ \
+ long res, tmp__; \
+ register long _a4 asm ("r10") = ((long)(a4)); \
+ asm volatile ( \
+ "call hypercall_page + %c[offset]" \
+ : "=a" (res), "=D" (tmp__), "=S" (tmp__), "=d" (tmp__), \
+ "=&r" (tmp__) \
+ : [offset] "i" (hcall * 32), \
+ "1" ((long)(a1)), "2" ((long)(a2)), "3" ((long)(a3)), \
+ "4" (_a4) \
+ : "memory" ); \
+ (type)res; \
+ })
+
+#endif /* CONFIG_XEN_GUEST */
+#endif /* __X86_XEN_HYPERCALL_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */