1af7b0868SMatt Evans #include "kvm/kvm.h" 2af7b0868SMatt Evans #include "kvm/boot-protocol.h" 3af7b0868SMatt Evans #include "kvm/cpufeature.h" 4af7b0868SMatt Evans #include "kvm/interrupt.h" 5af7b0868SMatt Evans #include "kvm/mptable.h" 6af7b0868SMatt Evans #include "kvm/util.h" 70b69bdefSMatt Evans #include "kvm/8250-serial.h" 80b69bdefSMatt Evans #include "kvm/virtio-console.h" 9af7b0868SMatt Evans 10af7b0868SMatt Evans #include <asm/bootparam.h> 11af7b0868SMatt Evans #include <linux/kvm.h> 1273f00e73SAndre Przywara #include <linux/kernel.h> 13af7b0868SMatt Evans 14af7b0868SMatt Evans #include <sys/types.h> 15af7b0868SMatt Evans #include <sys/ioctl.h> 16af7b0868SMatt Evans #include <sys/mman.h> 17af7b0868SMatt Evans #include <sys/stat.h> 18af7b0868SMatt Evans #include <stdbool.h> 19af7b0868SMatt Evans #include <stdlib.h> 20af7b0868SMatt Evans #include <string.h> 21af7b0868SMatt Evans #include <unistd.h> 22af7b0868SMatt Evans #include <stdio.h> 23af7b0868SMatt Evans #include <fcntl.h> 24af7b0868SMatt Evans 25af7b0868SMatt Evans struct kvm_ext kvm_req_ext[] = { 26af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_COALESCED_MMIO) }, 27af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_SET_TSS_ADDR) }, 28af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_PIT2) }, 29af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_USER_MEMORY) }, 30af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_IRQ_ROUTING) }, 31af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_IRQCHIP) }, 32af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_HLT) }, 33af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_IRQ_INJECT_STATUS) }, 34af7b0868SMatt Evans { DEFINE_KVM_EXT(KVM_CAP_EXT_CPUID) }, 35af7b0868SMatt Evans { 0, 0 } 36af7b0868SMatt Evans }; 37af7b0868SMatt Evans 38abe3f28aSAlexandru Elisei void kvm__arch_validate_cfg(struct kvm *kvm) 39abe3f28aSAlexandru Elisei { 40abe3f28aSAlexandru Elisei } 41abe3f28aSAlexandru Elisei 42af7b0868SMatt Evans bool kvm__arch_cpu_supports_vm(void) 43af7b0868SMatt Evans { 44af7b0868SMatt Evans struct cpuid_regs regs; 45af7b0868SMatt Evans u32 eax_base; 46af7b0868SMatt Evans int feature; 47af7b0868SMatt Evans 48af7b0868SMatt Evans regs = (struct cpuid_regs) { 49af7b0868SMatt Evans .eax = 0x00, 50af7b0868SMatt Evans }; 51af7b0868SMatt Evans host_cpuid(®s); 52af7b0868SMatt Evans 53af7b0868SMatt Evans switch (regs.ebx) { 54af7b0868SMatt Evans case CPUID_VENDOR_INTEL_1: 55af7b0868SMatt Evans eax_base = 0x00; 56af7b0868SMatt Evans feature = KVM__X86_FEATURE_VMX; 57af7b0868SMatt Evans break; 58af7b0868SMatt Evans 59af7b0868SMatt Evans case CPUID_VENDOR_AMD_1: 60af7b0868SMatt Evans eax_base = 0x80000000; 61af7b0868SMatt Evans feature = KVM__X86_FEATURE_SVM; 62af7b0868SMatt Evans break; 63af7b0868SMatt Evans 64af7b0868SMatt Evans default: 65af7b0868SMatt Evans return false; 66af7b0868SMatt Evans } 67af7b0868SMatt Evans 68af7b0868SMatt Evans regs = (struct cpuid_regs) { 69af7b0868SMatt Evans .eax = eax_base, 70af7b0868SMatt Evans }; 71af7b0868SMatt Evans host_cpuid(®s); 72af7b0868SMatt Evans 73af7b0868SMatt Evans if (regs.eax < eax_base + 0x01) 74af7b0868SMatt Evans return false; 75af7b0868SMatt Evans 76af7b0868SMatt Evans regs = (struct cpuid_regs) { 77af7b0868SMatt Evans .eax = eax_base + 0x01 78af7b0868SMatt Evans }; 79af7b0868SMatt Evans host_cpuid(®s); 80af7b0868SMatt Evans 81af7b0868SMatt Evans return regs.ecx & (1 << feature); 82af7b0868SMatt Evans } 83af7b0868SMatt Evans 84af7b0868SMatt Evans /* 85af7b0868SMatt Evans * Allocating RAM size bigger than 4GB requires us to leave a gap 86af7b0868SMatt Evans * in the RAM which is used for PCI MMIO, hotplug, and unconfigured 87af7b0868SMatt Evans * devices (see documentation of e820_setup_gap() for details). 88af7b0868SMatt Evans * 89af7b0868SMatt Evans * If we're required to initialize RAM bigger than 4GB, we will create 90af7b0868SMatt Evans * a gap between 0xe0000000 and 0x100000000 in the guest virtual mem space. 91af7b0868SMatt Evans */ 92af7b0868SMatt Evans 93af7b0868SMatt Evans void kvm__init_ram(struct kvm *kvm) 94af7b0868SMatt Evans { 95af7b0868SMatt Evans u64 phys_start, phys_size; 96af7b0868SMatt Evans void *host_mem; 97af7b0868SMatt Evans 98af7b0868SMatt Evans if (kvm->ram_size < KVM_32BIT_GAP_START) { 99af7b0868SMatt Evans /* Use a single block of RAM for 32bit RAM */ 100af7b0868SMatt Evans 101af7b0868SMatt Evans phys_start = 0; 102af7b0868SMatt Evans phys_size = kvm->ram_size; 103af7b0868SMatt Evans host_mem = kvm->ram_start; 104af7b0868SMatt Evans 1058f46c736SJean-Philippe Brucker kvm__register_ram(kvm, phys_start, phys_size, host_mem); 106af7b0868SMatt Evans } else { 107af7b0868SMatt Evans /* First RAM range from zero to the PCI gap: */ 108af7b0868SMatt Evans 109af7b0868SMatt Evans phys_start = 0; 110af7b0868SMatt Evans phys_size = KVM_32BIT_GAP_START; 111af7b0868SMatt Evans host_mem = kvm->ram_start; 112af7b0868SMatt Evans 1138f46c736SJean-Philippe Brucker kvm__register_ram(kvm, phys_start, phys_size, host_mem); 114af7b0868SMatt Evans 115af7b0868SMatt Evans /* Second RAM range from 4GB to the end of RAM: */ 116af7b0868SMatt Evans 117f7abc4cdSHongyong Zang phys_start = KVM_32BIT_MAX_MEM_SIZE; 118f7abc4cdSHongyong Zang phys_size = kvm->ram_size - phys_start; 119af7b0868SMatt Evans host_mem = kvm->ram_start + phys_start; 120af7b0868SMatt Evans 1218f46c736SJean-Philippe Brucker kvm__register_ram(kvm, phys_start, phys_size, host_mem); 122af7b0868SMatt Evans } 123af7b0868SMatt Evans } 124af7b0868SMatt Evans 1258e704a7aSMatt Evans /* Arch-specific commandline setup */ 1268e704a7aSMatt Evans void kvm__arch_set_cmdline(char *cmdline, bool video) 1278e704a7aSMatt Evans { 1288e704a7aSMatt Evans strcpy(cmdline, "noapic noacpi pci=conf1 reboot=k panic=1 i8042.direct=1 " 1298e704a7aSMatt Evans "i8042.dumbkbd=1 i8042.nopnp=1"); 1303a60be06SSasha Levin if (video) 1315857730cSWill Deacon strcat(cmdline, " video=vesafb"); 1323a60be06SSasha Levin else 1335857730cSWill Deacon strcat(cmdline, " earlyprintk=serial i8042.noaux=1"); 1348e704a7aSMatt Evans } 1358e704a7aSMatt Evans 136af7b0868SMatt Evans /* Architecture-specific KVM init */ 137*5e9c654eSJulien Grall void kvm__arch_init(struct kvm *kvm) 138af7b0868SMatt Evans { 139*5e9c654eSJulien Grall const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path; 140af7b0868SMatt Evans struct kvm_pit_config pit_config = { .flags = 0, }; 141*5e9c654eSJulien Grall u64 ram_size = kvm->cfg.ram_size; 142af7b0868SMatt Evans int ret; 143af7b0868SMatt Evans 144af7b0868SMatt Evans ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000); 145af7b0868SMatt Evans if (ret < 0) 146af7b0868SMatt Evans die_perror("KVM_SET_TSS_ADDR ioctl"); 147af7b0868SMatt Evans 148af7b0868SMatt Evans ret = ioctl(kvm->vm_fd, KVM_CREATE_PIT2, &pit_config); 149af7b0868SMatt Evans if (ret < 0) 150af7b0868SMatt Evans die_perror("KVM_CREATE_PIT2 ioctl"); 151af7b0868SMatt Evans 152f7abc4cdSHongyong Zang if (ram_size < KVM_32BIT_GAP_START) { 153af7b0868SMatt Evans kvm->ram_size = ram_size; 1543ebd8e0bSMichael Ellerman kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size); 155af7b0868SMatt Evans } else { 1563ebd8e0bSMichael Ellerman kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size + KVM_32BIT_GAP_SIZE); 157f7abc4cdSHongyong Zang kvm->ram_size = ram_size + KVM_32BIT_GAP_SIZE; 1583a60be06SSasha Levin if (kvm->ram_start != MAP_FAILED) 159af7b0868SMatt Evans /* 160af7b0868SMatt Evans * We mprotect the gap (see kvm__init_ram() for details) PROT_NONE so that 161af7b0868SMatt Evans * if we accidently write to it, we will know. 162af7b0868SMatt Evans */ 163af7b0868SMatt Evans mprotect(kvm->ram_start + KVM_32BIT_GAP_START, KVM_32BIT_GAP_SIZE, PROT_NONE); 164af7b0868SMatt Evans } 165af7b0868SMatt Evans if (kvm->ram_start == MAP_FAILED) 166af7b0868SMatt Evans die("out of memory"); 167af7b0868SMatt Evans 168af7b0868SMatt Evans madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE); 169af7b0868SMatt Evans 170af7b0868SMatt Evans ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP); 171af7b0868SMatt Evans if (ret < 0) 172af7b0868SMatt Evans die_perror("KVM_CREATE_IRQCHIP ioctl"); 173af7b0868SMatt Evans } 174af7b0868SMatt Evans 175e56e2de7SLai Jiangshan void kvm__arch_delete_ram(struct kvm *kvm) 176e56e2de7SLai Jiangshan { 177e56e2de7SLai Jiangshan munmap(kvm->ram_start, kvm->ram_size); 178e56e2de7SLai Jiangshan } 179e56e2de7SLai Jiangshan 180af7b0868SMatt Evans void kvm__irq_line(struct kvm *kvm, int irq, int level) 181af7b0868SMatt Evans { 182af7b0868SMatt Evans struct kvm_irq_level irq_level; 183af7b0868SMatt Evans 184af7b0868SMatt Evans irq_level = (struct kvm_irq_level) { 185af7b0868SMatt Evans { 186af7b0868SMatt Evans .irq = irq, 187af7b0868SMatt Evans }, 188af7b0868SMatt Evans .level = level, 189af7b0868SMatt Evans }; 190af7b0868SMatt Evans 191af7b0868SMatt Evans if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0) 192af7b0868SMatt Evans die_perror("KVM_IRQ_LINE failed"); 193af7b0868SMatt Evans } 194af7b0868SMatt Evans 195af7b0868SMatt Evans void kvm__irq_trigger(struct kvm *kvm, int irq) 196af7b0868SMatt Evans { 197af7b0868SMatt Evans kvm__irq_line(kvm, irq, 1); 198af7b0868SMatt Evans kvm__irq_line(kvm, irq, 0); 199af7b0868SMatt Evans } 200af7b0868SMatt Evans 201af7b0868SMatt Evans #define BOOT_LOADER_SELECTOR 0x1000 202af7b0868SMatt Evans #define BOOT_LOADER_IP 0x0000 203af7b0868SMatt Evans #define BOOT_LOADER_SP 0x8000 204af7b0868SMatt Evans #define BOOT_CMDLINE_OFFSET 0x20000 205af7b0868SMatt Evans 206af7b0868SMatt Evans #define BOOT_PROTOCOL_REQUIRED 0x206 207af7b0868SMatt Evans #define LOAD_HIGH 0x01 208af7b0868SMatt Evans 209f412251fSWill Deacon static inline void *guest_real_to_host(struct kvm *kvm, u16 selector, u16 offset) 210f412251fSWill Deacon { 2111cbb2c50SAndre Przywara unsigned long flat = ((u32)selector << 4) + offset; 212f412251fSWill Deacon 213f412251fSWill Deacon return guest_flat_to_host(kvm, flat); 214f412251fSWill Deacon } 215f412251fSWill Deacon 216004f7684SAndre Przywara static bool load_flat_binary(struct kvm *kvm, int fd_kernel) 217af7b0868SMatt Evans { 218af7b0868SMatt Evans void *p; 219af7b0868SMatt Evans 220604dbd63SMatt Evans if (lseek(fd_kernel, 0, SEEK_SET) < 0) 221af7b0868SMatt Evans die_perror("lseek"); 222af7b0868SMatt Evans 223af7b0868SMatt Evans p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP); 224af7b0868SMatt Evans 22573f00e73SAndre Przywara if (read_file(fd_kernel, p, kvm->cfg.ram_size) < 0) 22673f00e73SAndre Przywara die_perror("read"); 227af7b0868SMatt Evans 22842ac24f9SSasha Levin kvm->arch.boot_selector = BOOT_LOADER_SELECTOR; 22942ac24f9SSasha Levin kvm->arch.boot_ip = BOOT_LOADER_IP; 23042ac24f9SSasha Levin kvm->arch.boot_sp = BOOT_LOADER_SP; 231af7b0868SMatt Evans 232af7b0868SMatt Evans return true; 233af7b0868SMatt Evans } 234af7b0868SMatt Evans 235af7b0868SMatt Evans static const char *BZIMAGE_MAGIC = "HdrS"; 236af7b0868SMatt Evans 237004f7684SAndre Przywara static bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd, 238ff7ba6faSWill Deacon const char *kernel_cmdline) 239af7b0868SMatt Evans { 240af7b0868SMatt Evans struct boot_params *kern_boot; 241af7b0868SMatt Evans struct boot_params boot; 242af7b0868SMatt Evans size_t cmdline_size; 24373f00e73SAndre Przywara ssize_t file_size; 244af7b0868SMatt Evans void *p; 245ff7ba6faSWill Deacon u16 vidmode; 246af7b0868SMatt Evans 247af7b0868SMatt Evans /* 248af7b0868SMatt Evans * See Documentation/x86/boot.txt for details no bzImage on-disk and 249af7b0868SMatt Evans * memory layout. 250af7b0868SMatt Evans */ 251af7b0868SMatt Evans 25273f00e73SAndre Przywara if (read_in_full(fd_kernel, &boot, sizeof(boot)) != sizeof(boot)) 253af7b0868SMatt Evans return false; 254af7b0868SMatt Evans 255af7b0868SMatt Evans if (memcmp(&boot.hdr.header, BZIMAGE_MAGIC, strlen(BZIMAGE_MAGIC))) 256af7b0868SMatt Evans return false; 257af7b0868SMatt Evans 258af7b0868SMatt Evans if (boot.hdr.version < BOOT_PROTOCOL_REQUIRED) 259af7b0868SMatt Evans die("Too old kernel"); 260af7b0868SMatt Evans 261af7b0868SMatt Evans if (lseek(fd_kernel, 0, SEEK_SET) < 0) 262af7b0868SMatt Evans die_perror("lseek"); 263af7b0868SMatt Evans 264af7b0868SMatt Evans if (!boot.hdr.setup_sects) 265af7b0868SMatt Evans boot.hdr.setup_sects = BZ_DEFAULT_SETUP_SECTS; 26673f00e73SAndre Przywara file_size = (boot.hdr.setup_sects + 1) << 9; 267af7b0868SMatt Evans p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP); 26873f00e73SAndre Przywara if (read_in_full(fd_kernel, p, file_size) != file_size) 26973f00e73SAndre Przywara die_perror("kernel setup read"); 270af7b0868SMatt Evans 27173f00e73SAndre Przywara /* read actual kernel image (vmlinux.bin) to BZ_KERNEL_START */ 272af7b0868SMatt Evans p = guest_flat_to_host(kvm, BZ_KERNEL_START); 27373f00e73SAndre Przywara file_size = read_file(fd_kernel, p, 27473f00e73SAndre Przywara kvm->cfg.ram_size - BZ_KERNEL_START); 27573f00e73SAndre Przywara if (file_size < 0) 27673f00e73SAndre Przywara die_perror("kernel read"); 277af7b0868SMatt Evans 278af7b0868SMatt Evans p = guest_flat_to_host(kvm, BOOT_CMDLINE_OFFSET); 279af7b0868SMatt Evans if (kernel_cmdline) { 280af7b0868SMatt Evans cmdline_size = strlen(kernel_cmdline) + 1; 281af7b0868SMatt Evans if (cmdline_size > boot.hdr.cmdline_size) 282af7b0868SMatt Evans cmdline_size = boot.hdr.cmdline_size; 283af7b0868SMatt Evans 284af7b0868SMatt Evans memset(p, 0, boot.hdr.cmdline_size); 285af7b0868SMatt Evans memcpy(p, kernel_cmdline, cmdline_size - 1); 286af7b0868SMatt Evans } 287af7b0868SMatt Evans 288ff7ba6faSWill Deacon /* vidmode should be either specified or set by default */ 2897bcceb95SPekka Enberg if (kvm->cfg.vnc || kvm->cfg.sdl || kvm->cfg.gtk) { 2906ad7171aSAsias He if (!kvm->cfg.arch.vidmode) 291ff7ba6faSWill Deacon vidmode = 0x312; 2926ad7171aSAsias He else 2936ad7171aSAsias He vidmode = kvm->cfg.arch.vidmode; 294ff7ba6faSWill Deacon } else { 295ff7ba6faSWill Deacon vidmode = 0; 296ff7ba6faSWill Deacon } 297ff7ba6faSWill Deacon 298af7b0868SMatt Evans kern_boot = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, 0x00); 299af7b0868SMatt Evans 300af7b0868SMatt Evans kern_boot->hdr.cmd_line_ptr = BOOT_CMDLINE_OFFSET; 301af7b0868SMatt Evans kern_boot->hdr.type_of_loader = 0xff; 302af7b0868SMatt Evans kern_boot->hdr.heap_end_ptr = 0xfe00; 303af7b0868SMatt Evans kern_boot->hdr.loadflags |= CAN_USE_HEAP; 304af7b0868SMatt Evans kern_boot->hdr.vid_mode = vidmode; 305af7b0868SMatt Evans 306af7b0868SMatt Evans /* 307af7b0868SMatt Evans * Read initrd image into guest memory 308af7b0868SMatt Evans */ 309af7b0868SMatt Evans if (fd_initrd >= 0) { 310af7b0868SMatt Evans struct stat initrd_stat; 311af7b0868SMatt Evans unsigned long addr; 312af7b0868SMatt Evans 313af7b0868SMatt Evans if (fstat(fd_initrd, &initrd_stat)) 314af7b0868SMatt Evans die_perror("fstat"); 315af7b0868SMatt Evans 316af7b0868SMatt Evans addr = boot.hdr.initrd_addr_max & ~0xfffff; 317af7b0868SMatt Evans for (;;) { 318af7b0868SMatt Evans if (addr < BZ_KERNEL_START) 319af7b0868SMatt Evans die("Not enough memory for initrd"); 320af7b0868SMatt Evans else if (addr < (kvm->ram_size - initrd_stat.st_size)) 321af7b0868SMatt Evans break; 322af7b0868SMatt Evans addr -= 0x100000; 323af7b0868SMatt Evans } 324af7b0868SMatt Evans 325af7b0868SMatt Evans p = guest_flat_to_host(kvm, addr); 32673f00e73SAndre Przywara if (read_in_full(fd_initrd, p, initrd_stat.st_size) < 0) 327af7b0868SMatt Evans die("Failed to read initrd"); 328af7b0868SMatt Evans 329af7b0868SMatt Evans kern_boot->hdr.ramdisk_image = addr; 330af7b0868SMatt Evans kern_boot->hdr.ramdisk_size = initrd_stat.st_size; 331af7b0868SMatt Evans } 332af7b0868SMatt Evans 33342ac24f9SSasha Levin kvm->arch.boot_selector = BOOT_LOADER_SELECTOR; 334af7b0868SMatt Evans /* 335af7b0868SMatt Evans * The real-mode setup code starts at offset 0x200 of a bzImage. See 336af7b0868SMatt Evans * Documentation/x86/boot.txt for details. 337af7b0868SMatt Evans */ 33842ac24f9SSasha Levin kvm->arch.boot_ip = BOOT_LOADER_IP + 0x200; 33942ac24f9SSasha Levin kvm->arch.boot_sp = BOOT_LOADER_SP; 340af7b0868SMatt Evans 341af7b0868SMatt Evans return true; 342af7b0868SMatt Evans } 343af7b0868SMatt Evans 344004f7684SAndre Przywara bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd, 345004f7684SAndre Przywara const char *kernel_cmdline) 346004f7684SAndre Przywara { 347004f7684SAndre Przywara if (load_bzimage(kvm, fd_kernel, fd_initrd, kernel_cmdline)) 348004f7684SAndre Przywara return true; 349004f7684SAndre Przywara pr_warning("Kernel image is not a bzImage."); 350004f7684SAndre Przywara pr_warning("Trying to load it as a flat binary (no cmdline support)"); 351004f7684SAndre Przywara 352004f7684SAndre Przywara if (fd_initrd != -1) 353004f7684SAndre Przywara pr_warning("Loading initrd with flat binary not supported."); 354004f7684SAndre Przywara 355004f7684SAndre Przywara return load_flat_binary(kvm, fd_kernel); 356004f7684SAndre Przywara } 357004f7684SAndre Przywara 358af7b0868SMatt Evans /** 359af7b0868SMatt Evans * kvm__arch_setup_firmware - inject BIOS into guest system memory 360af7b0868SMatt Evans * @kvm - guest system descriptor 361af7b0868SMatt Evans * 362af7b0868SMatt Evans * This function is a main routine where we poke guest memory 363af7b0868SMatt Evans * and install BIOS there. 364af7b0868SMatt Evans */ 365f7f9d02bSCyrill Gorcunov int kvm__arch_setup_firmware(struct kvm *kvm) 366af7b0868SMatt Evans { 367af7b0868SMatt Evans /* standart minimal configuration */ 368af7b0868SMatt Evans setup_bios(kvm); 369af7b0868SMatt Evans 370af7b0868SMatt Evans /* FIXME: SMP, ACPI and friends here */ 371af7b0868SMatt Evans 3723d34111eSSasha Levin return 0; 3731add9f73SSasha Levin } 3741add9f73SSasha Levin 3751add9f73SSasha Levin int kvm__arch_free_firmware(struct kvm *kvm) 3761add9f73SSasha Levin { 3773d34111eSSasha Levin return 0; 378af7b0868SMatt Evans } 3790b69bdefSMatt Evans 38012c406a8SJonathan Austin void kvm__arch_read_term(struct kvm *kvm) 3810b69bdefSMatt Evans { 382f6b8ccc1SThomas Gleixner serial8250__update_consoles(kvm); 3830b69bdefSMatt Evans virtio_console__inject_interrupt(kvm); 3840b69bdefSMatt Evans } 385