summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2024-12-16 14:20:33 -0500
committerStefan Hajnoczi <stefanha@redhat.com>2024-12-16 14:20:33 -0500
commit8032c78e556cd0baec111740a6c636863f9bd7c8 (patch)
tree801739ff5bd81f1e3eaf4f41d59e951c826cb498
parent5d4d26254bb8a2add3c38d1521aa5c6cff00e712 (diff)
parent0f5715e4b5706b31b3550d8e6b88871e029c7823 (diff)
downloadfocaccia-qemu-8032c78e556cd0baec111740a6c636863f9bd7c8.tar.gz
focaccia-qemu-8032c78e556cd0baec111740a6c636863f9bd7c8.zip
Merge tag 'firmware-20241216-pull-request' of https://gitlab.com/kraxel/qemu into staging
x86/loader: fix efi binary loading
x86/loader: support secure boot with direct kernel load
firmware: json descriptor updates
roms: re-add edk2-basetools target

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmdgBfwACgkQTLbY7tPo
# cTj7MQ/+MJkVWTYN59Yy1o+XgfIBMoPKuF8Rm9jyosR751Nb5slw7ivd/nr9vKOd
# QNmCUNSHqNhkt10fGZmiL/OBNPH2I226iJ/QPB6CPgn+klWu9/n/qCYHKqkUl+4V
# uAe2CtsljiMmBouJUshmUvtUeB62aykwYYUBb2WfpElBaAvDqs8O+WBCp/83ugfP
# pd0G/bG+7lI6co9KLa3u7hMgcmxu2t/uKd55BaD/H2+Py353geQtnwXThom33jhy
# RMDzSZKWXxcXpwYtGJmUgy2XQqRwCe2uCqCldJ+Yn+VqWIJhszGrfxa1W3AQWoT0
# BHcnH9uriEwMEL5gO6i83m1No9tPJQaw9qhOa/zKtAxoVjdB9FBab1+MYCyYiS4N
# BBz6pIwR+74iDjn1SCOn4vJPmblEL6qtV+IB7MauG1o9GN6IluWDDHotpcmI5B6k
# oXh7mld70cqUFWjFZvoPYEp6HBAvhXLyUf3A4fQoemEX6mSVM9eYol4GM4gTj0gs
# IsBfd9wvHmaurpXMgB0cJOpr7UbbijtssseB/WzkMWlKskuMlJxsif/IEJO+GrbZ
# RdEcdVOr45Ty1Hmqv6b9M9kUojphUchLe6nl+CQihm3K7dF27yqhcJYqNTe7mKpt
# 4+i6RZaTKKtbY8FL80ycDRZIkDZg9cwMQHMxrDABQVN5WpVfRgU=
# =4fZc
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 16 Dec 2024 05:50:36 EST
# gpg:                using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* tag 'firmware-20241216-pull-request' of https://gitlab.com/kraxel/qemu:
  roms: re-add edk2-basetools target
  pc-bios: add missing riscv64 descriptor
  pc-bios: Add amd-sev-es to edk2 json
  x86/loader: add -shim option
  x86/loader: expose unpatched kernel
  x86/loader: read complete kernel
  x86/loader: only patch linux kernels

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--hw/core/machine.c20
-rw-r--r--hw/i386/x86-common.c32
-rw-r--r--include/hw/boards.h1
-rw-r--r--pc-bios/descriptors/60-edk2-riscv64.json31
-rw-r--r--pc-bios/descriptors/60-edk2-x86_64.json1
-rw-r--r--pc-bios/descriptors/meson.build3
-rw-r--r--qemu-options.hx7
-rw-r--r--roms/Makefile5
-rw-r--r--system/vl.c9
9 files changed, 102 insertions, 7 deletions
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;