diff --git a/hw/core/machine.c b/hw/core/machine.c index e6900b43ef..d970f753e3 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -305,6 +305,21 @@ static void machine_set_kernel(Object *obj, const char *value, Error **errp) ms->kernel_filename = g_strdup(value); } +static char *machine_get_shim(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->shim_filename); +} + +static void machine_set_shim(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + g_free(ms->shim_filename); + ms->shim_filename = g_strdup(value); +} + static char *machine_get_initrd(Object *obj, Error **errp) { MachineState *ms = MACHINE(obj); @@ -1082,6 +1097,11 @@ static void machine_class_init(ObjectClass *oc, void *data) object_class_property_set_description(oc, "kernel", "Linux kernel image file"); + object_class_property_add_str(oc, "shim", + machine_get_shim, machine_set_shim); + object_class_property_set_description(oc, "shim", + "shim.efi file"); + object_class_property_add_str(oc, "initrd", machine_get_initrd, machine_set_initrd); object_class_property_set_description(oc, "initrd", diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c index dc031af662..3f78182692 100644 --- a/hw/i386/x86-common.c +++ b/hw/i386/x86-common.c @@ -895,7 +895,6 @@ void x86_load_linux(X86MachineState *x86ms, fprintf(stderr, "qemu: invalid kernel header\n"); exit(1); } - kernel_size -= setup_size; setup = g_malloc(setup_size); kernel = g_malloc(kernel_size); @@ -904,6 +903,7 @@ void x86_load_linux(X86MachineState *x86ms, fprintf(stderr, "fread() failed\n"); exit(1); } + fseek(f, 0, SEEK_SET); if (fread(kernel, 1, kernel_size, f) != kernel_size) { fprintf(stderr, "fread() failed\n"); exit(1); @@ -945,15 +945,16 @@ 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()) { + if (!sev_enabled() && protocol > 0) { memcpy(setup, header, MIN(sizeof(header), setup_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); - 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_KERNEL_SIZE, kernel_size - setup_size); + fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, + kernel + setup_size, kernel_size - setup_size); + sev_load_ctx.kernel_data = (char *)kernel + setup_size; + sev_load_ctx.kernel_size = kernel_size - setup_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); @@ -961,6 +962,25 @@ void x86_load_linux(X86MachineState *x86ms, sev_load_ctx.setup_data = (char *)setup; sev_load_ctx.setup_size = setup_size; + /* kernel without setup header patches */ + fw_cfg_add_file(fw_cfg, "etc/boot/kernel", kernel, kernel_size); + + if (machine->shim_filename) { + GMappedFile *mapped_file; + GError *gerr = NULL; + + mapped_file = g_mapped_file_new(machine->shim_filename, false, &gerr); + if (!mapped_file) { + fprintf(stderr, "qemu: error reading shim %s: %s\n", + machine->shim_filename, gerr->message); + exit(1); + } + + fw_cfg_add_file(fw_cfg, "etc/boot/shim", + g_mapped_file_get_contents(mapped_file), + g_mapped_file_get_length(mapped_file)); + } + if (sev_enabled()) { sev_add_kernel_loader_hashes(&sev_load_ctx, &error_fatal); } diff --git a/include/hw/boards.h b/include/hw/boards.h index 7456889c37..5723ee76bd 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -431,6 +431,7 @@ struct MachineState { BootConfiguration boot_config; char *kernel_filename; char *kernel_cmdline; + char *shim_filename; char *initrd_filename; const char *cpu_type; AccelState *accelerator; diff --git a/pc-bios/descriptors/60-edk2-riscv64.json b/pc-bios/descriptors/60-edk2-riscv64.json new file mode 100644 index 0000000000..14811ca307 --- /dev/null +++ b/pc-bios/descriptors/60-edk2-riscv64.json @@ -0,0 +1,31 @@ +{ + "description": "UEFI firmware for riscv64", + "interface-types": [ + "uefi" + ], + "mapping": { + "device": "flash", + "executable": { + "filename": "@DATADIR@/edk2-riscv-code.fd", + "format": "raw" + }, + "nvram-template": { + "filename": "@DATADIR@/edk2-riscv-vars.fd", + "format": "raw" + } + }, + "targets": [ + { + "architecture": "riscv64", + "machines": [ + "virt*" + ] + } + ], + "features": [ + + ], + "tags": [ + + ] +} diff --git a/pc-bios/descriptors/60-edk2-x86_64.json b/pc-bios/descriptors/60-edk2-x86_64.json index 968cb65cf9..4599c63f14 100644 --- a/pc-bios/descriptors/60-edk2-x86_64.json +++ b/pc-bios/descriptors/60-edk2-x86_64.json @@ -26,6 +26,7 @@ "features": [ "acpi-s3", "amd-sev", + "amd-sev-es", "verbose-dynamic" ], "tags": [ diff --git a/pc-bios/descriptors/meson.build b/pc-bios/descriptors/meson.build index afb5a959cc..cdd0be01a3 100644 --- a/pc-bios/descriptors/meson.build +++ b/pc-bios/descriptors/meson.build @@ -6,7 +6,8 @@ if unpack_edk2_blobs and get_option('install_blobs') '60-edk2-arm.json', '60-edk2-i386.json', '60-edk2-x86_64.json', - '60-edk2-loongarch64.json' + '60-edk2-loongarch64.json', + '60-edk2-riscv64.json' ] configure_file(input: files(f), output: f, diff --git a/qemu-options.hx b/qemu-options.hx index dacc9790a4..cc694d3b89 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4145,6 +4145,13 @@ SRST or in multiboot format. ERST +DEF("shim", HAS_ARG, QEMU_OPTION_shim, \ + "-shim shim.efi use 'shim.efi' to boot the kernel\n", QEMU_ARCH_ALL) +SRST +``-shim shim.efi`` + Use 'shim.efi' to boot the kernel +ERST + DEF("append", HAS_ARG, QEMU_OPTION_append, \ "-append cmdline use 'cmdline' as kernel command line\n", QEMU_ARCH_ALL) SRST diff --git a/roms/Makefile b/roms/Makefile index dfed2b216a..31e4b97c98 100644 --- a/roms/Makefile +++ b/roms/Makefile @@ -157,6 +157,11 @@ edk2-version: edk2 touch $@; \ fi +edk2-basetools: edk2-version + $(PYTHON) edk2-build.py --config edk2-build.config \ + --silent --no-logs \ + --match none # build only basetools + efi: edk2-version $(PYTHON) edk2-build.py --config edk2-build.config \ --version-override "$(EDK2_STABLE)$(FIRMWARE_EXTRAVERSION)" \ diff --git a/system/vl.c b/system/vl.c index 4a370da624..09202b57e7 100644 --- a/system/vl.c +++ b/system/vl.c @@ -2427,6 +2427,7 @@ static void configure_accelerators(const char *progname) static void qemu_validate_options(const QDict *machine_opts) { const char *kernel_filename = qdict_get_try_str(machine_opts, "kernel"); + const char *shim_filename = qdict_get_try_str(machine_opts, "shim"); const char *initrd_filename = qdict_get_try_str(machine_opts, "initrd"); const char *kernel_cmdline = qdict_get_try_str(machine_opts, "append"); @@ -2436,6 +2437,11 @@ static void qemu_validate_options(const QDict *machine_opts) exit(1); } + if (shim_filename != NULL) { + error_report("-shim only allowed with -kernel option"); + exit(1); + } + if (initrd_filename != NULL) { error_report("-initrd only allowed with -kernel option"); exit(1); @@ -2912,6 +2918,9 @@ void qemu_init(int argc, char **argv) case QEMU_OPTION_kernel: qdict_put_str(machine_opts_dict, "kernel", optarg); break; + case QEMU_OPTION_shim: + qdict_put_str(machine_opts_dict, "shim", optarg); + break; case QEMU_OPTION_initrd: qdict_put_str(machine_opts_dict, "initrd", optarg); break;