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 Hypercall Subsystem
83 * The hypercall subsystem provides an interface for cells to invoke Jailhouse
84 * services and interact via the communication region.
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;
101 /* included to expand COMM_REGION_GENERIC_HEADER */
102 #include <jailhouse/hypercall.h>
105 /** Communication region between hypervisor and a cell. */
106 struct jailhouse_comm_region {
107 COMM_REGION_GENERIC_HEADER;
109 /** I/O port address of the PM timer (x86-specific). */
110 __u16 pm_timer_address;
111 /** Number of CPUs available to the cell (x86-specific). */
116 * Invoke a hypervisor without additional arguments.
117 * @param num Hypercall number.
119 * @return Result of the hypercall, semantic depends on the invoked service.
121 static inline __u32 jailhouse_call(__u32 num)
125 asm volatile(JAILHOUSE_CALL_CODE
126 : JAILHOUSE_CALL_RESULT
127 : JAILHOUSE_USE_VMCALL, JAILHOUSE_CALL_NUM
133 * Invoke a hypervisor with one argument.
134 * @param num Hypercall number.
135 * @param arg1 First argument.
137 * @return Result of the hypercall, semantic depends on the invoked service.
139 static inline __u32 jailhouse_call_arg1(__u32 num, unsigned long arg1)
143 asm volatile(JAILHOUSE_CALL_CODE
144 : JAILHOUSE_CALL_RESULT
145 : JAILHOUSE_USE_VMCALL,
146 JAILHOUSE_CALL_NUM, JAILHOUSE_CALL_ARG1
152 * Invoke a hypervisor with two arguments.
153 * @param num Hypercall number.
154 * @param arg1 First argument.
155 * @param arg2 Second argument.
157 * @return Result of the hypercall, semantic depends on the invoked service.
159 static inline __u32 jailhouse_call_arg2(__u32 num, unsigned long arg1,
164 asm volatile(JAILHOUSE_CALL_CODE
165 : JAILHOUSE_CALL_RESULT
166 : JAILHOUSE_USE_VMCALL,
167 JAILHOUSE_CALL_NUM, JAILHOUSE_CALL_ARG1, JAILHOUSE_CALL_ARG2
173 * Send a message from the hypervisor to a cell via the communication region.
174 * @param comm_region Pointer to Communication Region.
175 * @param msg Message to be sent.
178 jailhouse_send_msg_to_cell(struct jailhouse_comm_region *comm_region,
181 comm_region->reply_from_cell = JAILHOUSE_MSG_NONE;
182 /* ensure reply was cleared before sending new message */
183 asm volatile("mfence" : : : "memory");
184 comm_region->msg_to_cell = msg;
188 * Send a reply message from a cell to the hypervisor via the communication
190 * @param comm_region Pointer to Communication Region.
191 * @param reply Reply to be sent.
194 jailhouse_send_reply_from_cell(struct jailhouse_comm_region *comm_region,
197 comm_region->msg_to_cell = JAILHOUSE_MSG_NONE;
198 /* ensure message was cleared before sending reply */
199 asm volatile("mfence" : : : "memory");
200 comm_region->reply_from_cell = reply;
205 #endif /* !__ASSEMBLY__ */