2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) Siemens AG, 2013-2015
7 * Jan Kiszka <jan.kiszka@siemens.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
12 * Alternatively, you can use or redistribute this file under the following
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 * THE POSSIBILITY OF SUCH DAMAGE.
39 #define JAILHOUSE_BASE __MAKE_UL(0xfffffffff0000000)
42 * As this is never called on a CPU without VM extensions,
43 * we assume that where VMCALL isn't available, VMMCALL is.
45 #define JAILHOUSE_CALL_CODE \
46 "cmpb $0x01, %[use_vmcall]\n\t"\
53 #define JAILHOUSE_CALL_RESULT "=a" (result)
54 #define JAILHOUSE_USE_VMCALL [use_vmcall] "m" (jailhouse_use_vmcall)
55 #define JAILHOUSE_CALL_NUM "a" (num)
56 #define JAILHOUSE_CALL_ARG1 "D" (arg1)
57 #define JAILHOUSE_CALL_ARG2 "S" (arg2)
60 #define JAILHOUSE_CPU_STAT_VMEXITS_PIO JAILHOUSE_GENERIC_CPU_STATS
61 #define JAILHOUSE_CPU_STAT_VMEXITS_XAPIC JAILHOUSE_GENERIC_CPU_STATS + 1
62 #define JAILHOUSE_CPU_STAT_VMEXITS_CR JAILHOUSE_GENERIC_CPU_STATS + 2
63 #define JAILHOUSE_CPU_STAT_VMEXITS_MSR JAILHOUSE_GENERIC_CPU_STATS + 3
64 #define JAILHOUSE_CPU_STAT_VMEXITS_CPUID JAILHOUSE_GENERIC_CPU_STATS + 4
65 #define JAILHOUSE_CPU_STAT_VMEXITS_XSETBV JAILHOUSE_GENERIC_CPU_STATS + 5
66 #define JAILHOUSE_NUM_CPU_STATS JAILHOUSE_GENERIC_CPU_STATS + 6
69 #define JAILHOUSE_CPUID_SIGNATURE 0x40000000
70 #define JAILHOUSE_CPUID_FEATURES 0x40000001
74 #define __MAKE_UL(x) x
76 #else /* !__ASSEMBLY__ */
78 #define __MAKE_UL(x) x ## UL
81 * @defgroup Hypercalls
83 * The hypercall subsystem provides an interface for cells
84 * to call into Jailhouse.
90 * This variable selects the x86 hypercall instruction to be used by
91 * jailhouse_call(), jailhouse_call_arg1(), and jailhouse_call_arg2().
92 * A caller should define and initialize the variable before calling
93 * any of these functions.
95 * @li @c false Use AMD's VMMCALL.
96 * @li @c true Use Intel's VMCALL.
98 extern bool jailhouse_use_vmcall;
100 struct jailhouse_comm_region {
101 COMM_REGION_GENERIC_HEADER;
103 __u16 pm_timer_address;
107 static inline __u32 jailhouse_call(__u32 num)
111 asm volatile(JAILHOUSE_CALL_CODE
112 : JAILHOUSE_CALL_RESULT
113 : JAILHOUSE_USE_VMCALL, JAILHOUSE_CALL_NUM
118 static inline __u32 jailhouse_call_arg1(__u32 num, unsigned long arg1)
122 asm volatile(JAILHOUSE_CALL_CODE
123 : JAILHOUSE_CALL_RESULT
124 : JAILHOUSE_USE_VMCALL,
125 JAILHOUSE_CALL_NUM, JAILHOUSE_CALL_ARG1
130 static inline __u32 jailhouse_call_arg2(__u32 num, unsigned long arg1,
135 asm volatile(JAILHOUSE_CALL_CODE
136 : JAILHOUSE_CALL_RESULT
137 : JAILHOUSE_USE_VMCALL,
138 JAILHOUSE_CALL_NUM, JAILHOUSE_CALL_ARG1, JAILHOUSE_CALL_ARG2
144 jailhouse_send_msg_to_cell(struct jailhouse_comm_region *comm_region,
147 comm_region->reply_from_cell = JAILHOUSE_MSG_NONE;
148 /* ensure reply was cleared before sending new message */
149 asm volatile("mfence" : : : "memory");
150 comm_region->msg_to_cell = msg;
154 jailhouse_send_reply_from_cell(struct jailhouse_comm_region *comm_region,
157 comm_region->msg_to_cell = JAILHOUSE_MSG_NONE;
158 /* ensure message was cleared before sending reply */
159 asm volatile("mfence" : : : "memory");
160 comm_region->reply_from_cell = reply;
165 #endif /* !__ASSEMBLY__ */