On Fri, 19 Jun 2026 19:11:35 +0800
fanhuang <[email protected]> wrote:

> Add a qtest that reads the "etc/e820" fw_cfg table and checks its
> structural invariants: the file is a whole number of e820 entries and
> every entry has a non-zero length. The baseline q35 case asserts the
> guest sees RAM and, with no sp-mem device, no SOFT_RESERVED range.
> 
> Signed-off-by: FangSheng Huang <[email protected]>

Acked-by: Igor Mammedov <[email protected]>

> ---
>  tests/qtest/e820-test.c | 95 +++++++++++++++++++++++++++++++++++++++++
>  tests/qtest/meson.build |  1 +
>  2 files changed, 96 insertions(+)
>  create mode 100644 tests/qtest/e820-test.c
> 
> diff --git a/tests/qtest/e820-test.c b/tests/qtest/e820-test.c
> new file mode 100644
> index 0000000000..1db0744c08
> --- /dev/null
> +++ b/tests/qtest/e820-test.c
> @@ -0,0 +1,95 @@
> +/*
> + * qtest e820 fw_cfg test case
> + *
> + * Validate the "etc/e820" fw_cfg table that QEMU hands to the firmware.
> + *
> + * Copyright (c) 2026 Advanced Micro Devices, Inc.
> + *
> + * Authors:
> + *  FangSheng Huang <[email protected]>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +
> +#include "libqtest.h"
> +#include "libqos/fw_cfg.h"
> +#include "qemu/bswap.h"
> +
> +/* e820 entry layout and types (cf. hw/i386/e820_memory_layout.h) */
> +#define E820_RAM            1
> +#define E820_SOFT_RESERVED  0xefffffff
> +
> +struct e820_entry {
> +    uint64_t address;
> +    uint64_t length;
> +    uint32_t type;
> +} QEMU_PACKED;
> +
> +#define E820_MAX_ENTRIES    128
> +
> +/*
> + * Read and structurally validate "etc/e820": the file is a packed array
> + * of struct e820_entry, so its size must be a whole multiple of the entry
> + * size and every entry must have a non-zero length. Returns the entry
> + * count and fills @table.
> + */
> +static size_t get_e820_table(QFWCFG *fw_cfg, struct e820_entry *table)
> +{
> +    size_t filesize, n, i;
> +
> +    filesize = qfw_cfg_get_file(fw_cfg, "etc/e820", table,
> +                                E820_MAX_ENTRIES * sizeof(*table));
> +    g_assert_cmpint(filesize, >, 0);
> +    g_assert_cmpint(filesize % sizeof(struct e820_entry), ==, 0);
> +
> +    n = filesize / sizeof(struct e820_entry);
> +    g_assert_cmpint(n, <=, E820_MAX_ENTRIES);
> +
> +    for (i = 0; i < n; i++) {
> +        g_assert_cmpint(le64_to_cpu(table[i].length), >, 0);
> +    }
> +
> +    return n;
> +}
> +
> +static void test_e820_basic(void)
> +{
> +    struct e820_entry table[E820_MAX_ENTRIES];
> +    QFWCFG *fw_cfg;
> +    QTestState *s;
> +    size_t n, i;
> +    bool found_ram = false, found_soft_reserved = false;
> +
> +    s = qtest_init("-machine q35 -m 256M");
> +    fw_cfg = pc_fw_cfg_init(s);
> +
> +    n = get_e820_table(fw_cfg, table);
> +    for (i = 0; i < n; i++) {
> +        switch (le32_to_cpu(table[i].type)) {
> +        case E820_RAM:
> +            found_ram = true;
> +            break;
> +        case E820_SOFT_RESERVED:
> +            found_soft_reserved = true;
> +            break;
> +        }
> +    }
> +
> +    /* baseline: RAM present, no SOFT_RESERVED range */
> +    g_assert_true(found_ram);
> +    g_assert_false(found_soft_reserved);
> +
> +    pc_fw_cfg_uninit(fw_cfg);
> +    qtest_quit(s);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    g_test_init(&argc, &argv, NULL);
> +
> +    qtest_add_func("e820/basic", test_e820_basic);
> +
> +    return g_test_run();
> +}
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 4897325d84..d69ee27fa4 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -58,6 +58,7 @@ qtests_i386 = \
>    (config_all_devices.has_key('CONFIG_AHCI_ICH9') ? ['tco-test'] : []) +     
>                \
>    (config_all_devices.has_key('CONFIG_FDC_ISA') ? ['fdc-test'] : []) +       
>                \
>    (config_all_devices.has_key('CONFIG_I440FX') ? ['fw_cfg-test'] : []) +     
>                \
> +  (config_all_devices.has_key('CONFIG_Q35') ? ['e820-test'] : []) +          
>                 \
>    (config_all_devices.has_key('CONFIG_FW_CFG_DMA') ? ['vmcoreinfo-test'] : 
> []) +            \
>    (config_all_devices.has_key('CONFIG_I440FX') ? ['i440fx-test'] : []) +     
>                \
>    (config_all_devices.has_key('CONFIG_I440FX') ? ['ide-test'] : []) +        
>                \


Reply via email to