x86.c (7f5acfcb662d32a736d0db41211cc7f340193bdd) | x86.c (eac7a7791bb6d719233deed750034042318ffd56) |
---|---|
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 --- 36 unchanged lines hidden (view full) --- 45 46#include "hw/i386/x86.h" 47#include "target/i386/cpu.h" 48#include "hw/i386/topology.h" 49#include "hw/i386/fw_cfg.h" 50#include "hw/intc/i8259.h" 51#include "hw/rtc/mc146818rtc.h" 52#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 --- 36 unchanged lines hidden (view full) --- 45 46#include "hw/i386/x86.h" 47#include "target/i386/cpu.h" 48#include "hw/i386/topology.h" 49#include "hw/i386/fw_cfg.h" 50#include "hw/intc/i8259.h" 51#include "hw/rtc/mc146818rtc.h" 52#include "target/i386/sev.h" |
53#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" --- 747 unchanged lines hidden (view full) --- 808 hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0, first_setup_data = 0; 809 FILE *f; 810 char *vmode; 811 MachineState *machine = MACHINE(x86ms); 812 SetupData *setup_data; 813 const char *kernel_filename = machine->kernel_filename; 814 const char *initrd_filename = machine->initrd_filename; 815 const char *dtb_filename = machine->dtb; | 54 55#include "hw/acpi/cpu_hotplug.h" 56#include "hw/irq.h" 57#include "hw/nmi.h" 58#include "hw/loader.h" 59#include "multiboot.h" 60#include "elf.h" 61#include "standard-headers/asm-x86/bootparam.h" --- 747 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; |
816 const char *kernel_cmdline = machine->kernel_cmdline; | 817 char *kernel_cmdline; |
817 SevKernelLoaderContext sev_load_ctx = {}; 818 enum { RNG_SEED_LENGTH = 32 }; 819 | 818 SevKernelLoaderContext sev_load_ctx = {}; 819 enum { RNG_SEED_LENGTH = 32 }; 820 |
820 /* Align to 16 bytes as a paranoia measure */ 821 cmdline_size = (strlen(kernel_cmdline) + 16) & ~15; | 821 /* 822 * Add the NUL terminator, some padding for the microvm cmdline fiddling 823 * hack, and then align to 16 bytes as a paranoia measure 824 */ 825 cmdline_size = (strlen(machine->kernel_cmdline) + 1 + 826 VIRTIO_CMDLINE_TOTAL_MAX_LEN + 16) & ~15; 827 /* Make a copy, since we might append arbitrary bytes to it later. */ 828 kernel_cmdline = g_strndup(machine->kernel_cmdline, cmdline_size); |
822 823 /* load the kernel header */ 824 f = fopen(kernel_filename, "rb"); 825 if (!f) { 826 fprintf(stderr, "qemu: could not open kernel file '%s': %s\n", 827 kernel_filename, strerror(errno)); 828 exit(1); 829 } --- 124 unchanged lines hidden (view full) --- 954 } else { 955 initrd_max = 0x37ffffff; 956 } 957 958 if (initrd_max >= x86ms->below_4g_mem_size - acpi_data_size) { 959 initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1; 960 } 961 | 829 830 /* load the kernel header */ 831 f = fopen(kernel_filename, "rb"); 832 if (!f) { 833 fprintf(stderr, "qemu: could not open kernel file '%s': %s\n", 834 kernel_filename, strerror(errno)); 835 exit(1); 836 } --- 124 unchanged lines hidden (view full) --- 961 } else { 962 initrd_max = 0x37ffffff; 963 } 964 965 if (initrd_max >= x86ms->below_4g_mem_size - acpi_data_size) { 966 initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1; 967 } 968 |
962 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr); 963 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1); 964 fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); 965 sev_load_ctx.cmdline_data = (char *)kernel_cmdline; 966 sev_load_ctx.cmdline_size = strlen(kernel_cmdline) + 1; 967 | |
968 if (protocol >= 0x202) { 969 stl_p(header + 0x228, cmdline_addr); 970 } else { 971 stw_p(header + 0x20, 0xA33F); 972 stw_p(header + 0x22, cmdline_addr - real_addr); 973 } 974 975 /* handle vga= parameter */ --- 110 unchanged lines hidden (view full) --- 1086 1087 dtb_size = get_image_size(dtb_filename); 1088 if (dtb_size <= 0) { 1089 fprintf(stderr, "qemu: error reading dtb %s: %s\n", 1090 dtb_filename, strerror(errno)); 1091 exit(1); 1092 } 1093 | 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 |
1094 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16); 1095 kernel_size = setup_data_offset + sizeof(SetupData) + dtb_size; 1096 kernel = g_realloc(kernel, kernel_size); 1097 1098 1099 setup_data = (SetupData *)(kernel + setup_data_offset); | 1095 setup_data_offset = cmdline_size; 1096 cmdline_size += sizeof(SetupData) + dtb_size; 1097 kernel_cmdline = g_realloc(kernel_cmdline, cmdline_size); 1098 setup_data = (void *)kernel_cmdline + setup_data_offset; |
1100 setup_data->next = cpu_to_le64(first_setup_data); | 1099 setup_data->next = cpu_to_le64(first_setup_data); |
1101 first_setup_data = prot_addr + setup_data_offset; | 1100 first_setup_data = cmdline_addr + setup_data_offset; |
1102 setup_data->type = cpu_to_le32(SETUP_DTB); 1103 setup_data->len = cpu_to_le32(dtb_size); | 1101 setup_data->type = cpu_to_le32(SETUP_DTB); 1102 setup_data->len = cpu_to_le32(dtb_size); |
1104 | |
1105 load_image_size(dtb_filename, setup_data->data, dtb_size); 1106 } 1107 | 1103 load_image_size(dtb_filename, setup_data->data, dtb_size); 1104 } 1105 |
1108 if (!legacy_no_rng_seed) { 1109 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16); 1110 kernel_size = setup_data_offset + sizeof(SetupData) + RNG_SEED_LENGTH; 1111 kernel = g_realloc(kernel, kernel_size); 1112 setup_data = (SetupData *)(kernel + setup_data_offset); | 1106 if (!legacy_no_rng_seed && protocol >= 0x209) { 1107 setup_data_offset = cmdline_size; 1108 cmdline_size += sizeof(SetupData) + RNG_SEED_LENGTH; 1109 kernel_cmdline = g_realloc(kernel_cmdline, cmdline_size); 1110 setup_data = (void *)kernel_cmdline + setup_data_offset; |
1113 setup_data->next = cpu_to_le64(first_setup_data); | 1111 setup_data->next = cpu_to_le64(first_setup_data); |
1114 first_setup_data = prot_addr + setup_data_offset; | 1112 first_setup_data = cmdline_addr + setup_data_offset; |
1115 setup_data->type = cpu_to_le32(SETUP_RNG_SEED); 1116 setup_data->len = cpu_to_le32(RNG_SEED_LENGTH); 1117 qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH); 1118 qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data); 1119 fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL, 1120 setup_data, kernel, kernel_size, true); 1121 } else { 1122 fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size); 1123 } 1124 | 1113 setup_data->type = cpu_to_le32(SETUP_RNG_SEED); 1114 setup_data->len = cpu_to_le32(RNG_SEED_LENGTH); 1115 qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH); 1116 qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data); 1117 fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL, 1118 setup_data, kernel, kernel_size, true); 1119 } else { 1120 fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size); 1121 } 1122 |
1123 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr); 1124 fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, cmdline_size); 1125 fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline, cmdline_size); 1126 sev_load_ctx.cmdline_data = (char *)kernel_cmdline; 1127 sev_load_ctx.cmdline_size = cmdline_size; 1128 |
|
1125 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); 1126 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); 1127 sev_load_ctx.kernel_data = (char *)kernel; 1128 sev_load_ctx.kernel_size = kernel_size; 1129 1130 /* 1131 * If we're starting an encrypted VM, it will be OVMF based, which uses the 1132 * efi stub for booting and doesn't require any values to be placed in the 1133 * kernel header. We therefore don't update the header so the hash of the 1134 * kernel on the other side of the fw_cfg interface matches the hash of the 1135 * file the user passed in. 1136 */ | 1129 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); 1130 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); 1131 sev_load_ctx.kernel_data = (char *)kernel; 1132 sev_load_ctx.kernel_size = kernel_size; 1133 1134 /* 1135 * If we're starting an encrypted VM, it will be OVMF based, which uses the 1136 * efi stub for booting and doesn't require any values to be placed in the 1137 * kernel header. We therefore don't update the header so the hash of the 1138 * kernel on the other side of the fw_cfg interface matches the hash of the 1139 * file the user passed in. 1140 */ |
1137 if (!sev_enabled()) { | 1141 if (!sev_enabled() && first_setup_data) { |
1138 SetupDataFixup *fixup = g_malloc(sizeof(*fixup)); 1139 1140 memcpy(setup, header, MIN(sizeof(header), setup_size)); 1141 /* Offset 0x250 is a pointer to the first setup_data link. */ 1142 fixup->pos = setup + 0x250; 1143 fixup->orig_val = ldq_p(fixup->pos); 1144 fixup->new_val = first_setup_data; 1145 fixup->addr = cpu_to_le32(real_addr); --- 380 unchanged lines hidden --- | 1142 SetupDataFixup *fixup = g_malloc(sizeof(*fixup)); 1143 1144 memcpy(setup, header, MIN(sizeof(header), setup_size)); 1145 /* Offset 0x250 is a pointer to the first setup_data link. */ 1146 fixup->pos = setup + 0x250; 1147 fixup->orig_val = ldq_p(fixup->pos); 1148 fixup->new_val = first_setup_data; 1149 fixup->addr = cpu_to_le32(real_addr); --- 380 unchanged lines hidden --- |