Up until now there are just two ways how to specify UEFI paths to libvirt. The first one is editing qemu.conf, the other is editing qemu_conf.c and recompile which is not that fancy. So, new configure option is introduced: --with-loader-nvram which takes a list of pairs of UEFI firmware and NVRAM store. This way, the compiled in defaults can be passed during compile time without need to change the code itself. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- configure.ac | 32 +++++++++++++++++ src/qemu/qemu.conf | 12 +++++-- src/qemu/qemu_conf.c | 41 ++++++++++++++++++---- src/qemu/test_libvirtd_qemu.aug.in | 1 + .../domaincaps-qemu_1.6.50-1.xml | 1 + tests/domaincapstest.c | 15 ++++---- 6 files changed, 85 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index 9d12079..164cfad 100644 --- a/configure.ac +++ b/configure.ac @@ -2786,6 +2786,38 @@ AC_ARG_WITH([default-editor], [DEFAULT_EDITOR=vi]) AC_DEFINE_UNQUOTED([DEFAULT_EDITOR], ["$DEFAULT_EDITOR"], [Default editor to use]) +AC_ARG_WITH([loader-nvram], + [AS_HELP_STRING([--with-loader-nvram], + [Pass list of pairs of <loader>:<nvram> paths. Both + pairs and list items are separated by a colon. + @<:default=paths to OVMF and its clones@:>@])], + [with_loader_nvram=${withval}], + [with_loader_nvram=no]) + +if test "$with_loader_nvram" != "no"; then + IFS=':' read -a loader_arr <<< "${with_loader_nvram}" + + loader_str_c="{" + nvram_str_c="{" + for ((indx=0; indx<${#loader_arr[@]}; indx+=2)); do + loader=${loader_arr[[indx]]} + nvram=${loader_arr[[indx+1]]} + + if test -z "$loader" || test -z "$nvram"; then + AC_MSG_ERROR([Malformed loader-nvram list]) + fi + + loader_str_c="$loader_str_c \"$loader\"," + nvram_str_c="$nvram_str_c \"$nvram\"," + done + + loader_str_c="$loader_str_c }" + nvram_str_c="$nvram_str_c }" + + AC_DEFINE_UNQUOTED([DEFAULT_LOADER], [$loader_str_c], [Array of loader paths]) + AC_DEFINE_UNQUOTED([DEFAULT_NVRAM], [$nvram_str_c], [Array of nvram paths]) +fi + # Some GNULIB base64 symbols clash with a kerberos library AC_DEFINE_UNQUOTED([isbase64],[libvirt_gl_isbase64],[Hack to avoid symbol clash]) AC_DEFINE_UNQUOTED([base64_encode],[libvirt_gl_base64_encode],[Hack to avoid symbol clash]) diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index c6db568..1c589a2 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -506,6 +506,12 @@ # however, have different variables store. Therefore the nvram is # a list of strings when a single item is in form of: # ${PATH_TO_UEFI_FW}:${PATH_TO_UEFI_VARS}. -# Later, when libvirt creates per domain variable store, this -# list is searched for the master image. -#nvram = [ "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd" ] +# Later, when libvirt creates per domain variable store, this list is +# searched for the master image. The UEFI firmware can be called +# differently for different guest architectures. For instance, it's OVMF +# for x86_64 and i686, but it's AAVMF for aarch64. The libvirt default +# follows this scheme. +#nvram = [ +# "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd", +# "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd" +#] diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 9539231..728d01e 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -107,13 +107,21 @@ void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def) VIR_FREE(def); } -#define VIR_QEMU_LOADER_FILE_PATH "/usr/share/OVMF/OVMF_CODE.fd" -#define VIR_QEMU_NVRAM_FILE_PATH "/usr/share/OVMF/OVMF_VARS.fd" +#define VIR_QEMU_OVMF_LOADER_PATH "/usr/share/AAVMF/AAVMF_CODE.fd" +#define VIR_QEMU_OVMF_NVRAM_PATH "/usr/share/AAVMF/AAVMF_VARS.fd" +#define VIR_QEMU_AAVMF_LOADER_PATH "/usr/share/OVMF/OVMF_CODE.fd" +#define VIR_QEMU_AAVMF_NVRAM_PATH "/usr/share/OVMF/OVMF_VARS.fd" virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged) { virQEMUDriverConfigPtr cfg; +#if defined(DEFAULT_LOADER) && defined(DEFAULT_NVRAM) + const char *loader[] = DEFAULT_LOADER; + const char *nvram[] = DEFAULT_NVRAM; + size_t i; +#endif + if (virQEMUConfigInitialize() < 0) return NULL; @@ -258,14 +266,33 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged) cfg->logTimestamp = true; - if (VIR_ALLOC_N(cfg->loader, 1) < 0 || - VIR_ALLOC_N(cfg->nvram, 1) < 0) +#if defined(DEFAULT_LOADER) && defined(DEFAULT_NVRAM) + verify(ARRAY_CARDINALITY(loader) == ARRAY_CARDINALITY(nvram)); + + if (VIR_ALLOC_N(cfg->loader, ARRAY_CARDINALITY(loader)) < 0 || + VIR_ALLOC_N(cfg->nvram, ARRAY_CARDINALITY(loader)) < 0) + goto error; + cfg->nloader = ARRAY_CARDINALITY(loader); + + for (i = 0; i < ARRAY_CARDINALITY(loader); i++) { + if (VIR_STRDUP(cfg->loader[i], loader[i]) < 0 || + VIR_STRDUP(cfg->nvram[i], nvram[i]) < 0) + goto error; + } + +#else /* !defined(DEFAULT_LOADER) || !defined(DEFAULT_NVRAM) */ + + if (VIR_ALLOC_N(cfg->loader, 2) < 0 || + VIR_ALLOC_N(cfg->nvram, 2) < 0) goto error; - cfg->nloader = 1; + cfg->nloader = 2; - if (VIR_STRDUP(cfg->loader[0], VIR_QEMU_LOADER_FILE_PATH) < 0 || - VIR_STRDUP(cfg->nvram[0], VIR_QEMU_NVRAM_FILE_PATH) < 0) + if (VIR_STRDUP(cfg->loader[0], VIR_QEMU_OVMF_LOADER_PATH) < 0 || + VIR_STRDUP(cfg->nvram[0], VIR_QEMU_OVMF_NVRAM_PATH) < 0 || + VIR_STRDUP(cfg->loader[1], VIR_QEMU_AAVMF_LOADER_PATH) < 0 || + VIR_STRDUP(cfg->nvram[1], VIR_QEMU_AAVMF_NVRAM_PATH) < 0) goto error; +#endif /* !defined(DEFAULT_LOADER) || !defined(DEFAULT_NVRAM) */ return cfg; diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in index 30fd27e..fc4935b 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -76,4 +76,5 @@ module Test_libvirtd_qemu = { "log_timestamp" = "0" } { "nvram" { "1" = "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd" } + { "2" = "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd" } } diff --git a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml index 346ef65..37d2102 100644 --- a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml +++ b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml @@ -5,6 +5,7 @@ <arch>x86_64</arch> <os supported='yes'> <loader supported='yes'> + <value>/usr/share/AAVMF/AAVMF_CODE.fd</value> <value>/usr/share/OVMF/OVMF_CODE.fd</value> <enum name='type'> <value>rom</value> diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c index 70d2ef3..5ca8928 100644 --- a/tests/domaincapstest.c +++ b/tests/domaincapstest.c @@ -105,6 +105,7 @@ fillQemuCaps(virDomainCapsPtr domCaps, struct fillQemuCapsData *data = (struct fillQemuCapsData *) opaque; virQEMUCapsPtr qemuCaps = data->qemuCaps; virQEMUDriverConfigPtr cfg = data->cfg; + virDomainCapsLoaderPtr loader = &domCaps->os.loader; if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps, cfg->loader, cfg->nloader) < 0) @@ -122,14 +123,14 @@ fillQemuCaps(virDomainCapsPtr domCaps, /* Moreover, as of f05b6a918e28 we are expecting to see * OVMF_CODE.fd file which may not exists everywhere. */ - if (!domCaps->os.loader.values.nvalues) { - virDomainCapsLoaderPtr loader = &domCaps->os.loader; + while (loader->values.nvalues) + VIR_FREE(loader->values.values[--loader->values.nvalues]); - if (fillStringValues(&loader->values, - "/usr/share/OVMF/OVMF_CODE.fd", - NULL) < 0) - return -1; - } + if (fillStringValues(&loader->values, + "/usr/share/AAVMF/AAVMF_CODE.fd", + "/usr/share/OVMF/OVMF_CODE.fd", + NULL) < 0) + return -1; return 0; } #endif /* WITH_QEMU */ -- 2.0.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list