x86.c (526947e496e4447d74b8d42415e2847481c5043d) | x86.c (b34f2fd17e4276ac0a75f8d72485a0236a740954) |
---|---|
1/* 2 * Copyright (c) 2003-2004 Fabrice Bellard 3 * Copyright (c) 2019 Red Hat, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this software and associated documentation files (the "Software"), to deal 7 * in the Software without restriction, including without limitation the rights 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --- 35 unchanged lines hidden (view full) --- 44 45#include "hw/i386/x86.h" 46#include "target/i386/cpu.h" 47#include "hw/i386/topology.h" 48#include "hw/i386/fw_cfg.h" 49#include "hw/intc/i8259.h" 50#include "hw/rtc/mc146818rtc.h" 51#include "target/i386/sev.h" | 1/* 2 * Copyright (c) 2003-2004 Fabrice Bellard 3 * Copyright (c) 2019 Red Hat, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this software and associated documentation files (the "Software"), to deal 7 * in the Software without restriction, including without limitation the rights 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --- 35 unchanged lines hidden (view full) --- 44 45#include "hw/i386/x86.h" 46#include "target/i386/cpu.h" 47#include "hw/i386/topology.h" 48#include "hw/i386/fw_cfg.h" 49#include "hw/intc/i8259.h" 50#include "hw/rtc/mc146818rtc.h" 51#include "target/i386/sev.h" |
52#include "hw/i386/microvm.h" | |
53 54#include "hw/acpi/cpu_hotplug.h" 55#include "hw/irq.h" 56#include "hw/nmi.h" 57#include "hw/loader.h" 58#include "multiboot.h" 59#include "elf.h" 60#include "standard-headers/asm-x86/bootparam.h" 61#include CONFIG_DEVICES 62#include "kvm/kvm_i386.h" 63 | 52 53#include "hw/acpi/cpu_hotplug.h" 54#include "hw/irq.h" 55#include "hw/nmi.h" 56#include "hw/loader.h" 57#include "multiboot.h" 58#include "elf.h" 59#include "standard-headers/asm-x86/bootparam.h" 60#include CONFIG_DEVICES 61#include "kvm/kvm_i386.h" 62 |
64#ifdef CONFIG_XEN_EMU 65#include "hw/xen/xen.h" 66#include "hw/i386/kvm/xen_evtchn.h" 67#endif 68 | |
69/* Physical Address of PVH entry point read from kernel ELF NOTE */ 70static size_t pvh_start_addr; 71 72static void init_topo_info(X86CPUTopoInfo *topo_info, 73 const X86MachineState *x86ms) 74{ 75 MachineState *ms = MACHINE(x86ms); 76 --- 533 unchanged lines hidden (view full) --- 610 switch (n) { 611 case 0 ... ISA_NUM_IRQS - 1: 612 if (s->i8259_irq[n]) { 613 /* Under KVM, Kernel will forward to both PIC and IOAPIC */ 614 qemu_set_irq(s->i8259_irq[n], level); 615 } 616 /* fall through */ 617 case ISA_NUM_IRQS ... IOAPIC_NUM_PINS - 1: | 63/* Physical Address of PVH entry point read from kernel ELF NOTE */ 64static size_t pvh_start_addr; 65 66static void init_topo_info(X86CPUTopoInfo *topo_info, 67 const X86MachineState *x86ms) 68{ 69 MachineState *ms = MACHINE(x86ms); 70 --- 533 unchanged lines hidden (view full) --- 604 switch (n) { 605 case 0 ... ISA_NUM_IRQS - 1: 606 if (s->i8259_irq[n]) { 607 /* Under KVM, Kernel will forward to both PIC and IOAPIC */ 608 qemu_set_irq(s->i8259_irq[n], level); 609 } 610 /* fall through */ 611 case ISA_NUM_IRQS ... IOAPIC_NUM_PINS - 1: |
618#ifdef CONFIG_XEN_EMU 619 /* 620 * Xen delivers the GSI to the Legacy PIC (not that Legacy PIC 621 * routing actually works properly under Xen). And then to 622 * *either* the PIRQ handling or the I/OAPIC depending on 623 * whether the former wants it. 624 */ 625 if (xen_mode == XEN_EMULATE && xen_evtchn_set_gsi(n, level)) { 626 break; 627 } 628#endif | |
629 qemu_set_irq(s->ioapic_irq[n], level); 630 break; 631 case IO_APIC_SECONDARY_IRQBASE 632 ... IO_APIC_SECONDARY_IRQBASE + IOAPIC_NUM_PINS - 1: 633 qemu_set_irq(s->ioapic2_irq[n - IO_APIC_SECONDARY_IRQBASE], level); 634 break; 635 } 636} --- 189 unchanged lines hidden (view full) --- 826 hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0, first_setup_data = 0; 827 FILE *f; 828 char *vmode; 829 MachineState *machine = MACHINE(x86ms); 830 SetupData *setup_data; 831 const char *kernel_filename = machine->kernel_filename; 832 const char *initrd_filename = machine->initrd_filename; 833 const char *dtb_filename = machine->dtb; | 612 qemu_set_irq(s->ioapic_irq[n], level); 613 break; 614 case IO_APIC_SECONDARY_IRQBASE 615 ... IO_APIC_SECONDARY_IRQBASE + IOAPIC_NUM_PINS - 1: 616 qemu_set_irq(s->ioapic2_irq[n - IO_APIC_SECONDARY_IRQBASE], level); 617 break; 618 } 619} --- 189 unchanged lines hidden (view full) --- 809 hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0, first_setup_data = 0; 810 FILE *f; 811 char *vmode; 812 MachineState *machine = MACHINE(x86ms); 813 SetupData *setup_data; 814 const char *kernel_filename = machine->kernel_filename; 815 const char *initrd_filename = machine->initrd_filename; 816 const char *dtb_filename = machine->dtb; |
834 char *kernel_cmdline; | 817 const char *kernel_cmdline = machine->kernel_cmdline; |
835 SevKernelLoaderContext sev_load_ctx = {}; 836 enum { RNG_SEED_LENGTH = 32 }; 837 | 818 SevKernelLoaderContext sev_load_ctx = {}; 819 enum { RNG_SEED_LENGTH = 32 }; 820 |
838 /* 839 * Add the NUL terminator, some padding for the microvm cmdline fiddling 840 * hack, and then align to 16 bytes as a paranoia measure 841 */ 842 cmdline_size = (strlen(machine->kernel_cmdline) + 1 + 843 VIRTIO_CMDLINE_TOTAL_MAX_LEN + 16) & ~15; 844 /* Make a copy, since we might append arbitrary bytes to it later. */ 845 kernel_cmdline = g_strndup(machine->kernel_cmdline, cmdline_size); | 821 /* Align to 16 bytes as a paranoia measure */ 822 cmdline_size = (strlen(kernel_cmdline) + 16) & ~15; |
846 847 /* load the kernel header */ 848 f = fopen(kernel_filename, "rb"); 849 if (!f) { 850 fprintf(stderr, "qemu: could not open kernel file '%s': %s\n", 851 kernel_filename, strerror(errno)); 852 exit(1); 853 } --- 124 unchanged lines hidden (view full) --- 978 } else { 979 initrd_max = 0x37ffffff; 980 } 981 982 if (initrd_max >= x86ms->below_4g_mem_size - acpi_data_size) { 983 initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1; 984 } 985 | 823 824 /* load the kernel header */ 825 f = fopen(kernel_filename, "rb"); 826 if (!f) { 827 fprintf(stderr, "qemu: could not open kernel file '%s': %s\n", 828 kernel_filename, strerror(errno)); 829 exit(1); 830 } --- 124 unchanged lines hidden (view full) --- 955 } else { 956 initrd_max = 0x37ffffff; 957 } 958 959 if (initrd_max >= x86ms->below_4g_mem_size - acpi_data_size) { 960 initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1; 961 } 962 |
963 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr); 964 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1); 965 fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); 966 sev_load_ctx.cmdline_data = (char *)kernel_cmdline; 967 sev_load_ctx.cmdline_size = strlen(kernel_cmdline) + 1; 968 |
|
986 if (protocol >= 0x202) { 987 stl_p(header + 0x228, cmdline_addr); 988 } else { 989 stw_p(header + 0x20, 0xA33F); 990 stw_p(header + 0x22, cmdline_addr - real_addr); 991 } 992 993 /* handle vga= parameter */ --- 110 unchanged lines hidden (view full) --- 1104 1105 dtb_size = get_image_size(dtb_filename); 1106 if (dtb_size <= 0) { 1107 fprintf(stderr, "qemu: error reading dtb %s: %s\n", 1108 dtb_filename, strerror(errno)); 1109 exit(1); 1110 } 1111 | 969 if (protocol >= 0x202) { 970 stl_p(header + 0x228, cmdline_addr); 971 } else { 972 stw_p(header + 0x20, 0xA33F); 973 stw_p(header + 0x22, cmdline_addr - real_addr); 974 } 975 976 /* handle vga= parameter */ --- 110 unchanged lines hidden (view full) --- 1087 1088 dtb_size = get_image_size(dtb_filename); 1089 if (dtb_size <= 0) { 1090 fprintf(stderr, "qemu: error reading dtb %s: %s\n", 1091 dtb_filename, strerror(errno)); 1092 exit(1); 1093 } 1094 |
1112 setup_data_offset = cmdline_size; 1113 cmdline_size += sizeof(SetupData) + dtb_size; 1114 kernel_cmdline = g_realloc(kernel_cmdline, cmdline_size); 1115 setup_data = (void *)kernel_cmdline + setup_data_offset; | 1095 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16); 1096 kernel_size = setup_data_offset + sizeof(SetupData) + dtb_size; 1097 kernel = g_realloc(kernel, kernel_size); 1098 1099 1100 setup_data = (SetupData *)(kernel + setup_data_offset); |
1116 setup_data->next = cpu_to_le64(first_setup_data); | 1101 setup_data->next = cpu_to_le64(first_setup_data); |
1117 first_setup_data = cmdline_addr + setup_data_offset; | 1102 first_setup_data = prot_addr + setup_data_offset; |
1118 setup_data->type = cpu_to_le32(SETUP_DTB); 1119 setup_data->len = cpu_to_le32(dtb_size); | 1103 setup_data->type = cpu_to_le32(SETUP_DTB); 1104 setup_data->len = cpu_to_le32(dtb_size); |
1105 |
|
1120 load_image_size(dtb_filename, setup_data->data, dtb_size); 1121 } 1122 | 1106 load_image_size(dtb_filename, setup_data->data, dtb_size); 1107 } 1108 |
1123 if (!legacy_no_rng_seed && protocol >= 0x209) { 1124 setup_data_offset = cmdline_size; 1125 cmdline_size += sizeof(SetupData) + RNG_SEED_LENGTH; 1126 kernel_cmdline = g_realloc(kernel_cmdline, cmdline_size); 1127 setup_data = (void *)kernel_cmdline + setup_data_offset; | 1109 if (!legacy_no_rng_seed) { 1110 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16); 1111 kernel_size = setup_data_offset + sizeof(SetupData) + RNG_SEED_LENGTH; 1112 kernel = g_realloc(kernel, kernel_size); 1113 setup_data = (SetupData *)(kernel + setup_data_offset); |
1128 setup_data->next = cpu_to_le64(first_setup_data); | 1114 setup_data->next = cpu_to_le64(first_setup_data); |
1129 first_setup_data = cmdline_addr + setup_data_offset; | 1115 first_setup_data = prot_addr + setup_data_offset; |
1130 setup_data->type = cpu_to_le32(SETUP_RNG_SEED); 1131 setup_data->len = cpu_to_le32(RNG_SEED_LENGTH); 1132 qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH); 1133 qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data); 1134 fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL, 1135 setup_data, kernel, kernel_size, true); 1136 } else { 1137 fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size); 1138 } 1139 | 1116 setup_data->type = cpu_to_le32(SETUP_RNG_SEED); 1117 setup_data->len = cpu_to_le32(RNG_SEED_LENGTH); 1118 qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH); 1119 qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data); 1120 fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL, 1121 setup_data, kernel, kernel_size, true); 1122 } else { 1123 fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size); 1124 } 1125 |
1140 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr); 1141 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, cmdline_size); 1142 fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline, cmdline_size); 1143 sev_load_ctx.cmdline_data = (char *)kernel_cmdline; 1144 sev_load_ctx.cmdline_size = cmdline_size; 1145 | |
1146 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); 1147 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); 1148 sev_load_ctx.kernel_data = (char *)kernel; 1149 sev_load_ctx.kernel_size = kernel_size; 1150 1151 /* 1152 * If we're starting an encrypted VM, it will be OVMF based, which uses the 1153 * efi stub for booting and doesn't require any values to be placed in the 1154 * kernel header. We therefore don't update the header so the hash of the 1155 * kernel on the other side of the fw_cfg interface matches the hash of the 1156 * file the user passed in. 1157 */ | 1126 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); 1127 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); 1128 sev_load_ctx.kernel_data = (char *)kernel; 1129 sev_load_ctx.kernel_size = kernel_size; 1130 1131 /* 1132 * If we're starting an encrypted VM, it will be OVMF based, which uses the 1133 * efi stub for booting and doesn't require any values to be placed in the 1134 * kernel header. We therefore don't update the header so the hash of the 1135 * kernel on the other side of the fw_cfg interface matches the hash of the 1136 * file the user passed in. 1137 */ |
1158 if (!sev_enabled() && first_setup_data) { | 1138 if (!sev_enabled()) { |
1159 SetupDataFixup *fixup = g_malloc(sizeof(*fixup)); 1160 1161 memcpy(setup, header, MIN(sizeof(header), setup_size)); 1162 /* Offset 0x250 is a pointer to the first setup_data link. */ 1163 fixup->pos = setup + 0x250; 1164 fixup->orig_val = ldq_p(fixup->pos); 1165 fixup->new_val = first_setup_data; 1166 fixup->addr = cpu_to_le32(real_addr); --- 380 unchanged lines hidden --- | 1139 SetupDataFixup *fixup = g_malloc(sizeof(*fixup)); 1140 1141 memcpy(setup, header, MIN(sizeof(header), setup_size)); 1142 /* Offset 0x250 is a pointer to the first setup_data link. */ 1143 fixup->pos = setup + 0x250; 1144 fixup->orig_val = ldq_p(fixup->pos); 1145 fixup->new_val = first_setup_data; 1146 fixup->addr = cpu_to_le32(real_addr); --- 380 unchanged lines hidden --- |