will be defined in the following.
-Intel x86-64 (IA-32e) ABI
+Intel x86 (IA-32/32e) ABI
- - - - - - - - - - - - -
Instruction: vmcall
-Hypercall code: RAX
-1. argument: RDI
-2. argument: RSI
-Return code: RAX
+Hypercall code: EAX
+1. argument: RDI (IA-32e) / EDI (IA-32)
+2. argument: RSI (IA-32e) / ESI (IA-32)
+Return code: EAX
Hypercall "Disable" (code 0)
#include <jailhouse/header.h>
#include <jailhouse/hypercall.h>
+#ifdef CONFIG_X86_32
+#error 64-bit kernel required!
+#endif
+
/* For compatibility with older kernel versions */
#include <linux/version.h>
* the COPYING file in the top-level directory.
*/
-#ifndef __x86_64__
-#error 64-bit kernel required!
-#endif
-
#define JAILHOUSE_BASE 0xfffffffff0000000
#define JAILHOUSE_CALL_INS "vmcall"
return result;
}
-static inline __u32 jailhouse_call_arg1(__u32 num, __u32 arg1)
+static inline __u32 jailhouse_call_arg1(__u32 num, unsigned long arg1)
{
__u32 result;
return result;
}
-static inline __u32 jailhouse_call_arg2(__u32 num, __u32 arg1, __u32 arg2)
+static inline __u32 jailhouse_call_arg2(__u32 num, unsigned long arg1,
+ unsigned long arg2)
{
__u32 result;
static void vmx_handle_hypercall(struct registers *guest_regs,
struct per_cpu *cpu_data)
{
+ bool ia32e_mode = !!(vmcs_read64(GUEST_IA32_EFER) & EFER_LMA);
+ unsigned long arg_mask = ia32e_mode ? (u64)-1 : (u32)-1;
unsigned long code = guest_regs->rax;
vmx_skip_emulated_instruction(X86_INST_LEN_VMCALL);
- if ((!(vmcs_read64(GUEST_IA32_EFER) & EFER_LMA) &&
- vmcs_read64(GUEST_RFLAGS) & X86_RFLAGS_VM) ||
+ if ((!ia32e_mode && vmcs_read64(GUEST_RFLAGS) & X86_RFLAGS_VM) ||
(vmcs_read16(GUEST_CS_SELECTOR) & 3) != 0) {
guest_regs->rax = -EPERM;
return;
}
- guest_regs->rax = hypercall(cpu_data, code, guest_regs->rdi,
- guest_regs->rsi);
+ guest_regs->rax = hypercall(cpu_data, code, guest_regs->rdi & arg_mask,
+ guest_regs->rsi & arg_mask);
if (guest_regs->rax == -ENOSYS)
printk("CPU %d: Unknown vmcall %d, RIP: %p\n",
cpu_data->cpu_id, code,