aboutsummaryrefslogtreecommitdiff
path: root/hw/i386/x86.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-03-03 13:35:54 +0000
committerPeter Maydell <peter.maydell@linaro.org>2023-03-03 13:35:54 +0000
commit66577e9e1caee48c6ebc1a2161b5d9857fcde8b3 (patch)
treef27a2c85d5f986db2c7dd4f001d8bab12a39270d /hw/i386/x86.c
parent76116e28e1491a06966fd594fefdaacb084ada10 (diff)
parentee92a56b08d0b59016a4a9bc1bf3a3de1fbe3956 (diff)
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging
virtio,pc,pci: features, cleanups, fixes vhost-user support without ioeventfd word replacements in vhost user spec shpc improvements cleanups, fixes all over the place Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmQBO8QPHG1zdEByZWRo # YXQuY29tAAoJECgfDbjSjVRpMUMH/3/FVp4qaF4CDwCHn7xWFRJpOREIhX/iWfUu # lGkwxnB7Lfyqdg7i4CAfgMf2emWKZchEE2DamfCo5bIX0IgRU3DWcOdR9ePvJ29J # cKwIYpxZcB4RYSoWL5OUakQLCT3JOu4XWaXeVjyHABjQhf3lGpwN4KmIOBGOy/N6 # 0YHOQScW2eW62wIOwhAEuYQceMt6KU32Uw3tLnMbJliiBf3a/hPctVNM9TFY9pcd # UYHGfBx/zD45owf1lTVEQFDg0eqPZKWW29g5haiOd5oAyXHHolzu+bt3bU7lH46b # f7iP12LqDudyrgoF5YWv3NJ4HaGm5V3kPqNqLLF/mjF7alxG+N8= # =hN3h # -----END PGP SIGNATURE----- # gpg: Signature made Fri 03 Mar 2023 00:13:56 GMT # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: (53 commits) tests/data/acpi/virt: drop (most) duplicate files. hw/cxl/mailbox: Use new UUID network order define for cel_uuid qemu/uuid: Add UUID static initializer qemu/bswap: Add const_le64() tests: acpi: Update q35/DSDT.cxl for removed duplicate UID hw/i386/acpi: Drop duplicate _UID entry for CXL root bridge tests/acpi: Allow update of q35/DSDT.cxl hw/cxl: Add CXL_CAPACITY_MULTIPLIER definition hw/cxl: set cxl-type3 device type to PCI_CLASS_MEMORY_CXL hw/pci-bridge/cxl_downstream: Fix type naming mismatch hw/mem/cxl_type3: Improve error handling in realize() MAINTAINERS: Add Fan Ni as Compute eXpress Link QEMU reviewer intel-iommu: send UNMAP notifications for domain or global inv desc smmu: switch to use memory_region_unmap_iommu_notifier_range() memory: introduce memory_region_unmap_iommu_notifier_range() intel-iommu: fail DEVIOTLB_UNMAP without dt mode intel-iommu: fail MAP notifier without caching mode memory: Optimize replay of guest mapping chardev/char-socket: set s->listener = NULL in char_socket_finalize hw/pci: Trace IRQ routing on PCI topology ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i386/x86.c')
-rw-r--r--hw/i386/x86.c122
1 files changed, 32 insertions, 90 deletions
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index a56b10b2fb..a88a126123 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -26,7 +26,6 @@
#include "qemu/cutils.h"
#include "qemu/units.h"
#include "qemu/datadir.h"
-#include "qemu/guest-random.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-common.h"
#include "qapi/clone-visitor.h"
@@ -36,7 +35,6 @@
#include "sysemu/whpx.h"
#include "sysemu/numa.h"
#include "sysemu/replay.h"
-#include "sysemu/reset.h"
#include "sysemu/sysemu.h"
#include "sysemu/cpu-timers.h"
#include "sysemu/xen.h"
@@ -49,7 +47,6 @@
#include "hw/intc/i8259.h"
#include "hw/rtc/mc146818rtc.h"
#include "target/i386/sev.h"
-#include "hw/i386/microvm.h"
#include "hw/acpi/cpu_hotplug.h"
#include "hw/irq.h"
@@ -675,12 +672,12 @@ DeviceState *ioapic_init_secondary(GSIState *gsi_state)
return dev;
}
-typedef struct SetupData {
+struct setup_data {
uint64_t next;
uint32_t type;
uint32_t len;
uint8_t data[];
-} __attribute__((packed)) SetupData;
+} __attribute__((packed));
/*
@@ -787,35 +784,10 @@ static bool load_elfboot(const char *kernel_filename,
return true;
}
-typedef struct SetupDataFixup {
- void *pos;
- hwaddr orig_val, new_val;
- uint32_t addr;
-} SetupDataFixup;
-
-static void fixup_setup_data(void *opaque)
-{
- SetupDataFixup *fixup = opaque;
- stq_p(fixup->pos, fixup->new_val);
-}
-
-static void reset_setup_data(void *opaque)
-{
- SetupDataFixup *fixup = opaque;
- stq_p(fixup->pos, fixup->orig_val);
-}
-
-static void reset_rng_seed(void *opaque)
-{
- SetupData *setup_data = opaque;
- qemu_guest_getrandom_nofail(setup_data->data, le32_to_cpu(setup_data->len));
-}
-
void x86_load_linux(X86MachineState *x86ms,
FWCfgState *fw_cfg,
int acpi_data_size,
- bool pvh_enabled,
- bool legacy_no_rng_seed)
+ bool pvh_enabled)
{
bool linuxboot_dma_enabled = X86_MACHINE_GET_CLASS(x86ms)->fwcfg_dma_enabled;
uint16_t protocol;
@@ -823,26 +795,19 @@ void x86_load_linux(X86MachineState *x86ms,
int dtb_size, setup_data_offset;
uint32_t initrd_max;
uint8_t header[8192], *setup, *kernel;
- hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0, first_setup_data = 0;
+ hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0;
FILE *f;
char *vmode;
MachineState *machine = MACHINE(x86ms);
- SetupData *setup_data;
+ struct setup_data *setup_data;
const char *kernel_filename = machine->kernel_filename;
const char *initrd_filename = machine->initrd_filename;
const char *dtb_filename = machine->dtb;
- char *kernel_cmdline;
+ const char *kernel_cmdline = machine->kernel_cmdline;
SevKernelLoaderContext sev_load_ctx = {};
- enum { RNG_SEED_LENGTH = 32 };
- /*
- * Add the NUL terminator, some padding for the microvm cmdline fiddling
- * hack, and then align to 16 bytes as a paranoia measure
- */
- cmdline_size = (strlen(machine->kernel_cmdline) + 1 +
- VIRTIO_CMDLINE_TOTAL_MAX_LEN + 16) & ~15;
- /* Make a copy, since we might append arbitrary bytes to it later. */
- kernel_cmdline = g_strndup(machine->kernel_cmdline, cmdline_size);
+ /* Align to 16 bytes as a paranoia measure */
+ cmdline_size = (strlen(kernel_cmdline) + 16) & ~15;
/* load the kernel header */
f = fopen(kernel_filename, "rb");
@@ -983,6 +948,12 @@ void x86_load_linux(X86MachineState *x86ms,
initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1;
}
+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1);
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
+ sev_load_ctx.cmdline_data = (char *)kernel_cmdline;
+ sev_load_ctx.cmdline_size = strlen(kernel_cmdline) + 1;
+
if (protocol >= 0x202) {
stl_p(header + 0x228, cmdline_addr);
} else {
@@ -1109,45 +1080,20 @@ void x86_load_linux(X86MachineState *x86ms,
exit(1);
}
- setup_data_offset = cmdline_size;
- cmdline_size += sizeof(SetupData) + dtb_size;
- kernel_cmdline = g_realloc(kernel_cmdline, cmdline_size);
- setup_data = (void *)kernel_cmdline + setup_data_offset;
- setup_data->next = cpu_to_le64(first_setup_data);
- first_setup_data = cmdline_addr + setup_data_offset;
+ setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
+ kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size;
+ kernel = g_realloc(kernel, kernel_size);
+
+ stq_p(header + 0x250, prot_addr + setup_data_offset);
+
+ setup_data = (struct setup_data *)(kernel + setup_data_offset);
+ setup_data->next = 0;
setup_data->type = cpu_to_le32(SETUP_DTB);
setup_data->len = cpu_to_le32(dtb_size);
- load_image_size(dtb_filename, setup_data->data, dtb_size);
- }
- if (!legacy_no_rng_seed && protocol >= 0x209) {
- setup_data_offset = cmdline_size;
- cmdline_size += sizeof(SetupData) + RNG_SEED_LENGTH;
- kernel_cmdline = g_realloc(kernel_cmdline, cmdline_size);
- setup_data = (void *)kernel_cmdline + setup_data_offset;
- setup_data->next = cpu_to_le64(first_setup_data);
- first_setup_data = cmdline_addr + setup_data_offset;
- setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
- setup_data->len = cpu_to_le32(RNG_SEED_LENGTH);
- qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
- qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data);
- fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL,
- setup_data, kernel, kernel_size, true);
- } else {
- fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
+ load_image_size(dtb_filename, setup_data->data, dtb_size);
}
- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, cmdline_size);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline, cmdline_size);
- sev_load_ctx.cmdline_data = (char *)kernel_cmdline;
- sev_load_ctx.cmdline_size = cmdline_size;
-
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
- sev_load_ctx.kernel_data = (char *)kernel;
- sev_load_ctx.kernel_size = kernel_size;
-
/*
* If we're starting an encrypted VM, it will be OVMF based, which uses the
* efi stub for booting and doesn't require any values to be placed in the
@@ -1155,21 +1101,17 @@ void x86_load_linux(X86MachineState *x86ms,
* kernel on the other side of the fw_cfg interface matches the hash of the
* file the user passed in.
*/
- if (!sev_enabled() && first_setup_data) {
- SetupDataFixup *fixup = g_malloc(sizeof(*fixup));
-
+ if (!sev_enabled()) {
memcpy(setup, header, MIN(sizeof(header), setup_size));
- /* Offset 0x250 is a pointer to the first setup_data link. */
- fixup->pos = setup + 0x250;
- fixup->orig_val = ldq_p(fixup->pos);
- fixup->new_val = first_setup_data;
- fixup->addr = cpu_to_le32(real_addr);
- fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_SETUP_ADDR, fixup_setup_data, NULL,
- fixup, &fixup->addr, sizeof(fixup->addr), true);
- qemu_register_reset(reset_setup_data, fixup);
- } else {
- fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
}
+
+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
+ fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
+ sev_load_ctx.kernel_data = (char *)kernel;
+ sev_load_ctx.kernel_size = kernel_size;
+
+ fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
sev_load_ctx.setup_data = (char *)setup;