1b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes/* 2b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * Check decoding of KVM_* commands of ioctl syscall using /dev/kvm API. 3b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * Based on kvmtest.c from https://lwn.net/Articles/658512/ 4b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * 5b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * kvmtest.c author: Josh Triplett <josh@joshtriplett.org> 6b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * Copyright (c) 2015 Intel Corporation 7b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * Copyright (c) 2017-2018 The strace developers. 8b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * 9b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * Permission is hereby granted, free of charge, to any person obtaining a copy 10b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * of this software and associated documentation files (the "Software"), to 11b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * deal in the Software without restriction, including without limitation the 12b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * sell copies of the Software, and to permit persons to whom the Software is 14b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * furnished to do so, subject to the following conditions: 15b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * 16b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * The above copyright notice and this permission notice shall be included in 17b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * all copies or substantial portions of the Software. 18b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * 19b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * IN THE SOFTWARE. 26b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes */ 27b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 28b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes#include "tests.h" 29b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 30b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes#if defined HAVE_LINUX_KVM_H \ 31b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes && defined HAVE_STRUCT_KVM_REGS \ 32b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes && defined HAVE_STRUCT_KVM_SREGS \ 33b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes && defined HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION \ 34b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes &&(defined __x86_64__ || defined __i386__) 35b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 36b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes# include <fcntl.h> 37b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes# include <stdint.h> 38b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes# include <stdio.h> 39b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes# include <stdlib.h> 40b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes# include <string.h> 41b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes# include <sys/ioctl.h> 42b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes# include <sys/mman.h> 43b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes# include <linux/kvm.h> 44b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 45b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesstatic int 46b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hugheskvm_ioctl(int fd, unsigned long cmd, const char *cmd_str, void *arg) 47b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes{ 48b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes int rc = ioctl(fd, cmd, arg); 49b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes if (rc < 0) 50b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes perror_msg_and_skip("%s", cmd_str); 51b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes return rc; 52b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes} 53b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 54b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes#define KVM_IOCTL(fd_, cmd_, arg_) \ 55b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes kvm_ioctl((fd_), (cmd_), #cmd_, (arg_)) 56b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 57b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesstatic const char dev[] = "/dev/kvm"; 58b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesstatic const char vm_dev[] = "anon_inode:kvm-vm"; 59b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesstatic const char vcpu_dev[] = "anon_inode:kvm-vcpu"; 60b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesstatic size_t page_size; 61b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 62b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesextern const char code[]; 63b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesextern const unsigned short code_size; 64b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 65b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes__asm__( 66b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ".type code, @object \n" 67b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes "code: \n" 68b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " mov $0xd80003f8, %edx \n" 69b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " mov $'\n', %al \n" 70b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " out %al, (%dx) \n" 71b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " hlt \n" 72b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ".size code, . - code \n" 73b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ".type code_size, @object \n" 74b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes "code_size: \n" 75b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " .short . - code \n" 76b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ".size code_size, . - code_size \n" 77b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ); 78b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 79b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 80b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesstatic void 81b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesrun_kvm(const int vcpu_fd, struct kvm_run *const run, const size_t mmap_size, 82b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes void *const mem) 83b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes{ 84b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes /* Initialize CS to point at 0, via a read-modify-write of sregs. */ 85b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes struct kvm_sregs sregs; 86b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes KVM_IOCTL(vcpu_fd, KVM_GET_SREGS, &sregs); 87b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_GET_SREGS, {cs={base=%#jx, limit=%u, selector=%u" 88b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ", type=%u, present=%u, dpl=%u, db=%u, s=%u, l=%u, g=%u, avl=%u}" 89b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ", ...}) = 0\n", vcpu_fd, vcpu_dev, (uintmax_t) sregs.cs.base, 90b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes sregs.cs.limit, sregs.cs.selector, sregs.cs.type, 91b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes sregs.cs.present, sregs.cs.dpl, sregs.cs.db, sregs.cs.s, 92b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes sregs.cs.l, sregs.cs.g, sregs.cs.avl); 93b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 94b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes sregs.cs.base = 0; 95b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes sregs.cs.selector = 0; 96b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes KVM_IOCTL(vcpu_fd, KVM_SET_SREGS, &sregs); 97b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_SET_SREGS, {cs={base=%#jx, limit=%u" 98b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ", selector=%u, type=%u, present=%u, dpl=%u, db=%u, s=%u" 99b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ", l=%u, g=%u, avl=%u}, ...}) = 0\n", 100b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes vcpu_fd, vcpu_dev, (uintmax_t) sregs.cs.base, 101b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes sregs.cs.limit, sregs.cs.selector, sregs.cs.type, 102b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes sregs.cs.present, sregs.cs.dpl, sregs.cs.db, sregs.cs.s, 103b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes sregs.cs.l, sregs.cs.g, sregs.cs.avl); 104b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 105b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes /* 106b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * Initialize registers: instruction pointer for our code, addends, 107b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * and initial flags required by x86 architecture. 108b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes */ 109b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes struct kvm_regs regs = { 110b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes .rip = page_size, 111b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes .rax = 2, 112b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes .rbx = 2, 113b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes .rflags = 0x2, 114b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes }; 115b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes KVM_IOCTL(vcpu_fd, KVM_SET_REGS, ®s); 116b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_SET_REGS, {rax=%#jx, ..." 117b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ", rsp=%#jx, rbp=%#jx, ..., rip=%#jx, rflags=%#jx}) = 0\n", 118b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes vcpu_fd, vcpu_dev, (uintmax_t) regs.rax, 119b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes (uintmax_t) regs.rsp, (uintmax_t) regs.rbp, 120b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes (uintmax_t) regs.rip, (uintmax_t) regs.rflags); 121b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 122b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes /* Copy the code */ 123b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes memcpy(mem, code, code_size); 124b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 125b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes const char *p = "\n"; 126b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 127b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes /* Repeatedly run code and handle VM exits. */ 128b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes for (;;) { 129b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes KVM_IOCTL(vcpu_fd, KVM_RUN, NULL); 130b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_RUN, 0) = 0\n", vcpu_fd, vcpu_dev); 131b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 132b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes switch (run->exit_reason) { 133b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes case KVM_EXIT_HLT: 134b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes if (p) 135b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes error_msg_and_fail("premature KVM_EXIT_HLT"); 136b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes return; 137b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes case KVM_EXIT_IO: 138b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes if (run->io.direction == KVM_EXIT_IO_OUT 139b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes && run->io.size == 1 140b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes && run->io.port == 0x03f8 141b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes && run->io.count == 1 142b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes && run->io.data_offset < mmap_size 143b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes && p && *p == ((char *) run)[run->io.data_offset]) 144b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes p = NULL; 145b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes else 146b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes error_msg_and_fail("unhandled KVM_EXIT_IO"); 147b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes break; 148b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes case KVM_EXIT_MMIO: 149b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes error_msg_and_fail("Got an unexpected MMIO exit:" 150b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " phys_addr %#llx," 151b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " data %02x %02x %02x %02x" 152b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " %02x %02x %02x %02x," 153b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes " len %u, is_write %hhu", 154b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes (unsigned long long) run->mmio.phys_addr, 155b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes run->mmio.data[0], run->mmio.data[1], 156b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes run->mmio.data[2], run->mmio.data[3], 157b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes run->mmio.data[4], run->mmio.data[5], 158b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes run->mmio.data[6], run->mmio.data[7], 159b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes run->mmio.len, run->mmio.is_write); 160b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 161b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes default: 162b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes error_msg_and_fail("exit_reason = %#x", 163b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes run->exit_reason); 164b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes } 165b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes } 166b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes} 167b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 168b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesint 169b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughesmain(void) 170b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes{ 171b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes skip_if_unavailable("/proc/self/fd/"); 172b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 173b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes int kvm = open(dev, O_RDWR); 174b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes if (kvm < 0) 175b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes perror_msg_and_skip("open: %s", dev); 176b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 177b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes /* Make sure we have the stable version of the API */ 178b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes int ret = KVM_IOCTL(kvm, KVM_GET_API_VERSION, 0); 179b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes if (ret != KVM_API_VERSION) 180b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes error_msg_and_skip("KVM_GET_API_VERSION returned %d" 181b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ", KVM_API_VERSION is %d", 182b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes kvm, KVM_API_VERSION); 183b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_GET_API_VERSION, 0) = %d\n", 184b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes kvm, dev, ret); 185b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 186b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes int vm_fd = KVM_IOCTL(kvm, KVM_CREATE_VM, 0); 187b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_CREATE_VM, 0) = %d<%s>\n", 188b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes kvm, dev, vm_fd, vm_dev); 189b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 190b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes /* Allocate one aligned page of guest memory to hold the code. */ 191b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes page_size = get_page_size(); 192b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes void *const mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, 193b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes MAP_SHARED | MAP_ANONYMOUS, -1, 0); 194b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes if (mem == MAP_FAILED) 195b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes perror_msg_and_fail("mmap page"); 196b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 197b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes /* Map it to the second page frame (to avoid the real-mode IDT at 0). */ 198b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes struct kvm_userspace_memory_region region = { 199b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes .slot = 0, 200b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes .guest_phys_addr = page_size, 201b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes .memory_size = page_size, 202b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes .userspace_addr = (uintptr_t) mem, 203b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes }; 204b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes KVM_IOCTL(vm_fd, KVM_SET_USER_MEMORY_REGION, ®ion); 205b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_SET_USER_MEMORY_REGION" 206b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ", {slot=0, flags=0, guest_phys_addr=%#lx, memory_size=%lu" 207b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ", userspace_addr=%p}) = 0\n", vm_fd, vm_dev, 208b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes (unsigned long) page_size, (unsigned long) page_size, mem); 209b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 210b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes int vcpu_fd = KVM_IOCTL(vm_fd, KVM_CREATE_VCPU, NULL); 211b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_CREATE_VCPU, 0) = %d<%s>\n", 212b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes vm_fd, vm_dev, vcpu_fd, vcpu_dev); 213b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 214b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes /* Map the shared kvm_run structure and following data. */ 215b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ret = KVM_IOCTL(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL); 216b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes struct kvm_run *run; 217b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes if (ret < (int) sizeof(*run)) 218b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes error_msg_and_fail("KVM_GET_VCPU_MMAP_SIZE returned %d < %d", 219b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes ret, (int) sizeof(*run)); 220b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes printf("ioctl(%d<%s>, KVM_GET_VCPU_MMAP_SIZE, 0) = %d\n", 221b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes kvm, dev, ret); 222b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 223b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes const size_t mmap_size = (ret + page_size - 1) & -page_size; 224b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, 225b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes MAP_SHARED, vcpu_fd, 0); 226b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes if (run == MAP_FAILED) 227b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes perror_msg_and_fail("mmap vcpu"); 228b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 229b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes run_kvm(vcpu_fd, run, mmap_size, mem); 230b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 231b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes puts("+++ exited with 0 +++"); 232b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes return 0; 233b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes} 234b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 235b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes#else /* !HAVE_LINUX_KVM_H */ 236b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 237b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott HughesSKIP_MAIN_UNDEFINED("HAVE_LINUX_KVM_H && HAVE_STRUCT_KVM_REGS && " 238b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes "HAVE_STRUCT_KVM_SREGS && " 239b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes "HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION && " 240b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes "(__x86_64__ || __i386__)") 241b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes 242b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes#endif 243