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 ---