* [PATCH v5 01/10] x86: Replace arch-specific boot_module with common one
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
@ 2025-07-01 10:56 ` Alejandro Vallejo
2025-07-02 12:43 ` Jan Beulich
2025-07-01 10:56 ` [PATCH v5 02/10] xen: Refactor kernel_info to have a header like boot_domain Alejandro Vallejo
` (8 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:56 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Jan Beulich, Andrew Cooper,
Roger Pau Monné, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Daniel P. Smith
These types resemble each other very closely in layout and intent,
and with "struct boot_module" already in common code it makes perfect
sense to merge them. In order to do so, add an arch-specific area for
x86-specific tidbits, and rename identical fields with conflicting
names.
No functional change intended.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
xen/arch/x86/cpu/microcode/core.c | 7 ++--
xen/arch/x86/hvm/dom0_build.c | 6 ++--
xen/arch/x86/include/asm/bootfdt.h | 50 ++++++++++++++++++++++++++
xen/arch/x86/include/asm/bootinfo.h | 56 +++--------------------------
xen/arch/x86/pv/dom0_build.c | 4 +--
xen/arch/x86/setup.c | 43 +++++++++++-----------
xen/include/xen/bootfdt.h | 8 +++++
xen/xsm/xsm_policy.c | 2 +-
8 files changed, 93 insertions(+), 83 deletions(-)
create mode 100644 xen/arch/x86/include/asm/bootfdt.h
diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
index 34a94cd25b..816e9bfe40 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -764,8 +764,7 @@ static int __init early_microcode_load(struct boot_info *bi)
struct cpio_data cd;
/* Search anything unclaimed or likely to be a CPIO archive. */
- if ( bm->type != BOOTMOD_UNKNOWN &&
- bm->type != BOOTMOD_RAMDISK )
+ if ( bm->kind != BOOTMOD_UNKNOWN && bm->kind != BOOTMOD_RAMDISK )
continue;
size = bm->size;
@@ -815,12 +814,12 @@ static int __init early_microcode_load(struct boot_info *bi)
return -ENODEV;
}
- if ( bi->mods[idx].type != BOOTMOD_UNKNOWN )
+ if ( bi->mods[idx].kind != BOOTMOD_UNKNOWN )
{
printk(XENLOG_WARNING "Microcode: Chosen module %d already used\n", idx);
return -ENODEV;
}
- bi->mods[idx].type = BOOTMOD_MICROCODE;
+ bi->mods[idx].kind = BOOTMOD_MICROCODE;
size = bi->mods[idx].size;
data = bootstrap_map_bm(&bi->mods[idx]);
diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c
index a038e58c11..2bb8ef355c 100644
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -650,7 +650,7 @@ static int __init pvh_load_kernel(
struct boot_module *image = bd->kernel;
struct boot_module *initrd = bd->module;
void *image_base = bootstrap_map_bm(image);
- void *image_start = image_base + image->headroom;
+ void *image_start = image_base + image->arch.headroom;
unsigned long image_len = image->size;
unsigned long initrd_len = initrd ? initrd->size : 0;
size_t cmdline_len = bd->cmdline ? strlen(bd->cmdline) + 1 : 0;
@@ -721,9 +721,9 @@ static int __init pvh_load_kernel(
{
size_t initrd_space = elf_round_up(&elf, initrd_len);
- if ( initrd->cmdline_pa )
+ if ( initrd->arch.cmdline_pa )
{
- initrd_cmdline = __va(initrd->cmdline_pa);
+ initrd_cmdline = __va(initrd->arch.cmdline_pa);
if ( !*initrd_cmdline )
initrd_cmdline = NULL;
}
diff --git a/xen/arch/x86/include/asm/bootfdt.h b/xen/arch/x86/include/asm/bootfdt.h
new file mode 100644
index 0000000000..a4c4bf30b9
--- /dev/null
+++ b/xen/arch/x86/include/asm/bootfdt.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef X86_BOOTFDT_H
+#define X86_BOOTFDT_H
+
+#include <xen/types.h>
+
+struct arch_boot_module
+{
+ /*
+ * Module State Flags:
+ * relocated: indicates module has been relocated in memory.
+ * released: indicates module's pages have been freed.
+ */
+ bool relocated:1;
+ bool released:1;
+
+ /*
+ * A boot module may need decompressing by Xen. Headroom is an estimate of
+ * the additional space required to decompress the module.
+ *
+ * Headroom is accounted for at the start of the module. Decompressing is
+ * done in-place with input=start, output=start-headroom, expecting the
+ * pointers to become equal (give or take some rounding) when decompression
+ * is complete.
+ *
+ * Memory layout at boot:
+ *
+ * start ----+
+ * v
+ * |<-----headroom------>|<------size------->|
+ * +-------------------+
+ * | Compressed Module |
+ * +---------------------+-------------------+
+ * | Decompressed Module |
+ * +-----------------------------------------+
+ */
+ unsigned long headroom;
+ paddr_t cmdline_pa;
+};
+
+#endif /* X86_BOOTFDT_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/x86/include/asm/bootinfo.h b/xen/arch/x86/include/asm/bootinfo.h
index 3afc214c17..d33b100e04 100644
--- a/xen/arch/x86/include/asm/bootinfo.h
+++ b/xen/arch/x86/include/asm/bootinfo.h
@@ -8,6 +8,7 @@
#ifndef X86_BOOTINFO_H
#define X86_BOOTINFO_H
+#include <xen/bootfdt.h>
#include <xen/init.h>
#include <xen/multiboot.h>
#include <xen/types.h>
@@ -19,55 +20,6 @@
/* Max number of boot domains that Xen can construct */
#define MAX_NR_BOOTDOMS 1
-/* Boot module binary type / purpose */
-enum bootmod_type {
- BOOTMOD_UNKNOWN,
- BOOTMOD_XEN,
- BOOTMOD_KERNEL,
- BOOTMOD_RAMDISK,
- BOOTMOD_MICROCODE,
- BOOTMOD_XSM_POLICY,
-};
-
-struct boot_module {
- enum bootmod_type type;
-
- /*
- * Module State Flags:
- * relocated: indicates module has been relocated in memory.
- * released: indicates module's pages have been freed.
- */
- bool relocated:1;
- bool released:1;
-
- /*
- * A boot module may need decompressing by Xen. Headroom is an estimate of
- * the additional space required to decompress the module.
- *
- * Headroom is accounted for at the start of the module. Decompressing is
- * done in-place with input=start, output=start-headroom, expecting the
- * pointers to become equal (give or take some rounding) when decompression
- * is complete.
- *
- * Memory layout at boot:
- *
- * start ----+
- * v
- * |<-----headroom------>|<------size------->|
- * +-------------------+
- * | Compressed Module |
- * +---------------------+-------------------+
- * | Decompressed Module |
- * +-----------------------------------------+
- */
- unsigned long headroom;
-
- paddr_t cmdline_pa;
-
- paddr_t start;
- size_t size;
-};
-
/*
* Xen internal representation of information provided by the
* bootloader/environment, or derived from the information.
@@ -94,16 +46,16 @@ struct boot_info {
* Failure - a value greater than MAX_NR_BOOTMODS
*/
static inline unsigned int __init next_boot_module_index(
- const struct boot_info *bi, enum bootmod_type t, unsigned int start)
+ const struct boot_info *bi, boot_module_kind k, unsigned int start)
{
unsigned int i;
- if ( t == BOOTMOD_XEN )
+ if ( k == BOOTMOD_XEN )
return bi->nr_modules;
for ( i = start; i < bi->nr_modules; i++ )
{
- if ( bi->mods[i].type == t )
+ if ( bi->mods[i].kind == k )
return i;
}
diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c
index e1b78d47c2..a4b5362357 100644
--- a/xen/arch/x86/pv/dom0_build.c
+++ b/xen/arch/x86/pv/dom0_build.c
@@ -422,7 +422,7 @@ static int __init dom0_construct(const struct boot_domain *bd)
image_base = bootstrap_map_bm(image);
image_len = image->size;
- image_start = image_base + image->headroom;
+ image_start = image_base + image->arch.headroom;
d->max_pages = ~0U;
@@ -659,7 +659,7 @@ static int __init dom0_construct(const struct boot_domain *bd)
* pages. Tell the boot_module handling that we've freed it, so the
* memory is left alone.
*/
- initrd->released = true;
+ initrd->arch.released = true;
}
iommu_memory_setup(d, "initrd", mfn_to_page(_mfn(initrd_mfn)),
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 24e4f5ac7f..7e70b46332 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -303,7 +303,7 @@ struct boot_info __initdata xen_boot_info = {
*
* The extra entry exists to be able to add the Xen image as a module.
*/
- .mods = { [0 ... MAX_NR_BOOTMODS] = { .type = BOOTMOD_UNKNOWN } },
+ .mods = { [0 ... MAX_NR_BOOTMODS] = { .kind = BOOTMOD_UNKNOWN } },
};
static struct boot_info *__init multiboot_fill_boot_info(
@@ -338,7 +338,7 @@ static struct boot_info *__init multiboot_fill_boot_info(
*/
for ( i = 0; i < MAX_NR_BOOTMODS && i < bi->nr_modules; i++ )
{
- bi->mods[i].cmdline_pa = mods[i].string;
+ bi->mods[i].arch.cmdline_pa = mods[i].string;
if ( efi_enabled(EFI_LOADER) )
{
@@ -361,7 +361,7 @@ static struct boot_info *__init multiboot_fill_boot_info(
}
/* Variable 'i' should be one entry past the last module. */
- bi->mods[i].type = BOOTMOD_XEN;
+ bi->mods[i].kind = BOOTMOD_XEN;
return bi;
}
@@ -388,11 +388,11 @@ unsigned long __init initial_images_nrpages(nodeid_t node)
void __init release_boot_module(struct boot_module *bm)
{
- ASSERT(!bm->released);
+ ASSERT(!bm->arch.released);
init_domheap_pages(bm->start, bm->start + PAGE_ALIGN(bm->size));
- bm->released = true;
+ bm->arch.released = true;
}
void __init free_boot_modules(void)
@@ -402,7 +402,7 @@ void __init free_boot_modules(void)
for ( i = 0; i < bi->nr_modules; ++i )
{
- if ( bi->mods[i].released )
+ if ( bi->mods[i].arch.released )
continue;
release_boot_module(&bi->mods[i]);
@@ -997,8 +997,8 @@ static size_t __init domain_cmdline_size(const struct boot_info *bi,
{
size_t s = 0;
- if ( bd->kernel->cmdline_pa )
- s += strlen(__va(bd->kernel->cmdline_pa));
+ if ( bd->kernel->arch.cmdline_pa )
+ s += strlen(__va(bd->kernel->arch.cmdline_pa));
if ( bi->kextra )
s += strlen(bi->kextra);
@@ -1065,9 +1065,10 @@ static struct domain *__init create_dom0(struct boot_info *bi)
if ( !(cmdline = xzalloc_array(char, cmdline_size)) )
panic("Error allocating cmdline buffer for %pd\n", d);
- if ( bd->kernel->cmdline_pa )
+ if ( bd->kernel->arch.cmdline_pa )
strlcpy(cmdline,
- cmdline_cook(__va(bd->kernel->cmdline_pa), bi->loader),
+ cmdline_cook(__va(bd->kernel->arch.cmdline_pa),
+ bi->loader),
cmdline_size);
if ( bi->kextra )
@@ -1089,7 +1090,7 @@ static struct domain *__init create_dom0(struct boot_info *bi)
strlcat(cmdline, " acpi=", cmdline_size);
strlcat(cmdline, acpi_param, cmdline_size);
}
- bd->kernel->cmdline_pa = 0;
+ bd->kernel->arch.cmdline_pa = 0;
bd->cmdline = cmdline;
}
@@ -1302,7 +1303,7 @@ void asmlinkage __init noreturn __start_xen(void)
}
/* Dom0 kernel is always first */
- bi->mods[0].type = BOOTMOD_KERNEL;
+ bi->mods[0].kind = BOOTMOD_KERNEL;
bi->domains[0].kernel = &bi->mods[0];
if ( pvh_boot )
@@ -1486,7 +1487,7 @@ void asmlinkage __init noreturn __start_xen(void)
xen->size = __2M_rwdata_end - _stext;
}
- bi->mods[0].headroom =
+ bi->mods[0].arch.headroom =
bzimage_headroom(bootstrap_map_bm(&bi->mods[0]), bi->mods[0].size);
bootstrap_unmap();
@@ -1568,9 +1569,9 @@ void asmlinkage __init noreturn __start_xen(void)
for ( j = bi->nr_modules - 1; j >= 0; j-- )
{
struct boot_module *bm = &bi->mods[j];
- unsigned long size = PAGE_ALIGN(bm->headroom + bm->size);
+ unsigned long size = PAGE_ALIGN(bm->arch.headroom + bm->size);
- if ( bm->relocated )
+ if ( bm->arch.relocated )
continue;
/* Don't overlap with other modules (or Xen itself). */
@@ -1580,12 +1581,12 @@ void asmlinkage __init noreturn __start_xen(void)
if ( highmem_start && end > highmem_start )
continue;
- if ( s < end && (bm->headroom || (end - size) > bm->start) )
+ if ( s < end && (bm->arch.headroom || (end - size) > bm->start) )
{
- move_memory(end - size + bm->headroom, bm->start, bm->size);
+ move_memory(end - size + bm->arch.headroom, bm->start, bm->size);
bm->start = (end - size);
- bm->size += bm->headroom;
- bm->relocated = true;
+ bm->size += bm->arch.headroom;
+ bm->arch.relocated = true;
}
}
@@ -1611,7 +1612,7 @@ void asmlinkage __init noreturn __start_xen(void)
#endif
}
- if ( bi->mods[0].headroom && !bi->mods[0].relocated )
+ if ( bi->mods[0].arch.headroom && !bi->mods[0].arch.relocated )
panic("Not enough memory to relocate the dom0 kernel image\n");
for ( i = 0; i < bi->nr_modules; ++i )
{
@@ -2169,7 +2170,7 @@ void asmlinkage __init noreturn __start_xen(void)
initrdidx = first_boot_module_index(bi, BOOTMOD_UNKNOWN);
if ( initrdidx < MAX_NR_BOOTMODS )
{
- bi->mods[initrdidx].type = BOOTMOD_RAMDISK;
+ bi->mods[initrdidx].kind = BOOTMOD_RAMDISK;
bi->domains[0].module = &bi->mods[initrdidx];
if ( first_boot_module_index(bi, BOOTMOD_UNKNOWN) < MAX_NR_BOOTMODS )
printk(XENLOG_WARNING
diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h
index 236b456dd2..854e7f1ed9 100644
--- a/xen/include/xen/bootfdt.h
+++ b/xen/include/xen/bootfdt.h
@@ -7,6 +7,10 @@
#include <xen/macros.h>
#include <xen/xmalloc.h>
+#if __has_include(<asm/bootfdt.h>)
+#include <asm/bootfdt.h>
+#endif
+
#define MIN_FDT_ALIGN 8
#define NR_MEM_BANKS 256
@@ -108,6 +112,10 @@ struct boot_module {
bool domU;
paddr_t start;
paddr_t size;
+
+#if __has_include(<asm/bootfdt.h>)
+ struct arch_boot_module arch;
+#endif
};
/* DT_MAX_NAME is the node name max length according the DT spec */
diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c
index 1f88b4fc5a..1b4030edb4 100644
--- a/xen/xsm/xsm_policy.c
+++ b/xen/xsm/xsm_policy.c
@@ -53,7 +53,7 @@ int __init xsm_multiboot_policy_init(
printk("Policy len %#lx, start at %p.\n",
_policy_len,_policy_start);
- bm->type = BOOTMOD_XSM_POLICY;
+ bm->kind = BOOTMOD_XSM;
break;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [PATCH v5 01/10] x86: Replace arch-specific boot_module with common one
2025-07-01 10:56 ` [PATCH v5 01/10] x86: Replace arch-specific boot_module with common one Alejandro Vallejo
@ 2025-07-02 12:43 ` Jan Beulich
2025-07-02 15:02 ` Alejandro Vallejo
0 siblings, 1 reply; 28+ messages in thread
From: Jan Beulich @ 2025-07-02 12:43 UTC (permalink / raw)
To: Alejandro Vallejo
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Bertrand Marquis, Michal Orzel, Daniel P. Smith,
xen-devel
On 01.07.2025 12:56, Alejandro Vallejo wrote:
> These types resemble each other very closely in layout and intent,
> and with "struct boot_module" already in common code it makes perfect
> sense to merge them. In order to do so, add an arch-specific area for
> x86-specific tidbits, and rename identical fields with conflicting
> names.
>
> No functional change intended.
>
> Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
I'm largely okay with this change, just one question:
> --- a/xen/include/xen/bootfdt.h
> +++ b/xen/include/xen/bootfdt.h
> @@ -7,6 +7,10 @@
> #include <xen/macros.h>
> #include <xen/xmalloc.h>
>
> +#if __has_include(<asm/bootfdt.h>)
> +#include <asm/bootfdt.h>
> +#endif
> +
> #define MIN_FDT_ALIGN 8
>
> #define NR_MEM_BANKS 256
> @@ -108,6 +112,10 @@ struct boot_module {
> bool domU;
> paddr_t start;
> paddr_t size;
> +
> +#if __has_include(<asm/bootfdt.h>)
> + struct arch_boot_module arch;
> +#endif
> };
The pre-existing domU field isn't used by x86. Shouldn't that move into Arm's
(to be created) struct arch_boot_module? Or is that intended to become
dependent upon CONFIG_DOM0LESS_BOOT? (While we apparently didn't adopt Misra
rule 2.2, this is imo precisely the situation where we would better follow it:
An unused struct field raises questions.)
Jan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 01/10] x86: Replace arch-specific boot_module with common one
2025-07-02 12:43 ` Jan Beulich
@ 2025-07-02 15:02 ` Alejandro Vallejo
0 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-02 15:02 UTC (permalink / raw)
To: Jan Beulich
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Bertrand Marquis, Michal Orzel, Daniel P. Smith,
xen-devel
On Wed Jul 2, 2025 at 2:43 PM CEST, Jan Beulich wrote:
> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>> These types resemble each other very closely in layout and intent,
>> and with "struct boot_module" already in common code it makes perfect
>> sense to merge them. In order to do so, add an arch-specific area for
>> x86-specific tidbits, and rename identical fields with conflicting
>> names.
>>
>> No functional change intended.
>>
>> Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>
> I'm largely okay with this change, just one question:
>
>> --- a/xen/include/xen/bootfdt.h
>> +++ b/xen/include/xen/bootfdt.h
>> @@ -7,6 +7,10 @@
>> #include <xen/macros.h>
>> #include <xen/xmalloc.h>
>>
>> +#if __has_include(<asm/bootfdt.h>)
>> +#include <asm/bootfdt.h>
>> +#endif
>> +
>> #define MIN_FDT_ALIGN 8
>>
>> #define NR_MEM_BANKS 256
>> @@ -108,6 +112,10 @@ struct boot_module {
>> bool domU;
>> paddr_t start;
>> paddr_t size;
>> +
>> +#if __has_include(<asm/bootfdt.h>)
>> + struct arch_boot_module arch;
>> +#endif
>> };
>
> The pre-existing domU field isn't used by x86. Shouldn't that move into Arm's
> (to be created) struct arch_boot_module? Or is that intended to become
> dependent upon CONFIG_DOM0LESS_BOOT? (While we apparently didn't adopt Misra
> rule 2.2, this is imo precisely the situation where we would better follow it:
> An unused struct field raises questions.)
That can be moved to an arch-specific header, yes.
I expect that domU field to eventually drop after dom0less adopts the
more powerful hyperlaunch bindings for privilege separation. At that point
it doesn't matter whether a domain is a domU or not, it's jut a domain to be
constructed.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v5 02/10] xen: Refactor kernel_info to have a header like boot_domain
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
2025-07-01 10:56 ` [PATCH v5 01/10] x86: Replace arch-specific boot_module with common one Alejandro Vallejo
@ 2025-07-01 10:56 ` Alejandro Vallejo
2025-07-02 12:56 ` Jan Beulich
2025-07-01 10:56 ` [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one Alejandro Vallejo
` (7 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:56 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
Anthony PERARD, Jan Beulich, Roger Pau Monné
Create a struct header within kernel_info with the contents common to
kernel_info and boot_domain, and define that header in common code. This enables
x86 to use that header as-is and drop x86's boot_domain.
Not a functional change.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
xen/arch/arm/dom0less-build.c | 8 ++++----
xen/arch/arm/domain_build.c | 20 ++++++++++----------
xen/arch/arm/kernel.c | 8 ++++----
xen/common/device-tree/dom0less-build.c | 18 +++++++++---------
xen/common/device-tree/domain-build.c | 20 ++++++++++----------
xen/common/device-tree/kernel.c | 20 ++++++++++----------
xen/include/xen/bootfdt.h | 10 ++++++++++
xen/include/xen/fdt-kernel.h | 5 ++---
8 files changed, 59 insertions(+), 50 deletions(-)
diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
index 4b285cff5e..08e8424030 100644
--- a/xen/arch/arm/dom0less-build.c
+++ b/xen/arch/arm/dom0less-build.c
@@ -32,7 +32,7 @@ static int __init make_gicv2_domU_node(struct kernel_info *kinfo)
int res = 0;
__be32 reg[(GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS) * 2];
__be32 *cells;
- const struct domain *d = kinfo->d;
+ const struct domain *d = kinfo->hdr.d;
res = domain_fdt_begin_node(fdt, "interrupt-controller",
vgic_dist_base(&d->arch.vgic));
@@ -85,7 +85,7 @@ static int __init make_gicv3_domU_node(struct kernel_info *kinfo)
void *fdt = kinfo->fdt;
int res = 0;
__be32 *reg, *cells;
- const struct domain *d = kinfo->d;
+ const struct domain *d = kinfo->hdr.d;
unsigned int i, len = 0;
res = domain_fdt_begin_node(fdt, "interrupt-controller",
@@ -152,7 +152,7 @@ static int __init make_gicv3_domU_node(struct kernel_info *kinfo)
int __init make_intc_domU_node(struct kernel_info *kinfo)
{
- switch ( kinfo->d->arch.vgic.version )
+ switch ( kinfo->hdr.d->arch.vgic.version )
{
#ifdef CONFIG_GICV3
case GIC_V3:
@@ -175,7 +175,7 @@ static int __init make_vpl011_uart_node(struct kernel_info *kinfo)
gic_interrupt_t intr;
__be32 reg[GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS];
__be32 *cells;
- struct domain *d = kinfo->d;
+ struct domain *d = kinfo->hdr.d;
res = domain_fdt_begin_node(fdt, "sbsa-uart", d->arch.vpl011.base_addr);
if ( res )
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 3f5c7c2e5a..fb577f816f 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -464,8 +464,8 @@ static int __init write_properties(struct domain *d, struct kernel_info *kinfo,
int had_dom0_bootargs = 0;
struct dt_device_node *iommu_node;
- if ( kinfo->cmdline && kinfo->cmdline[0] )
- bootargs = &kinfo->cmdline[0];
+ if ( kinfo->hdr.cmdline && kinfo->hdr.cmdline[0] )
+ bootargs = &kinfo->hdr.cmdline[0];
/*
* We always skip the IOMMU device when creating DT for hwdom if there is
@@ -579,7 +579,7 @@ static int __init write_properties(struct domain *d, struct kernel_info *kinfo,
if ( dt_node_path_is_equal(node, "/chosen") )
{
- const struct boot_module *initrd = kinfo->initrd;
+ const struct boot_module *initrd = kinfo->hdr.initrd;
if ( bootargs )
{
@@ -1456,7 +1456,7 @@ int __init make_timer_node(const struct kernel_info *kinfo)
if ( res )
return res;
- if ( !is_64bit_domain(kinfo->d) )
+ if ( !is_64bit_domain(kinfo->hdr.d) )
res = fdt_property_string(fdt, "compatible", "arm,armv7-timer");
else
res = fdt_property_string(fdt, "compatible", "arm,armv8-timer");
@@ -1468,7 +1468,7 @@ int __init make_timer_node(const struct kernel_info *kinfo)
* It always exposes an active-low level-sensitive interrupt.
*/
- if ( is_hardware_domain(kinfo->d) )
+ if ( is_hardware_domain(kinfo->hdr.d) )
{
irq[TIMER_PHYS_SECURE_PPI] = timer_get_irq(TIMER_PHYS_SECURE_PPI);
irq[TIMER_PHYS_NONSECURE_PPI] =
@@ -1517,7 +1517,7 @@ int __init make_chosen_node(const struct kernel_info *kinfo)
{
int res;
const char *bootargs = NULL;
- const struct boot_module *initrd = kinfo->initrd;
+ const struct boot_module *initrd = kinfo->hdr.initrd;
void *fdt = kinfo->fdt;
dt_dprintk("Create chosen node\n");
@@ -1525,9 +1525,9 @@ int __init make_chosen_node(const struct kernel_info *kinfo)
if ( res )
return res;
- if ( kinfo->cmdline && kinfo->cmdline[0] )
+ if ( kinfo->hdr.cmdline && kinfo->hdr.cmdline[0] )
{
- bootargs = &kinfo->cmdline[0];
+ bootargs = &kinfo->hdr.cmdline[0];
res = fdt_property(fdt, "bootargs", bootargs, strlen(bootargs) + 1);
if ( res )
return res;
@@ -1976,7 +1976,7 @@ static int __init construct_dom0(struct domain *d)
d->max_pages = dom0_mem >> PAGE_SHIFT;
kinfo.unassigned_mem = dom0_mem;
- kinfo.d = d;
+ kinfo.hdr.d = d;
rc = kernel_probe(&kinfo, NULL);
if ( rc < 0 )
@@ -1988,7 +1988,7 @@ static int __init construct_dom0(struct domain *d)
int __init construct_hwdom(struct kernel_info *kinfo,
const struct dt_device_node *node)
{
- struct domain *d = kinfo->d;
+ struct domain *d = kinfo->hdr.d;
int rc;
iommu_hwdom_init(d);
diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
index e734ec5c1e..10e5dcad5e 100644
--- a/xen/arch/arm/kernel.c
+++ b/xen/arch/arm/kernel.c
@@ -46,7 +46,7 @@ static void __init place_modules(struct kernel_info *info,
paddr_t kernbase, paddr_t kernend)
{
/* Align DTB and initrd size to 2Mb. Linux only requires 4 byte alignment */
- const struct boot_module *mod = info->initrd;
+ const struct boot_module *mod = info->hdr.initrd;
const struct membanks *mem = kernel_info_get_mem(info);
const paddr_t initrd_len = ROUNDUP(mod ? mod->size : 0, MB(2));
const paddr_t dtb_len = ROUNDUP(fdt_totalsize(info->fdt), MB(2));
@@ -152,12 +152,12 @@ static void __init kernel_zimage_load(struct kernel_info *info)
kernel = ioremap_wc(paddr, len);
if ( !kernel )
- panic("Unable to map the %pd kernel\n", info->d);
+ panic("Unable to map the %pd kernel\n", info->hdr.d);
- rc = copy_to_guest_phys_flush_dcache(info->d, load_addr,
+ rc = copy_to_guest_phys_flush_dcache(info->hdr.d, load_addr,
kernel, len);
if ( rc != 0 )
- panic("Unable to copy the kernel in the %pd memory\n", info->d);
+ panic("Unable to copy the kernel in the %pd memory\n", info->hdr.d);
iounmap(kernel);
}
diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tree/dom0less-build.c
index 221b875a2f..e321747175 100644
--- a/xen/common/device-tree/dom0less-build.c
+++ b/xen/common/device-tree/dom0less-build.c
@@ -167,18 +167,18 @@ static int __init handle_passthrough_prop(struct kernel_info *kinfo,
return -EINVAL;
}
- res = iomem_permit_access(kinfo->d, paddr_to_pfn(mstart),
+ res = iomem_permit_access(kinfo->hdr.d, paddr_to_pfn(mstart),
paddr_to_pfn(PAGE_ALIGN(mstart + size - 1)));
if ( res )
{
printk(XENLOG_ERR "Unable to permit to dom%d access to"
" 0x%"PRIpaddr" - 0x%"PRIpaddr"\n",
- kinfo->d->domain_id,
+ kinfo->hdr.d->domain_id,
mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 1);
return res;
}
- res = map_regions_p2mt(kinfo->d,
+ res = map_regions_p2mt(kinfo->hdr.d,
gaddr_to_gfn(gstart),
PFN_DOWN(size),
maddr_to_mfn(mstart),
@@ -217,7 +217,7 @@ static int __init handle_passthrough_prop(struct kernel_info *kinfo,
return -EINVAL;
}
- res = map_device_irqs_to_domain(kinfo->d, node, true, NULL);
+ res = map_device_irqs_to_domain(kinfo->hdr.d, node, true, NULL);
if ( res < 0 )
return res;
@@ -229,7 +229,7 @@ static int __init handle_passthrough_prop(struct kernel_info *kinfo,
if ( xen_force && !dt_device_is_protected(node) )
return 0;
- return iommu_assign_dt_device(kinfo->d, node);
+ return iommu_assign_dt_device(kinfo->hdr.d, node);
}
static int __init handle_prop_pfdt(struct kernel_info *kinfo,
@@ -296,14 +296,14 @@ static int __init handle_prop_pfdt(struct kernel_info *kinfo,
address_cells, size_cells);
if ( res < 0 )
{
- printk(XENLOG_ERR "Failed to assign device to %pd\n", kinfo->d);
+ printk(XENLOG_ERR "Failed to assign device to %pd\n", kinfo->hdr.d);
return res;
}
}
else if ( (xen_path && !xen_reg) || (xen_reg && !xen_path && !xen_force) )
{
printk(XENLOG_ERR "xen,reg or xen,path missing for %pd\n",
- kinfo->d);
+ kinfo->hdr.d);
return -EINVAL;
}
@@ -605,7 +605,7 @@ static int __init alloc_xenstore_page(struct domain *d)
static int __init alloc_xenstore_params(struct kernel_info *kinfo)
{
- struct domain *d = kinfo->d;
+ struct domain *d = kinfo->hdr.d;
int rc = 0;
#ifdef CONFIG_HVM
@@ -773,7 +773,7 @@ static int __init construct_domU(struct domain *d,
d->max_pages = ((paddr_t)mem * SZ_1K) >> PAGE_SHIFT;
- kinfo.d = d;
+ kinfo.hdr.d = d;
rc = kernel_probe(&kinfo, node);
if ( rc < 0 )
diff --git a/xen/common/device-tree/domain-build.c b/xen/common/device-tree/domain-build.c
index cd01a8b4bc..51182d10ef 100644
--- a/xen/common/device-tree/domain-build.c
+++ b/xen/common/device-tree/domain-build.c
@@ -76,7 +76,7 @@ bool __init allocate_bank_memory(struct kernel_info *kinfo, gfn_t sgfn,
paddr_t tot_size)
{
struct membanks *mem = kernel_info_get_mem(kinfo);
- struct domain *d = kinfo->d;
+ struct domain *d = kinfo->hdr.d;
struct membank *bank;
/*
@@ -170,7 +170,7 @@ int __init find_unallocated_memory(const struct kernel_info *kinfo,
unsigned int i, j;
int res;
- ASSERT(domain_use_host_layout(kinfo->d));
+ ASSERT(domain_use_host_layout(kinfo->hdr.d));
unalloc_mem = rangeset_new(NULL, NULL, 0);
if ( !unalloc_mem )
@@ -336,23 +336,23 @@ void __init dtb_load(struct kernel_info *kinfo,
unsigned long left;
printk("Loading %pd DTB to 0x%"PRIpaddr"-0x%"PRIpaddr"\n",
- kinfo->d, kinfo->dtb_paddr,
+ kinfo->hdr.d, kinfo->dtb_paddr,
kinfo->dtb_paddr + fdt_totalsize(kinfo->fdt));
- left = copy_to_guest(kinfo->d, kinfo->dtb_paddr,
+ left = copy_to_guest(kinfo->hdr.d, kinfo->dtb_paddr,
kinfo->fdt,
fdt_totalsize(kinfo->fdt));
if ( left != 0 )
panic("Unable to copy the DTB to %pd memory (left = %lu bytes)\n",
- kinfo->d, left);
+ kinfo->hdr.d, left);
xfree(kinfo->fdt);
}
void __init initrd_load(struct kernel_info *kinfo,
copy_to_guest_phys_cb copy_to_guest)
{
- const struct boot_module *mod = kinfo->initrd;
+ const struct boot_module *mod = kinfo->hdr.initrd;
paddr_t load_addr = kinfo->initrd_paddr;
paddr_t paddr, len;
int node;
@@ -368,7 +368,7 @@ void __init initrd_load(struct kernel_info *kinfo,
len = mod->size;
printk("Loading %pd initrd from %"PRIpaddr" to 0x%"PRIpaddr"-0x%"PRIpaddr"\n",
- kinfo->d, paddr, load_addr, load_addr + len);
+ kinfo->hdr.d, paddr, load_addr, load_addr + len);
/* Fix up linux,initrd-start and linux,initrd-end in /chosen */
node = fdt_path_offset(kinfo->fdt, "/chosen");
@@ -391,12 +391,12 @@ void __init initrd_load(struct kernel_info *kinfo,
initrd = ioremap_wc(paddr, len);
if ( !initrd )
- panic("Unable to map the %pd initrd\n", kinfo->d);
+ panic("Unable to map the %pd initrd\n", kinfo->hdr.d);
- res = copy_to_guest(kinfo->d, load_addr,
+ res = copy_to_guest(kinfo->hdr.d, load_addr,
initrd, len);
if ( res != 0 )
- panic("Unable to copy the initrd in the %pd memory\n", kinfo->d);
+ panic("Unable to copy the initrd in the %pd memory\n", kinfo->hdr.d);
iounmap(initrd);
}
diff --git a/xen/common/device-tree/kernel.c b/xen/common/device-tree/kernel.c
index e1b22dc1c7..7a00768e6b 100644
--- a/xen/common/device-tree/kernel.c
+++ b/xen/common/device-tree/kernel.c
@@ -136,16 +136,16 @@ int __init kernel_probe(struct kernel_info *info,
/* domain is NULL only for the hardware domain */
if ( domain == NULL )
{
- ASSERT(is_hardware_domain(info->d));
+ ASSERT(is_hardware_domain(info->hdr.d));
mod = boot_module_find_by_kind(BOOTMOD_KERNEL);
- info->kernel = mod;
- info->initrd = boot_module_find_by_kind(BOOTMOD_RAMDISK);
+ info->hdr.kernel = mod;
+ info->hdr.initrd = boot_module_find_by_kind(BOOTMOD_RAMDISK);
cmd = boot_cmdline_find_by_kind(BOOTMOD_KERNEL);
if ( cmd )
- info->cmdline = &cmd->cmdline[0];
+ info->hdr.cmdline = &cmd->cmdline[0];
}
else
{
@@ -162,7 +162,7 @@ int __init kernel_probe(struct kernel_info *info,
dt_get_range(&val, node, &kernel_addr, &size);
mod = boot_module_find_by_addr_and_kind(
BOOTMOD_KERNEL, kernel_addr);
- info->kernel = mod;
+ info->hdr.kernel = mod;
}
else if ( dt_device_is_compatible(node, "multiboot,ramdisk") )
{
@@ -171,7 +171,7 @@ int __init kernel_probe(struct kernel_info *info,
val = dt_get_property(node, "reg", &len);
dt_get_range(&val, node, &initrd_addr, &size);
- info->initrd = boot_module_find_by_addr_and_kind(
+ info->hdr.initrd = boot_module_find_by_addr_and_kind(
BOOTMOD_RAMDISK, initrd_addr);
}
else if ( dt_device_is_compatible(node, "multiboot,device-tree") )
@@ -192,7 +192,7 @@ int __init kernel_probe(struct kernel_info *info,
name = dt_node_name(domain);
cmd = boot_cmdline_find_by_name(name);
if ( cmd )
- info->cmdline = &cmd->cmdline[0];
+ info->hdr.cmdline = &cmd->cmdline[0];
}
if ( !mod || !mod->size )
{
@@ -201,10 +201,10 @@ int __init kernel_probe(struct kernel_info *info,
}
printk("Loading %pd kernel from boot module @ %"PRIpaddr"\n",
- info->d, info->kernel->start);
- if ( info->initrd )
+ info->hdr.d, info->hdr.kernel->start);
+ if ( info->hdr.initrd )
printk("Loading ramdisk from boot module @ %"PRIpaddr"\n",
- info->initrd->start);
+ info->hdr.initrd->start);
/*
* uImage isn't really used nowadays thereby leave kernel_uimage_probe()
diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h
index 854e7f1ed9..be0abe30ef 100644
--- a/xen/include/xen/bootfdt.h
+++ b/xen/include/xen/bootfdt.h
@@ -100,6 +100,16 @@ struct shared_meminfo {
struct shmem_membank_extra extra[NR_SHMEM_BANKS];
};
+
+struct boot_domain {
+ struct domain *d;
+
+ struct boot_module *kernel;
+ struct boot_module *initrd;
+
+ const char* cmdline;
+};
+
/*
* The domU flag is set for kernels and ramdisks of "xen,domain" nodes.
* The purpose of the domU flag is to avoid getting confused in
diff --git a/xen/include/xen/fdt-kernel.h b/xen/include/xen/fdt-kernel.h
index 12a0b42d17..fee8eac1db 100644
--- a/xen/include/xen/fdt-kernel.h
+++ b/xen/include/xen/fdt-kernel.h
@@ -16,7 +16,7 @@
#endif
struct kernel_info {
- struct domain *d;
+ struct boot_domain hdr;
void *fdt; /* flat device tree */
paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */
@@ -34,8 +34,7 @@ struct kernel_info {
paddr_t gnttab_size;
/* boot blob load addresses */
- const struct boot_module *kernel, *initrd, *dtb;
- const char* cmdline;
+ const struct boot_module *dtb;
paddr_t dtb_paddr;
paddr_t initrd_paddr;
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [PATCH v5 02/10] xen: Refactor kernel_info to have a header like boot_domain
2025-07-01 10:56 ` [PATCH v5 02/10] xen: Refactor kernel_info to have a header like boot_domain Alejandro Vallejo
@ 2025-07-02 12:56 ` Jan Beulich
2025-07-02 16:04 ` Alejandro Vallejo
0 siblings, 1 reply; 28+ messages in thread
From: Jan Beulich @ 2025-07-02 12:56 UTC (permalink / raw)
To: Alejandro Vallejo
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
Volodymyr Babchuk, Andrew Cooper, Anthony PERARD,
Roger Pau Monné, xen-devel
On 01.07.2025 12:56, Alejandro Vallejo wrote:
> --- a/xen/include/xen/bootfdt.h
> +++ b/xen/include/xen/bootfdt.h
> @@ -100,6 +100,16 @@ struct shared_meminfo {
> struct shmem_membank_extra extra[NR_SHMEM_BANKS];
> };
>
> +
Nit: No double blank lines please.
> +struct boot_domain {
> + struct domain *d;
> +
> + struct boot_module *kernel;
> + struct boot_module *initrd;
> +
> + const char* cmdline;
Nit: * and blank want to change places.
> --- a/xen/include/xen/fdt-kernel.h
> +++ b/xen/include/xen/fdt-kernel.h
> @@ -16,7 +16,7 @@
> #endif
>
> struct kernel_info {
> - struct domain *d;
> + struct boot_domain hdr;
>
> void *fdt; /* flat device tree */
> paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */
> @@ -34,8 +34,7 @@ struct kernel_info {
> paddr_t gnttab_size;
>
> /* boot blob load addresses */
> - const struct boot_module *kernel, *initrd, *dtb;
Where did this "const" go?
> - const char* cmdline;
> + const struct boot_module *dtb;
This one only retains the intended effect here.
> paddr_t dtb_paddr;
> paddr_t initrd_paddr;
"hdr" is an odd name here. That struct has no need to live at the beginning,
afaict. How about "gen" for "generic" or "bd" for "boot_domain"?
Jan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 02/10] xen: Refactor kernel_info to have a header like boot_domain
2025-07-02 12:56 ` Jan Beulich
@ 2025-07-02 16:04 ` Alejandro Vallejo
2025-07-03 6:01 ` Jan Beulich
0 siblings, 1 reply; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-02 16:04 UTC (permalink / raw)
To: Jan Beulich, Alejandro Vallejo
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
Volodymyr Babchuk, Andrew Cooper, Anthony PERARD,
Roger Pau Monné, xen-devel
On Wed Jul 2, 2025 at 2:56 PM CEST, Jan Beulich wrote:
> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>> --- a/xen/include/xen/bootfdt.h
>> +++ b/xen/include/xen/bootfdt.h
>> @@ -100,6 +100,16 @@ struct shared_meminfo {
>> struct shmem_membank_extra extra[NR_SHMEM_BANKS];
>> };
>>
>> +
>
> Nit: No double blank lines please.
>
>> +struct boot_domain {
>> + struct domain *d;
>> +
>> + struct boot_module *kernel;
>> + struct boot_module *initrd;
>> +
>> + const char* cmdline;
>
> Nit: * and blank want to change places.
>
>> --- a/xen/include/xen/fdt-kernel.h
>> +++ b/xen/include/xen/fdt-kernel.h
>> @@ -16,7 +16,7 @@
>> #endif
>>
>> struct kernel_info {
>> - struct domain *d;
>> + struct boot_domain hdr;
>>
>> void *fdt; /* flat device tree */
>> paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */
>> @@ -34,8 +34,7 @@ struct kernel_info {
>> paddr_t gnttab_size;
>>
>> /* boot blob load addresses */
>> - const struct boot_module *kernel, *initrd, *dtb;
>
> Where did this "const" go?
x86 mutates the boot module to set the released flag, the headroom, etc.
>
>> - const char* cmdline;
>> + const struct boot_module *dtb;
>
> This one only retains the intended effect here.
Because x86 doesn't see or use the containing struct.
>
>> paddr_t dtb_paddr;
>> paddr_t initrd_paddr;
>
> "hdr" is an odd name here. That struct has no need to live at the beginning,
> afaict. How about "gen" for "generic" or "bd" for "boot_domain"?
>
> Jan
Sure. I'm fine with `bd`. Will adjust.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 02/10] xen: Refactor kernel_info to have a header like boot_domain
2025-07-02 16:04 ` Alejandro Vallejo
@ 2025-07-03 6:01 ` Jan Beulich
2025-07-03 9:57 ` Alejandro Vallejo
0 siblings, 1 reply; 28+ messages in thread
From: Jan Beulich @ 2025-07-03 6:01 UTC (permalink / raw)
To: Alejandro Vallejo, Alejandro Vallejo
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
Volodymyr Babchuk, Andrew Cooper, Anthony PERARD,
Roger Pau Monné, xen-devel
On 02.07.2025 18:04, Alejandro Vallejo wrote:
> On Wed Jul 2, 2025 at 2:56 PM CEST, Jan Beulich wrote:
>> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>>> --- a/xen/include/xen/fdt-kernel.h
>>> +++ b/xen/include/xen/fdt-kernel.h
>>> @@ -16,7 +16,7 @@
>>> #endif
>>>
>>> struct kernel_info {
>>> - struct domain *d;
>>> + struct boot_domain hdr;
>>>
>>> void *fdt; /* flat device tree */
>>> paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */
>>> @@ -34,8 +34,7 @@ struct kernel_info {
>>> paddr_t gnttab_size;
>>>
>>> /* boot blob load addresses */
>>> - const struct boot_module *kernel, *initrd, *dtb;
>>
>> Where did this "const" go?
>
> x86 mutates the boot module to set the released flag, the headroom, etc.
Might be nice to mention such an aspect in the description.
Jan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 02/10] xen: Refactor kernel_info to have a header like boot_domain
2025-07-03 6:01 ` Jan Beulich
@ 2025-07-03 9:57 ` Alejandro Vallejo
0 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-03 9:57 UTC (permalink / raw)
To: Jan Beulich, Alejandro Vallejo
Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
Volodymyr Babchuk, Andrew Cooper, Anthony PERARD,
Roger Pau Monné, xen-devel
On Thu Jul 3, 2025 at 8:01 AM CEST, Jan Beulich wrote:
> On 02.07.2025 18:04, Alejandro Vallejo wrote:
>> On Wed Jul 2, 2025 at 2:56 PM CEST, Jan Beulich wrote:
>>> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>>>> --- a/xen/include/xen/fdt-kernel.h
>>>> +++ b/xen/include/xen/fdt-kernel.h
>>>> @@ -16,7 +16,7 @@
>>>> #endif
>>>>
>>>> struct kernel_info {
>>>> - struct domain *d;
>>>> + struct boot_domain hdr;
>>>>
>>>> void *fdt; /* flat device tree */
>>>> paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */
>>>> @@ -34,8 +34,7 @@ struct kernel_info {
>>>> paddr_t gnttab_size;
>>>>
>>>> /* boot blob load addresses */
>>>> - const struct boot_module *kernel, *initrd, *dtb;
>>>
>>> Where did this "const" go?
>>
>> x86 mutates the boot module to set the released flag, the headroom, etc.
>
> Might be nice to mention such an aspect in the description.
>
> Jan
Sure.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
2025-07-01 10:56 ` [PATCH v5 01/10] x86: Replace arch-specific boot_module with common one Alejandro Vallejo
2025-07-01 10:56 ` [PATCH v5 02/10] xen: Refactor kernel_info to have a header like boot_domain Alejandro Vallejo
@ 2025-07-01 10:56 ` Alejandro Vallejo
2025-07-02 13:15 ` Jan Beulich
2025-07-01 10:56 ` [PATCH v5 04/10] xen/dt: Move bootfdt functions to xen/bootfdt.h Alejandro Vallejo
` (6 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:56 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Jan Beulich, Andrew Cooper,
Roger Pau Monné, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel
Add the single arch-specific field in an "arch" subfield defined in
asm/bootfdt.h.
No functional change intended.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
xen/arch/x86/hvm/dom0_build.c | 2 +-
xen/arch/x86/include/asm/boot-domain.h | 33 --------------------------
xen/arch/x86/include/asm/bootfdt.h | 6 +++++
xen/arch/x86/include/asm/bootinfo.h | 1 -
xen/arch/x86/pv/dom0_build.c | 2 +-
xen/arch/x86/setup.c | 12 ++++++----
xen/include/xen/bootfdt.h | 4 ++++
7 files changed, 19 insertions(+), 41 deletions(-)
delete mode 100644 xen/arch/x86/include/asm/boot-domain.h
diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c
index 2bb8ef355c..8d2734f2b5 100644
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -648,7 +648,7 @@ static int __init pvh_load_kernel(
{
struct domain *d = bd->d;
struct boot_module *image = bd->kernel;
- struct boot_module *initrd = bd->module;
+ struct boot_module *initrd = bd->initrd;
void *image_base = bootstrap_map_bm(image);
void *image_start = image_base + image->arch.headroom;
unsigned long image_len = image->size;
diff --git a/xen/arch/x86/include/asm/boot-domain.h b/xen/arch/x86/include/asm/boot-domain.h
deleted file mode 100644
index d7c6042e25..0000000000
--- a/xen/arch/x86/include/asm/boot-domain.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (c) 2024 Apertus Solutions, LLC
- * Author: Daniel P. Smith <dpsmith@apertussolutions.com>
- * Copyright (c) 2024 Christopher Clark <christopher.w.clark@gmail.com>
- */
-
-#ifndef __XEN_X86_BOOTDOMAIN_H__
-#define __XEN_X86_BOOTDOMAIN_H__
-
-#include <public/xen.h>
-
-struct boot_domain {
- domid_t domid;
-
- struct boot_module *kernel;
- struct boot_module *module;
- const char *cmdline;
-
- struct domain *d;
-};
-
-#endif
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/xen/arch/x86/include/asm/bootfdt.h b/xen/arch/x86/include/asm/bootfdt.h
index a4c4bf30b9..c21dbe961b 100644
--- a/xen/arch/x86/include/asm/bootfdt.h
+++ b/xen/arch/x86/include/asm/bootfdt.h
@@ -3,6 +3,12 @@
#define X86_BOOTFDT_H
#include <xen/types.h>
+#include <public/xen.h>
+
+struct arch_boot_domain
+{
+ domid_t domid;
+};
struct arch_boot_module
{
diff --git a/xen/arch/x86/include/asm/bootinfo.h b/xen/arch/x86/include/asm/bootinfo.h
index d33b100e04..4f2cc5906e 100644
--- a/xen/arch/x86/include/asm/bootinfo.h
+++ b/xen/arch/x86/include/asm/bootinfo.h
@@ -12,7 +12,6 @@
#include <xen/init.h>
#include <xen/multiboot.h>
#include <xen/types.h>
-#include <asm/boot-domain.h>
/* Max number of boot modules a bootloader can provide in addition to Xen */
#define MAX_NR_BOOTMODS 63
diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c
index a4b5362357..c37bea9454 100644
--- a/xen/arch/x86/pv/dom0_build.c
+++ b/xen/arch/x86/pv/dom0_build.c
@@ -375,7 +375,7 @@ static int __init dom0_construct(const struct boot_domain *bd)
struct vcpu *v = d->vcpu[0];
struct boot_module *image = bd->kernel;
- struct boot_module *initrd = bd->module;
+ struct boot_module *initrd = bd->initrd;
void *image_base;
unsigned long image_len;
void *image_start;
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 7e70b46332..5adb7af930 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -297,7 +297,9 @@ static const char *cmdline_cook(const char *p, const char *loader_name);
struct boot_info __initdata xen_boot_info = {
.loader = "unknown",
.cmdline = "",
- .domains = { [0 ... MAX_NR_BOOTDOMS - 1] = { .domid = DOMID_INVALID } },
+ .domains = { [0 ... MAX_NR_BOOTDOMS - 1] = {
+ .arch.domid = DOMID_INVALID
+ }},
/*
* There's a MAX_NR_BOOTMODS-th entry in the array. It's not off by one.
*
@@ -1048,11 +1050,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
/* Create initial domain. Not d0 for pvshim. */
- bd->domid = get_initial_domain_id();
- d = domain_create(bd->domid, &dom0_cfg,
+ bd->arch.domid = get_initial_domain_id();
+ d = domain_create(bd->arch.domid, &dom0_cfg,
pv_shim ? 0 : CDF_privileged | CDF_hardware);
if ( IS_ERR(d) )
- panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
+ panic("Error creating d%u: %ld\n", bd->arch.domid, PTR_ERR(d));
init_dom0_cpuid_policy(d);
@@ -2171,7 +2173,7 @@ void asmlinkage __init noreturn __start_xen(void)
if ( initrdidx < MAX_NR_BOOTMODS )
{
bi->mods[initrdidx].kind = BOOTMOD_RAMDISK;
- bi->domains[0].module = &bi->mods[initrdidx];
+ bi->domains[0].initrd = &bi->mods[initrdidx];
if ( first_boot_module_index(bi, BOOTMOD_UNKNOWN) < MAX_NR_BOOTMODS )
printk(XENLOG_WARNING
"Multiple initrd candidates, picking module #%u\n",
diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h
index be0abe30ef..8ea52290b7 100644
--- a/xen/include/xen/bootfdt.h
+++ b/xen/include/xen/bootfdt.h
@@ -108,6 +108,10 @@ struct boot_domain {
struct boot_module *initrd;
const char* cmdline;
+
+#if __has_include(<asm/bootfdt.h>)
+ struct arch_boot_domain arch;
+#endif
};
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one
2025-07-01 10:56 ` [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one Alejandro Vallejo
@ 2025-07-02 13:15 ` Jan Beulich
2025-07-02 15:04 ` Alejandro Vallejo
2025-07-02 15:09 ` Alejandro Vallejo
0 siblings, 2 replies; 28+ messages in thread
From: Jan Beulich @ 2025-07-02 13:15 UTC (permalink / raw)
To: Alejandro Vallejo, Daniel Smith, Jason Andryuk
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Bertrand Marquis, Michal Orzel, xen-devel
On 01.07.2025 12:56, Alejandro Vallejo wrote:
> --- a/xen/arch/x86/include/asm/bootfdt.h
> +++ b/xen/arch/x86/include/asm/bootfdt.h
> @@ -3,6 +3,12 @@
> #define X86_BOOTFDT_H
>
> #include <xen/types.h>
> +#include <public/xen.h>
> +
> +struct arch_boot_domain
> +{
> + domid_t domid;
> +};
>
> struct arch_boot_module
> {
>[...]
> @@ -1048,11 +1050,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
> dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
>
> /* Create initial domain. Not d0 for pvshim. */
> - bd->domid = get_initial_domain_id();
> - d = domain_create(bd->domid, &dom0_cfg,
> + bd->arch.domid = get_initial_domain_id();
> + d = domain_create(bd->arch.domid, &dom0_cfg,
> pv_shim ? 0 : CDF_privileged | CDF_hardware);
> if ( IS_ERR(d) )
> - panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
> + panic("Error creating d%u: %ld\n", bd->arch.domid, PTR_ERR(d));
This being the only place where the (now) arch-specific field is used, why
does it exist? A local variable would do? And if it's needed for
(supposedly arch-agnostic) hyperlaunch, then it probably shouldn't be
arch-specific? Daniel, Jason?
Jan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one
2025-07-02 13:15 ` Jan Beulich
@ 2025-07-02 15:04 ` Alejandro Vallejo
2025-07-02 15:09 ` Alejandro Vallejo
1 sibling, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-02 15:04 UTC (permalink / raw)
To: Jan Beulich, Daniel Smith, Jason Andryuk
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Bertrand Marquis, Michal Orzel, xen-devel
On Wed Jul 2, 2025 at 3:15 PM CEST, Jan Beulich wrote:
> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>> --- a/xen/arch/x86/include/asm/bootfdt.h
>> +++ b/xen/arch/x86/include/asm/bootfdt.h
>> @@ -3,6 +3,12 @@
>> #define X86_BOOTFDT_H
>>
>> #include <xen/types.h>
>> +#include <public/xen.h>
>> +
>> +struct arch_boot_domain
>> +{
>> + domid_t domid;
>> +};
>>
>> struct arch_boot_module
>> {
>>[...]
>> @@ -1048,11 +1050,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
>> dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
>>
>> /* Create initial domain. Not d0 for pvshim. */
>> - bd->domid = get_initial_domain_id();
>> - d = domain_create(bd->domid, &dom0_cfg,
>> + bd->arch.domid = get_initial_domain_id();
>> + d = domain_create(bd->arch.domid, &dom0_cfg,
>> pv_shim ? 0 : CDF_privileged | CDF_hardware);
>> if ( IS_ERR(d) )
>> - panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
>> + panic("Error creating d%u: %ld\n", bd->arch.domid, PTR_ERR(d));
>
> This being the only place where the (now) arch-specific field is used, why
> does it exist? A local variable would do? And if it's needed for
> (supposedly arch-agnostic) hyperlaunch, then it probably shouldn't be
> arch-specific? Daniel, Jason?
>
> Jan
It eventually becomes a holding spot for the domid property of each domain in
the DTB. It exists so we can describe every domain fully ahead of trying to
construct it.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one
2025-07-02 13:15 ` Jan Beulich
2025-07-02 15:04 ` Alejandro Vallejo
@ 2025-07-02 15:09 ` Alejandro Vallejo
2025-07-02 15:15 ` Jan Beulich
1 sibling, 1 reply; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-02 15:09 UTC (permalink / raw)
To: Jan Beulich, Daniel Smith, Jason Andryuk
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Bertrand Marquis, Michal Orzel, xen-devel
On Wed Jul 2, 2025 at 3:15 PM CEST, Jan Beulich wrote:
> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>> --- a/xen/arch/x86/include/asm/bootfdt.h
>> +++ b/xen/arch/x86/include/asm/bootfdt.h
>> @@ -3,6 +3,12 @@
>> #define X86_BOOTFDT_H
>>
>> #include <xen/types.h>
>> +#include <public/xen.h>
>> +
>> +struct arch_boot_domain
>> +{
>> + domid_t domid;
>> +};
>>
>> struct arch_boot_module
>> {
>>[...]
>> @@ -1048,11 +1050,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
>> dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
>>
>> /* Create initial domain. Not d0 for pvshim. */
>> - bd->domid = get_initial_domain_id();
>> - d = domain_create(bd->domid, &dom0_cfg,
>> + bd->arch.domid = get_initial_domain_id();
>> + d = domain_create(bd->arch.domid, &dom0_cfg,
>> pv_shim ? 0 : CDF_privileged | CDF_hardware);
>> if ( IS_ERR(d) )
>> - panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
>> + panic("Error creating d%u: %ld\n", bd->arch.domid, PTR_ERR(d));
>
> This being the only place where the (now) arch-specific field is used, why
> does it exist? A local variable would do? And if it's needed for
> (supposedly arch-agnostic) hyperlaunch, then it probably shouldn't be
> arch-specific? Daniel, Jason?
>
> Jan
As for the arch-agnostic side of things, arm needs some extra work to be
able to do it safely. dom0less currently constructs domains immediately after
parsing them, which is problematic for cases where some domains have the prop
and others don't. The domid allocation strategy may preclude further otherwise
good domains from being created just because their domid was stolen by a domain
that didn't actually care about which domid it got.
It'll eventually want to leave the arch-specific area, but I don't want to do
that work now.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one
2025-07-02 15:09 ` Alejandro Vallejo
@ 2025-07-02 15:15 ` Jan Beulich
2025-07-02 15:34 ` Alejandro Vallejo
0 siblings, 1 reply; 28+ messages in thread
From: Jan Beulich @ 2025-07-02 15:15 UTC (permalink / raw)
To: Alejandro Vallejo
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Jason Andryuk, Bertrand Marquis, Michal Orzel,
xen-devel, Daniel Smith
On 02.07.2025 17:09, Alejandro Vallejo wrote:
> On Wed Jul 2, 2025 at 3:15 PM CEST, Jan Beulich wrote:
>> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>>> --- a/xen/arch/x86/include/asm/bootfdt.h
>>> +++ b/xen/arch/x86/include/asm/bootfdt.h
>>> @@ -3,6 +3,12 @@
>>> #define X86_BOOTFDT_H
>>>
>>> #include <xen/types.h>
>>> +#include <public/xen.h>
>>> +
>>> +struct arch_boot_domain
>>> +{
>>> + domid_t domid;
>>> +};
>>>
>>> struct arch_boot_module
>>> {
>>> [...]
>>> @@ -1048,11 +1050,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
>>> dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
>>>
>>> /* Create initial domain. Not d0 for pvshim. */
>>> - bd->domid = get_initial_domain_id();
>>> - d = domain_create(bd->domid, &dom0_cfg,
>>> + bd->arch.domid = get_initial_domain_id();
>>> + d = domain_create(bd->arch.domid, &dom0_cfg,
>>> pv_shim ? 0 : CDF_privileged | CDF_hardware);
>>> if ( IS_ERR(d) )
>>> - panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
>>> + panic("Error creating d%u: %ld\n", bd->arch.domid, PTR_ERR(d));
>>
>> This being the only place where the (now) arch-specific field is used, why
>> does it exist? A local variable would do? And if it's needed for
>> (supposedly arch-agnostic) hyperlaunch, then it probably shouldn't be
>> arch-specific? Daniel, Jason?
>
> As for the arch-agnostic side of things, arm needs some extra work to be
> able to do it safely. dom0less currently constructs domains immediately after
> parsing them, which is problematic for cases where some domains have the prop
> and others don't. The domid allocation strategy may preclude further otherwise
> good domains from being created just because their domid was stolen by a domain
> that didn't actually care about which domid it got.
>
> It'll eventually want to leave the arch-specific area, but I don't want to do
> that work now.
But if the domU field is fine to live in a common struct despite being unused
on x86, why can't the domid field live in a common struct too, despite being
unused on non-x86? Otherwise it'll be extra churn for no gain to later move it
there.
Jan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one
2025-07-02 15:15 ` Jan Beulich
@ 2025-07-02 15:34 ` Alejandro Vallejo
2025-07-03 6:04 ` Jan Beulich
0 siblings, 1 reply; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-02 15:34 UTC (permalink / raw)
To: Jan Beulich
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Jason Andryuk, Bertrand Marquis, Michal Orzel,
xen-devel, Daniel Smith
On Wed Jul 2, 2025 at 5:15 PM CEST, Jan Beulich wrote:
> On 02.07.2025 17:09, Alejandro Vallejo wrote:
>> On Wed Jul 2, 2025 at 3:15 PM CEST, Jan Beulich wrote:
>>> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>>>> --- a/xen/arch/x86/include/asm/bootfdt.h
>>>> +++ b/xen/arch/x86/include/asm/bootfdt.h
>>>> @@ -3,6 +3,12 @@
>>>> #define X86_BOOTFDT_H
>>>>
>>>> #include <xen/types.h>
>>>> +#include <public/xen.h>
>>>> +
>>>> +struct arch_boot_domain
>>>> +{
>>>> + domid_t domid;
>>>> +};
>>>>
>>>> struct arch_boot_module
>>>> {
>>>> [...]
>>>> @@ -1048,11 +1050,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
>>>> dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
>>>>
>>>> /* Create initial domain. Not d0 for pvshim. */
>>>> - bd->domid = get_initial_domain_id();
>>>> - d = domain_create(bd->domid, &dom0_cfg,
>>>> + bd->arch.domid = get_initial_domain_id();
>>>> + d = domain_create(bd->arch.domid, &dom0_cfg,
>>>> pv_shim ? 0 : CDF_privileged | CDF_hardware);
>>>> if ( IS_ERR(d) )
>>>> - panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
>>>> + panic("Error creating d%u: %ld\n", bd->arch.domid, PTR_ERR(d));
>>>
>>> This being the only place where the (now) arch-specific field is used, why
>>> does it exist? A local variable would do? And if it's needed for
>>> (supposedly arch-agnostic) hyperlaunch, then it probably shouldn't be
>>> arch-specific? Daniel, Jason?
>>
>> As for the arch-agnostic side of things, arm needs some extra work to be
>> able to do it safely. dom0less currently constructs domains immediately after
>> parsing them, which is problematic for cases where some domains have the prop
>> and others don't. The domid allocation strategy may preclude further otherwise
>> good domains from being created just because their domid was stolen by a domain
>> that didn't actually care about which domid it got.
>>
>> It'll eventually want to leave the arch-specific area, but I don't want to do
>> that work now.
>
> But if the domU field is fine to live in a common struct despite being unused
> on x86, why can't the domid field live in a common struct too, despite being
> unused on non-x86? Otherwise it'll be extra churn for no gain to later move it
> there.
>
> Jan
Mostly out of tidiness. Otherwise it's hard to know which fields serve a purpose
where.
I genuinely forgot about the domU field. I'm more than happy to drop that arch
subfield and have domid in the main body of the struct, but I suspect MISRA
would have something to say about dead data?
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one
2025-07-02 15:34 ` Alejandro Vallejo
@ 2025-07-03 6:04 ` Jan Beulich
2025-07-07 14:49 ` Alejandro Vallejo
0 siblings, 1 reply; 28+ messages in thread
From: Jan Beulich @ 2025-07-03 6:04 UTC (permalink / raw)
To: Alejandro Vallejo
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Jason Andryuk, Bertrand Marquis, Michal Orzel,
xen-devel, Daniel Smith
On 02.07.2025 17:34, Alejandro Vallejo wrote:
> On Wed Jul 2, 2025 at 5:15 PM CEST, Jan Beulich wrote:
>> On 02.07.2025 17:09, Alejandro Vallejo wrote:
>>> On Wed Jul 2, 2025 at 3:15 PM CEST, Jan Beulich wrote:
>>>> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>>>>> --- a/xen/arch/x86/include/asm/bootfdt.h
>>>>> +++ b/xen/arch/x86/include/asm/bootfdt.h
>>>>> @@ -3,6 +3,12 @@
>>>>> #define X86_BOOTFDT_H
>>>>>
>>>>> #include <xen/types.h>
>>>>> +#include <public/xen.h>
>>>>> +
>>>>> +struct arch_boot_domain
>>>>> +{
>>>>> + domid_t domid;
>>>>> +};
>>>>>
>>>>> struct arch_boot_module
>>>>> {
>>>>> [...]
>>>>> @@ -1048,11 +1050,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
>>>>> dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
>>>>>
>>>>> /* Create initial domain. Not d0 for pvshim. */
>>>>> - bd->domid = get_initial_domain_id();
>>>>> - d = domain_create(bd->domid, &dom0_cfg,
>>>>> + bd->arch.domid = get_initial_domain_id();
>>>>> + d = domain_create(bd->arch.domid, &dom0_cfg,
>>>>> pv_shim ? 0 : CDF_privileged | CDF_hardware);
>>>>> if ( IS_ERR(d) )
>>>>> - panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
>>>>> + panic("Error creating d%u: %ld\n", bd->arch.domid, PTR_ERR(d));
>>>>
>>>> This being the only place where the (now) arch-specific field is used, why
>>>> does it exist? A local variable would do? And if it's needed for
>>>> (supposedly arch-agnostic) hyperlaunch, then it probably shouldn't be
>>>> arch-specific? Daniel, Jason?
>>>
>>> As for the arch-agnostic side of things, arm needs some extra work to be
>>> able to do it safely. dom0less currently constructs domains immediately after
>>> parsing them, which is problematic for cases where some domains have the prop
>>> and others don't. The domid allocation strategy may preclude further otherwise
>>> good domains from being created just because their domid was stolen by a domain
>>> that didn't actually care about which domid it got.
>>>
>>> It'll eventually want to leave the arch-specific area, but I don't want to do
>>> that work now.
>>
>> But if the domU field is fine to live in a common struct despite being unused
>> on x86, why can't the domid field live in a common struct too, despite being
>> unused on non-x86? Otherwise it'll be extra churn for no gain to later move it
>> there.
>
> Mostly out of tidiness. Otherwise it's hard to know which fields serve a purpose
> where.
>
> I genuinely forgot about the domU field. I'm more than happy to drop that arch
> subfield and have domid in the main body of the struct, but I suspect MISRA
> would have something to say about dead data?
In principle yes (and then also about the domU field), but we rejected the
respective rule altogether (for now? plus for a reason that I must have forgot
and that escapes me).
Jan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one
2025-07-03 6:04 ` Jan Beulich
@ 2025-07-07 14:49 ` Alejandro Vallejo
0 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-07 14:49 UTC (permalink / raw)
To: Jan Beulich
Cc: Andrew Cooper, Roger Pau Monné, Stefano Stabellini,
Julien Grall, Jason Andryuk, Bertrand Marquis, Michal Orzel,
xen-devel, Daniel Smith
On Thu Jul 3, 2025 at 8:04 AM CEST, Jan Beulich wrote:
> On 02.07.2025 17:34, Alejandro Vallejo wrote:
>> On Wed Jul 2, 2025 at 5:15 PM CEST, Jan Beulich wrote:
>>> On 02.07.2025 17:09, Alejandro Vallejo wrote:
>>>> On Wed Jul 2, 2025 at 3:15 PM CEST, Jan Beulich wrote:
>>>>> On 01.07.2025 12:56, Alejandro Vallejo wrote:
>>>>>> --- a/xen/arch/x86/include/asm/bootfdt.h
>>>>>> +++ b/xen/arch/x86/include/asm/bootfdt.h
>>>>>> @@ -3,6 +3,12 @@
>>>>>> #define X86_BOOTFDT_H
>>>>>>
>>>>>> #include <xen/types.h>
>>>>>> +#include <public/xen.h>
>>>>>> +
>>>>>> +struct arch_boot_domain
>>>>>> +{
>>>>>> + domid_t domid;
>>>>>> +};
>>>>>>
>>>>>> struct arch_boot_module
>>>>>> {
>>>>>> [...]
>>>>>> @@ -1048,11 +1050,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
>>>>>> dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
>>>>>>
>>>>>> /* Create initial domain. Not d0 for pvshim. */
>>>>>> - bd->domid = get_initial_domain_id();
>>>>>> - d = domain_create(bd->domid, &dom0_cfg,
>>>>>> + bd->arch.domid = get_initial_domain_id();
>>>>>> + d = domain_create(bd->arch.domid, &dom0_cfg,
>>>>>> pv_shim ? 0 : CDF_privileged | CDF_hardware);
>>>>>> if ( IS_ERR(d) )
>>>>>> - panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
>>>>>> + panic("Error creating d%u: %ld\n", bd->arch.domid, PTR_ERR(d));
>>>>>
>>>>> This being the only place where the (now) arch-specific field is used, why
>>>>> does it exist? A local variable would do? And if it's needed for
>>>>> (supposedly arch-agnostic) hyperlaunch, then it probably shouldn't be
>>>>> arch-specific? Daniel, Jason?
>>>>
>>>> As for the arch-agnostic side of things, arm needs some extra work to be
>>>> able to do it safely. dom0less currently constructs domains immediately after
>>>> parsing them, which is problematic for cases where some domains have the prop
>>>> and others don't. The domid allocation strategy may preclude further otherwise
>>>> good domains from being created just because their domid was stolen by a domain
>>>> that didn't actually care about which domid it got.
>>>>
>>>> It'll eventually want to leave the arch-specific area, but I don't want to do
>>>> that work now.
>>>
>>> But if the domU field is fine to live in a common struct despite being unused
>>> on x86, why can't the domid field live in a common struct too, despite being
>>> unused on non-x86? Otherwise it'll be extra churn for no gain to later move it
>>> there.
>>
>> Mostly out of tidiness. Otherwise it's hard to know which fields serve a purpose
>> where.
>>
>> I genuinely forgot about the domU field. I'm more than happy to drop that arch
>> subfield and have domid in the main body of the struct, but I suspect MISRA
>> would have something to say about dead data?
>
> In principle yes (and then also about the domU field), but we rejected the
> respective rule altogether (for now? plus for a reason that I must have forgot
> and that escapes me).
>
> Jan
Actually, moving it to an arch-specific field is rather annoying. everyone but
x86 needs the field. I'll just compile it out for x86 specifically with ifdef
guards, even if it is common code.
For the record, I hope to get rid of it on arm/riscv/ppc entirely later on by
deducing domU vs dom0 from the capabilities property.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v5 04/10] xen/dt: Move bootfdt functions to xen/bootfdt.h
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
` (2 preceding siblings ...)
2025-07-01 10:56 ` [PATCH v5 03/10] x86: Replace arch-specific boot_domain with the common one Alejandro Vallejo
@ 2025-07-01 10:56 ` Alejandro Vallejo
2025-07-01 10:56 ` [PATCH v5 05/10] xen/dt: Move bootinfo functions to a new bootinfo.h Alejandro Vallejo
` (5 subsequent siblings)
9 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:56 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Alistair Francis, Bob Eshleman, Connor Davis,
Oleksii Kurochko, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Dario Faggioli, Juergen Gross,
George Dunlap
Part of an unpicking process to extract bootfdt contents independent of bootinfo
to a separate file for x86 to take.
Move functions required for early FDT parsing from device_tree.h and arm's
setup.h onto bootfdt.h
Declaration motion only. Not a functional change.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
xen/arch/riscv/cpufeature.c | 1 +
xen/arch/riscv/smpboot.c | 1 +
xen/common/device-tree/device-tree.c | 1 +
xen/common/device-tree/static-evtchn.c | 1 +
xen/common/sched/boot-cpupool.c | 1 +
xen/include/xen/bootfdt.h | 91 ++++++++++++++++++++++++++
xen/include/xen/device_tree.h | 78 ----------------------
7 files changed, 96 insertions(+), 78 deletions(-)
diff --git a/xen/arch/riscv/cpufeature.c b/xen/arch/riscv/cpufeature.c
index b7d5ec6580..b846a106a3 100644
--- a/xen/arch/riscv/cpufeature.c
+++ b/xen/arch/riscv/cpufeature.c
@@ -8,6 +8,7 @@
*/
#include <xen/bitmap.h>
+#include <xen/bootfdt.h>
#include <xen/ctype.h>
#include <xen/device_tree.h>
#include <xen/errno.h>
diff --git a/xen/arch/riscv/smpboot.c b/xen/arch/riscv/smpboot.c
index 470f6d1311..3b8bf98e20 100644
--- a/xen/arch/riscv/smpboot.c
+++ b/xen/arch/riscv/smpboot.c
@@ -1,3 +1,4 @@
+#include <xen/bootfdt.h>
#include <xen/cpumask.h>
#include <xen/device_tree.h>
#include <xen/errno.h>
diff --git a/xen/common/device-tree/device-tree.c b/xen/common/device-tree/device-tree.c
index 886e6c7712..725ff71646 100644
--- a/xen/common/device-tree/device-tree.c
+++ b/xen/common/device-tree/device-tree.c
@@ -7,6 +7,7 @@
* benh@kernel.crashing.org
*/
+#include <xen/bootfdt.h>
#include <xen/types.h>
#include <xen/init.h>
#include <xen/guest_access.h>
diff --git a/xen/common/device-tree/static-evtchn.c b/xen/common/device-tree/static-evtchn.c
index 8b82e6b3d8..88342b44a1 100644
--- a/xen/common/device-tree/static-evtchn.c
+++ b/xen/common/device-tree/static-evtchn.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <xen/bootfdt.h>
#include <xen/event.h>
#include <xen/static-evtchn.h>
diff --git a/xen/common/sched/boot-cpupool.c b/xen/common/sched/boot-cpupool.c
index 641f3495cb..03be73efdd 100644
--- a/xen/common/sched/boot-cpupool.c
+++ b/xen/common/sched/boot-cpupool.c
@@ -7,6 +7,7 @@
* Copyright (C) 2022 Arm Ltd.
*/
+#include <xen/bootfdt.h>
#include <xen/acpi.h>
#include <xen/sched.h>
diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h
index 8ea52290b7..0846317f30 100644
--- a/xen/include/xen/bootfdt.h
+++ b/xen/include/xen/bootfdt.h
@@ -2,8 +2,11 @@
#ifndef XEN_BOOTFDT_H
#define XEN_BOOTFDT_H
+#include <xen/byteorder.h>
+#include <xen/bug.h>
#include <xen/types.h>
#include <xen/kernel.h>
+#include <xen/lib.h>
#include <xen/macros.h>
#include <xen/xmalloc.h>
@@ -16,8 +19,80 @@
#define NR_MEM_BANKS 256
#define NR_SHMEM_BANKS 32
+/* Default #address and #size cells */
+#define DT_ROOT_NODE_ADDR_CELLS_DEFAULT 2
+#define DT_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+
#define MAX_MODULES 32 /* Current maximum useful modules */
+#define DEVICE_TREE_MAX_DEPTH 16
+
+/* Helper to read a big number; size is in cells (not bytes) */
+static inline u64 dt_read_number(const __be32 *cell, int size)
+{
+ u64 r = 0;
+
+ while ( size-- )
+ r = (r << 32) | be32_to_cpu(*(cell++));
+ return r;
+}
+
+/* Wrapper for dt_read_number() to return paddr_t (instead of uint64_t) */
+static inline paddr_t dt_read_paddr(const __be32 *cell, int size)
+{
+ uint64_t dt_r;
+ paddr_t r;
+
+ /*
+ * dt_read_number will return uint64_t whereas paddr_t may not be 64-bit.
+ * Thus, there is an implicit cast from uint64_t to paddr_t.
+ */
+ dt_r = dt_read_number(cell, size);
+
+ if ( dt_r != (paddr_t)dt_r )
+ {
+ printk("Physical address greater than max width supported\n");
+ WARN();
+ }
+
+ /*
+ * Xen will truncate the address/size if it is greater than the maximum
+ * supported width and it will give an appropriate warning.
+ */
+ r = dt_r;
+
+ return r;
+}
+
+static inline u64 dt_next_cell(int s, const __be32 **cellp)
+{
+ const __be32 *p = *cellp;
+
+ *cellp = p + s;
+ return dt_read_number(p, s);
+}
+
+typedef int (*device_tree_node_func)(const void *fdt,
+ int node, const char *name, int depth,
+ u32 address_cells, u32 size_cells,
+ void *data);
+
+/**
+ * device_tree_for_each_node - iterate over all device tree sub-nodes
+ * @fdt: flat device tree.
+ * @node: parent node to start the search from
+ * @func: function to call for each sub-node.
+ * @data: data to pass to @func.
+ *
+ * Any nodes nested at DEVICE_TREE_MAX_DEPTH or deeper are ignored.
+ *
+ * Returns 0 if all nodes were iterated over successfully. If @func
+ * returns a value different from 0, that value is returned immediately.
+ */
+int device_tree_for_each_node(const void *fdt, int node,
+ device_tree_node_func func,
+ void *data);
+
typedef enum {
BOOTMOD_XEN,
BOOTMOD_FDT,
@@ -260,4 +335,20 @@ static inline struct membanks *membanks_xzalloc(unsigned int nr,
return banks;
}
+/*
+ * Interpret the property `prop_name` of `node` as a u32.
+ *
+ * Returns the property value on success; otherwise returns `dflt`.
+ */
+u32 device_tree_get_u32(const void *fdt, int node,
+ const char *prop_name, u32 dflt);
+
+/*
+ * Interpret the property `prop_name` of `node` as a "reg".
+ *
+ * Returns outputs in `start` and `size`.
+ */
+void device_tree_get_reg(const __be32 **cell, uint32_t address_cells,
+ uint32_t size_cells, paddr_t *start, paddr_t *size);
+
#endif /* XEN_BOOTFDT_H */
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index d2de7c3a13..b6d16756fc 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -22,8 +22,6 @@
#include <xen/list.h>
#include <xen/rwlock.h>
-#define DEVICE_TREE_MAX_DEPTH 16
-
/*
* Struct used for matching a device
*/
@@ -164,17 +162,8 @@ struct dt_raw_irq {
u32 specifier[DT_MAX_IRQ_SPEC];
};
-typedef int (*device_tree_node_func)(const void *fdt,
- int node, const char *name, int depth,
- u32 address_cells, u32 size_cells,
- void *data);
-
extern const void *device_tree_flattened;
-int device_tree_for_each_node(const void *fdt, int node,
- device_tree_node_func func,
- void *data);
-
/**
* dt_unflatten_host_device_tree - Unflatten the host device tree
*
@@ -245,10 +234,6 @@ void intc_dt_preinit(void);
#define dt_node_cmp(s1, s2) strcasecmp((s1), (s2))
#define dt_compat_cmp(s1, s2) strcasecmp((s1), (s2))
-/* Default #address and #size cells */
-#define DT_ROOT_NODE_ADDR_CELLS_DEFAULT 2
-#define DT_ROOT_NODE_SIZE_CELLS_DEFAULT 1
-
#define dt_for_each_property_node(dn, pp) \
for ( pp = (dn)->properties; (pp) != NULL; pp = (pp)->next )
@@ -258,55 +243,6 @@ void intc_dt_preinit(void);
#define dt_for_each_child_node(dt, dn) \
for ( dn = (dt)->child; (dn) != NULL; dn = (dn)->sibling )
-/* Helper to read a big number; size is in cells (not bytes) */
-static inline u64 dt_read_number(const __be32 *cell, int size)
-{
- u64 r = be32_to_cpu(*cell);
-
- switch ( size )
- {
- case 1:
- break;
- case 2:
- r = (r << 32) | be32_to_cpu(cell[1]);
- break;
- default:
- /* Nonsensical size. default to 1 */
- printk(XENLOG_ERR "dt_read_number(,%d) bad size\n", size);
- ASSERT_UNREACHABLE();
- break;
- };
-
- return r;
-}
-
-/* Wrapper for dt_read_number() to return paddr_t (instead of uint64_t) */
-static inline paddr_t dt_read_paddr(const __be32 *cell, int size)
-{
- uint64_t dt_r;
- paddr_t r;
-
- /*
- * dt_read_number will return uint64_t whereas paddr_t may not be 64-bit.
- * Thus, there is an implicit cast from uint64_t to paddr_t.
- */
- dt_r = dt_read_number(cell, size);
-
- if ( dt_r != (paddr_t)dt_r )
- {
- printk("Physical address greater than max width supported\n");
- WARN();
- }
-
- /*
- * Xen will truncate the address/size if it is greater than the maximum
- * supported width and it will give an appropriate warning.
- */
- r = dt_r;
-
- return r;
-}
-
/* Helper to convert a number of cells to bytes */
static inline int dt_cells_to_size(int size)
{
@@ -319,14 +255,6 @@ static inline int dt_size_to_cells(int bytes)
return (bytes / sizeof(u32));
}
-static inline u64 dt_next_cell(int s, const __be32 **cellp)
-{
- const __be32 *p = *cellp;
-
- *cellp = p + s;
- return dt_read_number(p, s);
-}
-
static inline const char *dt_node_full_name(const struct dt_device_node *np)
{
return (np && np->full_name) ? np->full_name : "<no-node>";
@@ -961,12 +889,6 @@ int dt_get_pci_domain_nr(struct dt_device_node *node);
struct dt_device_node *dt_find_node_by_phandle(dt_phandle handle);
-void device_tree_get_reg(const __be32 **cell, uint32_t address_cells,
- uint32_t size_cells, paddr_t *start, paddr_t *size);
-
-u32 device_tree_get_u32(const void *fdt, int node,
- const char *prop_name, u32 dflt);
-
#ifdef CONFIG_DEVICE_TREE_DEBUG
#define dt_dprintk(fmt, args...) \
printk(XENLOG_DEBUG fmt, ## args)
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH v5 05/10] xen/dt: Move bootinfo functions to a new bootinfo.h
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
` (3 preceding siblings ...)
2025-07-01 10:56 ` [PATCH v5 04/10] xen/dt: Move bootfdt functions to xen/bootfdt.h Alejandro Vallejo
@ 2025-07-01 10:56 ` Alejandro Vallejo
2025-07-01 10:57 ` [PATCH v5 06/10] xen/dt: Rename bootfdt.c -> bootinfo-fdt.c Alejandro Vallejo
` (4 subsequent siblings)
9 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:56 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
Anthony PERARD, Jan Beulich, Roger Pau Monné,
Alistair Francis, Bob Eshleman, Connor Davis, Oleksii Kurochko
Part of an unpicking process to extract bootfdt contents independent of
bootinfo to a separate file for x86 to take.
With this, bootfdt.h can be cleanly included from x86. A later patch
extracts the definitions so the functions may be called too.
Not a functional change.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
xen/arch/arm/domain_build.c | 1 +
xen/arch/arm/include/asm/setup.h | 2 +-
xen/arch/arm/setup.c | 1 +
xen/arch/riscv/mm.c | 2 +-
xen/arch/riscv/setup.c | 2 +-
xen/common/device-tree/bootfdt.c | 2 +-
xen/common/device-tree/bootinfo.c | 2 +-
xen/common/device-tree/dom0less-build.c | 2 +-
xen/common/device-tree/domain-build.c | 2 +-
xen/common/device-tree/kernel.c | 2 +-
xen/include/xen/bootfdt.h | 208 -----------------------
xen/include/xen/bootinfo.h | 213 ++++++++++++++++++++++++
xen/include/xen/fdt-domain-build.h | 2 +-
xen/include/xen/fdt-kernel.h | 2 +-
14 files changed, 225 insertions(+), 218 deletions(-)
create mode 100644 xen/include/xen/bootinfo.h
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index fb577f816f..822f7430bd 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <xen/init.h>
+#include <xen/bootinfo.h>
#include <xen/compile.h>
#include <xen/fdt-domain-build.h>
#include <xen/fdt-kernel.h>
diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
index b199d92a42..1eaf13bd66 100644
--- a/xen/arch/arm/include/asm/setup.h
+++ b/xen/arch/arm/include/asm/setup.h
@@ -3,7 +3,7 @@
#include <public/version.h>
#include <asm/p2m.h>
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/device_tree.h>
#if defined(CONFIG_MMU)
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 58acc2d0d4..28fe1de3e2 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -8,6 +8,7 @@
* Copyright (c) 2011 Citrix Systems.
*/
+#include <xen/bootinfo.h>
#include <xen/compile.h>
#include <xen/device_tree.h>
#include <xen/domain_page.h>
diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c
index 774ea42f2d..1ef015f179 100644
--- a/xen/arch/riscv/mm.c
+++ b/xen/arch/riscv/mm.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/bug.h>
#include <xen/compiler.h>
#include <xen/domain_page.h>
diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
index 8bcd19218d..3e99e2e194 100644
--- a/xen/arch/riscv/setup.c
+++ b/xen/arch/riscv/setup.c
@@ -2,7 +2,7 @@
#include <xen/acpi.h>
#include <xen/bug.h>
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/compile.h>
#include <xen/device_tree.h>
#include <xen/init.h>
diff --git a/xen/common/device-tree/bootfdt.c b/xen/common/device-tree/bootfdt.c
index 39334d6205..1848478e82 100644
--- a/xen/common/device-tree/bootfdt.c
+++ b/xen/common/device-tree/bootfdt.c
@@ -5,7 +5,7 @@
* Copyright (C) 2012-2014 Citrix Systems, Inc.
*/
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/device_tree.h>
#include <xen/efi.h>
#include <xen/init.h>
diff --git a/xen/common/device-tree/bootinfo.c b/xen/common/device-tree/bootinfo.c
index 2a27d1318b..00a43fb358 100644
--- a/xen/common/device-tree/bootinfo.c
+++ b/xen/common/device-tree/bootinfo.c
@@ -10,7 +10,7 @@
*/
#include <xen/acpi.h>
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/bug.h>
#include <xen/device_tree.h>
#include <xen/init.h>
diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tree/dom0less-build.c
index e321747175..4413b17aac 100644
--- a/xen/common/device-tree/dom0less-build.c
+++ b/xen/common/device-tree/dom0less-build.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/device_tree.h>
#include <xen/domain.h>
#include <xen/domain_page.h>
diff --git a/xen/common/device-tree/domain-build.c b/xen/common/device-tree/domain-build.c
index 51182d10ef..b97206c917 100644
--- a/xen/common/device-tree/domain-build.c
+++ b/xen/common/device-tree/domain-build.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/fdt-domain-build.h>
#include <xen/init.h>
#include <xen/lib.h>
diff --git a/xen/common/device-tree/kernel.c b/xen/common/device-tree/kernel.c
index 7a00768e6b..7f73520388 100644
--- a/xen/common/device-tree/kernel.c
+++ b/xen/common/device-tree/kernel.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/device_tree.h>
#include <xen/fdt-kernel.h>
#include <xen/errno.h>
diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h
index 0846317f30..ad6b11cb6d 100644
--- a/xen/include/xen/bootfdt.h
+++ b/xen/include/xen/bootfdt.h
@@ -5,10 +5,7 @@
#include <xen/byteorder.h>
#include <xen/bug.h>
#include <xen/types.h>
-#include <xen/kernel.h>
#include <xen/lib.h>
-#include <xen/macros.h>
-#include <xen/xmalloc.h>
#if __has_include(<asm/bootfdt.h>)
#include <asm/bootfdt.h>
@@ -16,15 +13,10 @@
#define MIN_FDT_ALIGN 8
-#define NR_MEM_BANKS 256
-#define NR_SHMEM_BANKS 32
-
/* Default #address and #size cells */
#define DT_ROOT_NODE_ADDR_CELLS_DEFAULT 2
#define DT_ROOT_NODE_SIZE_CELLS_DEFAULT 1
-#define MAX_MODULES 32 /* Current maximum useful modules */
-
#define DEVICE_TREE_MAX_DEPTH 16
/* Helper to read a big number; size is in cells (not bytes) */
@@ -104,78 +96,6 @@ typedef enum {
BOOTMOD_UNKNOWN
} boot_module_kind;
-enum membank_type {
- /*
- * The MEMBANK_DEFAULT type refers to either reserved memory for the
- * device/firmware (when the bank is in 'reserved_mem') or any RAM (when
- * the bank is in 'mem').
- */
- MEMBANK_DEFAULT,
- /*
- * The MEMBANK_STATIC_DOMAIN type is used to indicate whether the memory
- * bank is bound to a static Xen domain. It is only valid when the bank
- * is in reserved_mem.
- */
- MEMBANK_STATIC_DOMAIN,
- /*
- * The MEMBANK_STATIC_HEAP type is used to indicate whether the memory
- * bank is reserved as static heap. It is only valid when the bank is
- * in reserved_mem.
- */
- MEMBANK_STATIC_HEAP,
- /*
- * The MEMBANK_FDT_RESVMEM type is used to indicate whether the memory
- * bank is from the FDT reserve map.
- */
- MEMBANK_FDT_RESVMEM,
-};
-
-enum region_type {
- MEMORY,
- RESERVED_MEMORY,
- STATIC_SHARED_MEMORY
-};
-
-/* Indicates the maximum number of characters(\0 included) for shm_id */
-#define MAX_SHM_ID_LENGTH 16
-
-struct shmem_membank_extra {
- char shm_id[MAX_SHM_ID_LENGTH];
- unsigned int nr_shm_borrowers;
-};
-
-struct membank {
- paddr_t start;
- paddr_t size;
- union {
- enum membank_type type;
-#ifdef CONFIG_STATIC_SHM
- struct shmem_membank_extra *shmem_extra;
-#endif
- };
-};
-
-struct membanks {
- __struct_group(membanks_hdr, common, ,
- unsigned int nr_banks;
- unsigned int max_banks;
- enum region_type type;
- );
- struct membank bank[];
-};
-
-struct meminfo {
- struct membanks_hdr common;
- struct membank bank[NR_MEM_BANKS];
-};
-
-struct shared_meminfo {
- struct membanks_hdr common;
- struct membank bank[NR_SHMEM_BANKS];
- struct shmem_membank_extra extra[NR_SHMEM_BANKS];
-};
-
-
struct boot_domain {
struct domain *d;
@@ -207,134 +127,6 @@ struct boot_module {
#endif
};
-/* DT_MAX_NAME is the node name max length according the DT spec */
-#define DT_MAX_NAME 41
-struct bootcmdline {
- boot_module_kind kind;
- bool domU;
- paddr_t start;
- char dt_name[DT_MAX_NAME];
- char cmdline[BOOTMOD_MAX_CMDLINE];
-};
-
-struct boot_modules {
- int nr_mods;
- struct boot_module module[MAX_MODULES];
-};
-
-struct bootcmdlines {
- unsigned int nr_mods;
- struct bootcmdline cmdline[MAX_MODULES];
-};
-
-struct bootinfo {
- struct meminfo mem;
- /* The reserved regions are only used when booting using Device-Tree */
- struct meminfo reserved_mem;
- struct boot_modules modules;
- struct bootcmdlines cmdlines;
-#ifdef CONFIG_ACPI
- struct meminfo acpi;
-#endif
-#ifdef CONFIG_STATIC_SHM
- struct shared_meminfo shmem;
-#endif
-};
-
-#ifdef CONFIG_ACPI
-#define BOOTINFO_ACPI_INIT \
- .acpi.common.max_banks = NR_MEM_BANKS, \
- .acpi.common.type = MEMORY,
-#else
-#define BOOTINFO_ACPI_INIT
-#endif
-
-#ifdef CONFIG_STATIC_SHM
-#define BOOTINFO_SHMEM_INIT \
- .shmem.common.max_banks = NR_SHMEM_BANKS, \
- .shmem.common.type = STATIC_SHARED_MEMORY,
-#else
-#define BOOTINFO_SHMEM_INIT
-#endif
-
-#define BOOTINFO_INIT \
-{ \
- .mem.common.max_banks = NR_MEM_BANKS, \
- .mem.common.type = MEMORY, \
- .reserved_mem.common.max_banks = NR_MEM_BANKS, \
- .reserved_mem.common.type = RESERVED_MEMORY, \
- BOOTINFO_ACPI_INIT \
- BOOTINFO_SHMEM_INIT \
-}
-
-extern struct bootinfo bootinfo;
-
-bool check_reserved_regions_overlap(paddr_t region_start,
- paddr_t region_size,
- bool allow_memreserve_overlap);
-
-struct boot_module *add_boot_module(boot_module_kind kind,
- paddr_t start, paddr_t size, bool domU);
-struct boot_module *boot_module_find_by_kind(boot_module_kind kind);
-struct boot_module * boot_module_find_by_addr_and_kind(boot_module_kind kind,
- paddr_t start);
-void add_boot_cmdline(const char *name, const char *cmdline,
- boot_module_kind kind, paddr_t start, bool domU);
-struct bootcmdline *boot_cmdline_find_by_kind(boot_module_kind kind);
-struct bootcmdline * boot_cmdline_find_by_name(const char *name);
-const char *boot_module_kind_as_string(boot_module_kind kind);
-
-void populate_boot_allocator(void);
-
-size_t boot_fdt_info(const void *fdt, paddr_t paddr);
-
-const char *boot_fdt_cmdline(const void *fdt);
-int domain_fdt_begin_node(void *fdt, const char *name, uint64_t unit);
-
-static inline struct membanks *bootinfo_get_reserved_mem(void)
-{
- return container_of(&bootinfo.reserved_mem.common, struct membanks, common);
-}
-
-static inline struct membanks *bootinfo_get_mem(void)
-{
- return container_of(&bootinfo.mem.common, struct membanks, common);
-}
-
-#ifdef CONFIG_ACPI
-static inline struct membanks *bootinfo_get_acpi(void)
-{
- return container_of(&bootinfo.acpi.common, struct membanks, common);
-}
-#endif
-
-#ifdef CONFIG_STATIC_SHM
-static inline struct membanks *bootinfo_get_shmem(void)
-{
- return container_of(&bootinfo.shmem.common, struct membanks, common);
-}
-
-static inline struct shmem_membank_extra *bootinfo_get_shmem_extra(void)
-{
- return bootinfo.shmem.extra;
-}
-#endif
-
-static inline struct membanks *membanks_xzalloc(unsigned int nr,
- enum region_type type)
-{
- struct membanks *banks = xzalloc_flex_struct(struct membanks, bank, nr);
-
- if ( !banks )
- goto out;
-
- banks->max_banks = nr;
- banks->type = type;
-
- out:
- return banks;
-}
-
/*
* Interpret the property `prop_name` of `node` as a u32.
*
diff --git a/xen/include/xen/bootinfo.h b/xen/include/xen/bootinfo.h
new file mode 100644
index 0000000000..f834f19571
--- /dev/null
+++ b/xen/include/xen/bootinfo.h
@@ -0,0 +1,213 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef XEN_BOOTINFO_H
+#define XEN_BOOTINFO_H
+
+#include <xen/bootfdt.h>
+#include <xen/kernel.h>
+#include <xen/macros.h>
+#include <xen/xmalloc.h>
+
+#define NR_MEM_BANKS 256
+#define NR_SHMEM_BANKS 32
+
+#define MAX_MODULES 32 /* Current maximum useful modules */
+
+enum membank_type {
+ /*
+ * The MEMBANK_DEFAULT type refers to either reserved memory for the
+ * device/firmware (when the bank is in 'reserved_mem') or any RAM (when
+ * the bank is in 'mem').
+ */
+ MEMBANK_DEFAULT,
+ /*
+ * The MEMBANK_STATIC_DOMAIN type is used to indicate whether the memory
+ * bank is bound to a static Xen domain. It is only valid when the bank
+ * is in reserved_mem.
+ */
+ MEMBANK_STATIC_DOMAIN,
+ /*
+ * The MEMBANK_STATIC_HEAP type is used to indicate whether the memory
+ * bank is reserved as static heap. It is only valid when the bank is
+ * in reserved_mem.
+ */
+ MEMBANK_STATIC_HEAP,
+ /*
+ * The MEMBANK_FDT_RESVMEM type is used to indicate whether the memory
+ * bank is from the FDT reserve map.
+ */
+ MEMBANK_FDT_RESVMEM,
+};
+
+enum region_type {
+ MEMORY,
+ RESERVED_MEMORY,
+ STATIC_SHARED_MEMORY
+};
+
+/* Indicates the maximum number of characters(\0 included) for shm_id */
+#define MAX_SHM_ID_LENGTH 16
+
+struct shmem_membank_extra {
+ char shm_id[MAX_SHM_ID_LENGTH];
+ unsigned int nr_shm_borrowers;
+};
+
+struct membank {
+ paddr_t start;
+ paddr_t size;
+ union {
+ enum membank_type type;
+#ifdef CONFIG_STATIC_SHM
+ struct shmem_membank_extra *shmem_extra;
+#endif
+ };
+};
+
+struct membanks {
+ __struct_group(membanks_hdr, common, ,
+ unsigned int nr_banks;
+ unsigned int max_banks;
+ enum region_type type;
+ );
+ struct membank bank[];
+};
+
+struct meminfo {
+ struct membanks_hdr common;
+ struct membank bank[NR_MEM_BANKS];
+};
+
+struct shared_meminfo {
+ struct membanks_hdr common;
+ struct membank bank[NR_SHMEM_BANKS];
+ struct shmem_membank_extra extra[NR_SHMEM_BANKS];
+};
+
+/* DT_MAX_NAME is the node name max length according the DT spec */
+#define DT_MAX_NAME 41
+struct bootcmdline {
+ boot_module_kind kind;
+ bool domU;
+ paddr_t start;
+ char dt_name[DT_MAX_NAME];
+ char cmdline[BOOTMOD_MAX_CMDLINE];
+};
+
+struct boot_modules {
+ int nr_mods;
+ struct boot_module module[MAX_MODULES];
+};
+
+struct bootcmdlines {
+ unsigned int nr_mods;
+ struct bootcmdline cmdline[MAX_MODULES];
+};
+
+struct bootinfo {
+ struct meminfo mem;
+ /* The reserved regions are only used when booting using Device-Tree */
+ struct meminfo reserved_mem;
+ struct boot_modules modules;
+ struct bootcmdlines cmdlines;
+#ifdef CONFIG_ACPI
+ struct meminfo acpi;
+#endif
+#ifdef CONFIG_STATIC_SHM
+ struct shared_meminfo shmem;
+#endif
+};
+
+#ifdef CONFIG_ACPI
+#define BOOTINFO_ACPI_INIT \
+ .acpi.common.max_banks = NR_MEM_BANKS, \
+ .acpi.common.type = MEMORY,
+#else
+#define BOOTINFO_ACPI_INIT
+#endif
+
+#ifdef CONFIG_STATIC_SHM
+#define BOOTINFO_SHMEM_INIT \
+ .shmem.common.max_banks = NR_SHMEM_BANKS, \
+ .shmem.common.type = STATIC_SHARED_MEMORY,
+#else
+#define BOOTINFO_SHMEM_INIT
+#endif
+
+#define BOOTINFO_INIT \
+{ \
+ .mem.common.max_banks = NR_MEM_BANKS, \
+ .mem.common.type = MEMORY, \
+ .reserved_mem.common.max_banks = NR_MEM_BANKS, \
+ .reserved_mem.common.type = RESERVED_MEMORY, \
+ BOOTINFO_ACPI_INIT \
+ BOOTINFO_SHMEM_INIT \
+}
+
+extern struct bootinfo bootinfo;
+
+bool check_reserved_regions_overlap(paddr_t region_start,
+ paddr_t region_size,
+ bool allow_memreserve_overlap);
+
+struct boot_module *add_boot_module(boot_module_kind kind,
+ paddr_t start, paddr_t size, bool domU);
+struct boot_module *boot_module_find_by_kind(boot_module_kind kind);
+struct boot_module * boot_module_find_by_addr_and_kind(boot_module_kind kind,
+ paddr_t start);
+void add_boot_cmdline(const char *name, const char *cmdline,
+ boot_module_kind kind, paddr_t start, bool domU);
+struct bootcmdline *boot_cmdline_find_by_kind(boot_module_kind kind);
+struct bootcmdline * boot_cmdline_find_by_name(const char *name);
+const char *boot_module_kind_as_string(boot_module_kind kind);
+
+void populate_boot_allocator(void);
+
+size_t boot_fdt_info(const void *fdt, paddr_t paddr);
+const char *boot_fdt_cmdline(const void *fdt);
+int domain_fdt_begin_node(void *fdt, const char *name, uint64_t unit);
+
+static inline struct membanks *bootinfo_get_reserved_mem(void)
+{
+ return container_of(&bootinfo.reserved_mem.common, struct membanks, common);
+}
+
+static inline struct membanks *bootinfo_get_mem(void)
+{
+ return container_of(&bootinfo.mem.common, struct membanks, common);
+}
+
+#ifdef CONFIG_ACPI
+static inline struct membanks *bootinfo_get_acpi(void)
+{
+ return container_of(&bootinfo.acpi.common, struct membanks, common);
+}
+#endif
+
+#ifdef CONFIG_STATIC_SHM
+static inline struct membanks *bootinfo_get_shmem(void)
+{
+ return container_of(&bootinfo.shmem.common, struct membanks, common);
+}
+
+static inline struct shmem_membank_extra *bootinfo_get_shmem_extra(void)
+{
+ return bootinfo.shmem.extra;
+}
+#endif
+
+static inline struct membanks *membanks_xzalloc(unsigned int nr,
+ enum region_type type)
+{
+ struct membanks *banks = xzalloc_flex_struct(struct membanks, bank, nr);
+
+ if ( !banks )
+ goto out;
+
+ banks->max_banks = nr;
+ banks->type = type;
+
+ out:
+ return banks;
+}
+
+#endif /* XEN_BOOTINFO_H */
diff --git a/xen/include/xen/fdt-domain-build.h b/xen/include/xen/fdt-domain-build.h
index 45981dbec0..60565fdbf9 100644
--- a/xen/include/xen/fdt-domain-build.h
+++ b/xen/include/xen/fdt-domain-build.h
@@ -3,7 +3,7 @@
#ifndef __XEN_FDT_DOMAIN_BUILD_H__
#define __XEN_FDT_DOMAIN_BUILD_H__
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/device_tree.h>
#include <xen/fdt-kernel.h>
#include <xen/mm.h>
diff --git a/xen/include/xen/fdt-kernel.h b/xen/include/xen/fdt-kernel.h
index fee8eac1db..ee29aad9fe 100644
--- a/xen/include/xen/fdt-kernel.h
+++ b/xen/include/xen/fdt-kernel.h
@@ -7,7 +7,7 @@
#ifndef __XEN_FDT_KERNEL_H__
#define __XEN_FDT_KERNEL_H__
-#include <xen/bootfdt.h>
+#include <xen/bootinfo.h>
#include <xen/device_tree.h>
#include <xen/types.h>
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH v5 06/10] xen/dt: Rename bootfdt.c -> bootinfo-fdt.c
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
` (4 preceding siblings ...)
2025-07-01 10:56 ` [PATCH v5 05/10] xen/dt: Move bootinfo functions to a new bootinfo.h Alejandro Vallejo
@ 2025-07-01 10:57 ` Alejandro Vallejo
2025-07-01 10:57 ` [PATCH v5 07/10] xen/dt: Extract helper to map nodes to module kinds Alejandro Vallejo
` (3 subsequent siblings)
9 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:57 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Daniel P. Smith
This file will eventually contain bootfdt helpers that make heavy use of
bootinfo. To simplify git history do the rename here explicitly. A later
patch extracts bootinfo-independent helpers into bootfdt.c.
Doing so here would needlessly pollute the diffs.
Not a functional change.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
xen/common/device-tree/Makefile | 1 +
xen/common/device-tree/bootfdt.c | 646 +-------------------------
xen/common/device-tree/bootinfo-fdt.c | 597 ++++++++++++++++++++++++
3 files changed, 619 insertions(+), 625 deletions(-)
create mode 100644 xen/common/device-tree/bootinfo-fdt.c
diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makefile
index 13127296cb..8abc069c4b 100644
--- a/xen/common/device-tree/Makefile
+++ b/xen/common/device-tree/Makefile
@@ -1,4 +1,5 @@
obj-y += bootfdt.init.o
+obj-y += bootinfo-fdt.init.o
obj-y += bootinfo.init.o
obj-y += device-tree.o
obj-$(CONFIG_DOMAIN_BUILD_HELPERS) += domain-build.init.o
diff --git a/xen/common/device-tree/bootfdt.c b/xen/common/device-tree/bootfdt.c
index 1848478e82..0d8d9ea357 100644
--- a/xen/common/device-tree/bootfdt.c
+++ b/xen/common/device-tree/bootfdt.c
@@ -1,206 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Early Device Tree
- *
- * Copyright (C) 2012-2014 Citrix Systems, Inc.
- */
-
-#include <xen/bootinfo.h>
-#include <xen/device_tree.h>
-#include <xen/efi.h>
-#include <xen/init.h>
-#include <xen/kernel.h>
+#include <xen/bootfdt.h>
+#include <xen/bug.h>
#include <xen/lib.h>
-#include <xen/libfdt/libfdt-xen.h>
-#include <xen/sort.h>
-#include <xen/static-shmem.h>
-#include <xsm/xsm.h>
-#include <asm/setup.h>
-
-static void __init __maybe_unused build_assertions(void)
-{
- /*
- * Check that no padding is between struct membanks "bank" flexible array
- * member and struct meminfo "bank" member
- */
- BUILD_BUG_ON((offsetof(struct membanks, bank) !=
- offsetof(struct meminfo, bank)));
- /* Ensure "struct membanks" and "struct membank" are equally aligned */
- BUILD_BUG_ON(alignof(struct membanks) != alignof(struct membank));
-}
-
-static bool __init device_tree_node_is_available(const void *fdt, int node)
-{
- const char *status;
- int len;
-
- status = fdt_getprop(fdt, node, "status", &len);
- if ( !status )
- return true;
-
- if ( len > 0 )
- {
- if ( !strcmp(status, "ok") || !strcmp(status, "okay") )
- return true;
- }
-
- return false;
-}
-
-static bool __init device_tree_node_matches(const void *fdt, int node,
- const char *match)
-{
- const char *name;
- size_t match_len;
-
- name = fdt_get_name(fdt, node, NULL);
- match_len = strlen(match);
-
- /* Match both "match" and "match@..." patterns but not
- "match-foo". */
- return strncmp(name, match, match_len) == 0
- && (name[match_len] == '@' || name[match_len] == '\0');
-}
-
-static bool __init device_tree_node_compatible(const void *fdt, int node,
- const char *match)
-{
- int len, l;
- const void *prop;
-
- prop = fdt_getprop(fdt, node, "compatible", &len);
- if ( prop == NULL )
- return false;
-
- while ( len > 0 ) {
- if ( !dt_compat_cmp(prop, match) )
- return true;
- l = strlen(prop) + 1;
- prop += l;
- len -= l;
- }
-
- return false;
-}
-
-/*
- * Check if a node is a proper /memory node according to Devicetree
- * Specification v0.4, chapter 3.4.
- */
-static bool __init device_tree_is_memory_node(const void *fdt, int node,
- int depth)
-{
- const char *type;
- int len;
-
- if ( depth != 1 )
- return false;
-
- if ( !device_tree_node_matches(fdt, node, "memory") )
- return false;
-
- type = fdt_getprop(fdt, node, "device_type", &len);
- if ( !type )
- return false;
-
- if ( (len <= strlen("memory")) || strcmp(type, "memory") )
- return false;
-
- return true;
-}
-
-void __init device_tree_get_reg(const __be32 **cell, uint32_t address_cells,
- uint32_t size_cells, paddr_t *start,
- paddr_t *size)
-{
- uint64_t dt_start, dt_size;
-
- /*
- * dt_next_cell will return uint64_t whereas paddr_t may not be 64-bit.
- * Thus, there is an implicit cast from uint64_t to paddr_t.
- */
- dt_start = dt_next_cell(address_cells, cell);
- dt_size = dt_next_cell(size_cells, cell);
-
- if ( dt_start != (paddr_t)dt_start )
- {
- printk("Physical address greater than max width supported\n");
- WARN();
- }
-
- if ( dt_size != (paddr_t)dt_size )
- {
- printk("Physical size greater than max width supported\n");
- WARN();
- }
-
- /*
- * Xen will truncate the address/size if it is greater than the maximum
- * supported width and it will give an appropriate warning.
- */
- *start = dt_start;
- *size = dt_size;
-}
-
-static int __init device_tree_get_meminfo(const void *fdt, int node,
- const char *prop_name,
- u32 address_cells, u32 size_cells,
- struct membanks *mem,
- enum membank_type type)
-{
- const struct fdt_property *prop;
- unsigned int i, banks;
- const __be32 *cell;
- u32 reg_cells = address_cells + size_cells;
- paddr_t start, size;
-
- if ( !device_tree_node_is_available(fdt, node) )
- return 0;
-
- if ( address_cells < 1 || size_cells < 1 )
- {
- printk("fdt: property `%s': invalid #address-cells or #size-cells",
- prop_name);
- return -EINVAL;
- }
-
- prop = fdt_get_property(fdt, node, prop_name, NULL);
- if ( !prop )
- return -ENOENT;
-
- cell = (const __be32 *)prop->data;
- banks = fdt32_to_cpu(prop->len) / (reg_cells * sizeof (u32));
-
- for ( i = 0; i < banks && mem->nr_banks < mem->max_banks; i++ )
- {
- device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
- /*
- * Some valid device trees, such as those generated by OpenPOWER
- * skiboot firmware, expose all reserved memory regions in the
- * FDT memory reservation block AND in the reserved-memory node which
- * has already been parsed. Thus, any matching overlaps in the
- * reserved_mem banks should be ignored.
- */
- if ( mem == bootinfo_get_reserved_mem() &&
- check_reserved_regions_overlap(start, size, true) )
- return -EINVAL;
- /* Some DT may describe empty bank, ignore them */
- if ( !size )
- continue;
- mem->bank[mem->nr_banks].start = start;
- mem->bank[mem->nr_banks].size = size;
- mem->bank[mem->nr_banks].type = type;
- mem->nr_banks++;
- }
-
- if ( i < banks )
- {
- printk("Warning: Max number of supported memory regions reached.\n");
- return -ENOSPC;
- }
-
- return 0;
-}
+#include <xen/libfdt/libfdt.h>
u32 __init device_tree_get_u32(const void *fdt, int node,
const char *prop_name, u32 dflt)
@@ -214,18 +16,6 @@ u32 __init device_tree_get_u32(const void *fdt, int node,
return fdt32_to_cpu(*(uint32_t*)prop->data);
}
-/**
- * device_tree_for_each_node - iterate over all device tree sub-nodes
- * @fdt: flat device tree.
- * @node: parent node to start the search from
- * @func: function to call for each sub-node.
- * @data: data to pass to @func.
- *
- * Any nodes nested at DEVICE_TREE_MAX_DEPTH or deeper are ignored.
- *
- * Returns 0 if all nodes were iterated over successfully. If @func
- * returns a value different from 0, that value is returned immediately.
- */
int __init device_tree_for_each_node(const void *fdt, int node,
device_tree_node_func func,
void *data)
@@ -273,429 +63,35 @@ int __init device_tree_for_each_node(const void *fdt, int node,
return 0;
}
-static int __init process_memory_node(const void *fdt, int node,
- const char *name, int depth,
- u32 address_cells, u32 size_cells,
- struct membanks *mem)
-{
- return device_tree_get_meminfo(fdt, node, "reg", address_cells, size_cells,
- mem, MEMBANK_DEFAULT);
-}
-
-static int __init process_reserved_memory_node(const void *fdt, int node,
- const char *name, int depth,
- u32 address_cells,
- u32 size_cells,
- void *data)
-{
- int rc = process_memory_node(fdt, node, name, depth, address_cells,
- size_cells, data);
-
- if ( rc == -ENOSPC )
- panic("Max number of supported reserved-memory regions reached.\n");
- else if ( rc != -ENOENT )
- return rc;
- return 0;
-}
-
-static int __init process_reserved_memory(const void *fdt, int node,
- const char *name, int depth,
- u32 address_cells, u32 size_cells)
-{
- return device_tree_for_each_node(fdt, node,
- process_reserved_memory_node,
- bootinfo_get_reserved_mem());
-}
-
-static void __init process_multiboot_node(const void *fdt, int node,
- const char *name,
- u32 address_cells, u32 size_cells)
-{
- static int __initdata kind_guess = 0;
- const struct fdt_property *prop;
- const __be32 *cell;
- boot_module_kind kind;
- paddr_t start, size;
- int len;
- /* sizeof("/chosen/") + DT_MAX_NAME + '/' + DT_MAX_NAME + '/0' => 92 */
- char path[92];
- int parent_node, ret;
- bool domU;
-
- parent_node = fdt_parent_offset(fdt, node);
- ASSERT(parent_node >= 0);
-
- /* Check that the node is under "/chosen" (first 7 chars of path) */
- ret = fdt_get_path(fdt, node, path, sizeof (path));
- if ( ret != 0 || strncmp(path, "/chosen", 7) )
- return;
-
- prop = fdt_get_property(fdt, node, "reg", &len);
- if ( !prop )
- panic("node %s missing `reg' property\n", name);
-
- if ( len < dt_cells_to_size(address_cells + size_cells) )
- panic("fdt: node `%s': `reg` property length is too short\n",
- name);
-
- cell = (const __be32 *)prop->data;
- device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
-
- if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
- fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
- kind = BOOTMOD_KERNEL;
- else if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 ||
- fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 )
- kind = BOOTMOD_RAMDISK;
- else if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 )
- kind = BOOTMOD_XSM;
- else if ( fdt_node_check_compatible(fdt, node, "multiboot,device-tree") == 0 )
- kind = BOOTMOD_GUEST_DTB;
- else if ( fdt_node_check_compatible(fdt, node, "multiboot,microcode") == 0 )
- kind = BOOTMOD_MICROCODE;
- else
- kind = BOOTMOD_UNKNOWN;
-
- /**
- * Guess the kind of these first two unknowns respectively:
- * (1) The first unknown must be kernel.
- * (2) Detect the XSM Magic from the 2nd unknown:
- * a. If it's XSM, set the kind as XSM, and that also means we
- * won't load ramdisk;
- * b. if it's not XSM, set the kind as ramdisk.
- * So if user want to load ramdisk, it must be the 2nd unknown.
- * We also detect the XSM Magic for the following unknowns,
- * then set its kind according to the return value of has_xsm_magic.
- */
- if ( kind == BOOTMOD_UNKNOWN )
- {
- switch ( kind_guess++ )
- {
- case 0: kind = BOOTMOD_KERNEL; break;
- case 1: kind = BOOTMOD_RAMDISK; break;
- default: break;
- }
- if ( kind_guess > 1 && has_xsm_magic(start) )
- kind = BOOTMOD_XSM;
- }
-
- domU = fdt_node_check_compatible(fdt, parent_node, "xen,domain") == 0;
- add_boot_module(kind, start, size, domU);
-
- prop = fdt_get_property(fdt, node, "bootargs", &len);
- if ( !prop )
- return;
- add_boot_cmdline(fdt_get_name(fdt, parent_node, &len), prop->data,
- kind, start, domU);
-}
-
-static int __init process_chosen_node(const void *fdt, int node,
- const char *name,
- u32 address_cells, u32 size_cells)
-{
- const struct fdt_property *prop;
- paddr_t start, end;
- int len;
-
- if ( fdt_get_property(fdt, node, "xen,static-heap", NULL) )
- {
- int rc;
-
- printk("Checking for static heap in /chosen\n");
-
- rc = device_tree_get_meminfo(fdt, node, "xen,static-heap",
- address_cells, size_cells,
- bootinfo_get_reserved_mem(),
- MEMBANK_STATIC_HEAP);
- if ( rc )
- return rc;
-
- using_static_heap = true;
- }
-
- printk("Checking for initrd in /chosen\n");
-
- prop = fdt_get_property(fdt, node, "linux,initrd-start", &len);
- if ( !prop )
- /* No initrd present. */
- return 0;
- if ( len != sizeof(u32) && len != sizeof(u64) )
- {
- printk("linux,initrd-start property has invalid length %d\n", len);
- return -EINVAL;
- }
- start = dt_read_paddr((const void *)&prop->data, dt_size_to_cells(len));
-
- prop = fdt_get_property(fdt, node, "linux,initrd-end", &len);
- if ( !prop )
- {
- printk("linux,initrd-end not present but -start was\n");
- return -EINVAL;
- }
- if ( len != sizeof(u32) && len != sizeof(u64) )
- {
- printk("linux,initrd-end property has invalid length %d\n", len);
- return -EINVAL;
- }
- end = dt_read_paddr((const void *)&prop->data, dt_size_to_cells(len));
-
- if ( start >= end )
- {
- printk("linux,initrd limits invalid: %"PRIpaddr" >= %"PRIpaddr"\n",
- start, end);
- return -EINVAL;
- }
-
- printk("Initrd %"PRIpaddr"-%"PRIpaddr"\n", start, end - 1);
-
- add_boot_module(BOOTMOD_RAMDISK, start, end-start, false);
-
- return 0;
-}
-
-static int __init process_domain_node(const void *fdt, int node,
- const char *name,
- u32 address_cells, u32 size_cells)
-{
- const struct fdt_property *prop;
-
- printk("Checking for \"xen,static-mem\" in domain node\n");
-
- prop = fdt_get_property(fdt, node, "xen,static-mem", NULL);
- if ( !prop )
- /* No "xen,static-mem" present. */
- return 0;
-
- return device_tree_get_meminfo(fdt, node, "xen,static-mem", address_cells,
- size_cells, bootinfo_get_reserved_mem(),
- MEMBANK_STATIC_DOMAIN);
-}
-
-#ifndef CONFIG_STATIC_SHM
-static inline int process_shm_node(const void *fdt, int node,
- uint32_t address_cells, uint32_t size_cells)
-{
- printk("CONFIG_STATIC_SHM must be enabled for parsing static shared"
- " memory nodes\n");
- return -EINVAL;
-}
-#endif
-
-static int __init early_scan_node(const void *fdt,
- int node, const char *name, int depth,
- u32 address_cells, u32 size_cells,
- void *data)
+void __init device_tree_get_reg(const __be32 **cell, uint32_t address_cells,
+ uint32_t size_cells, paddr_t *start,
+ paddr_t *size)
{
- int rc = 0;
+ uint64_t dt_start, dt_size;
/*
- * If Xen has been booted via UEFI, the memory banks are
- * populated. So we should skip the parsing.
+ * dt_next_cell will return uint64_t whereas paddr_t may not be 64-bit.
+ * Thus, there is an implicit cast from uint64_t to paddr_t.
*/
- if ( !efi_enabled(EFI_BOOT) &&
- device_tree_is_memory_node(fdt, node, depth) )
- rc = process_memory_node(fdt, node, name, depth,
- address_cells, size_cells, bootinfo_get_mem());
- else if ( depth == 1 && !dt_node_cmp(name, "reserved-memory") )
- rc = process_reserved_memory(fdt, node, name, depth,
- address_cells, size_cells);
- else if ( depth <= 3 && (device_tree_node_compatible(fdt, node, "xen,multiboot-module" ) ||
- device_tree_node_compatible(fdt, node, "multiboot,module" )))
- process_multiboot_node(fdt, node, name, address_cells, size_cells);
- else if ( depth == 1 && device_tree_node_matches(fdt, node, "chosen") )
- rc = process_chosen_node(fdt, node, name, address_cells, size_cells);
- else if ( depth == 2 && device_tree_node_compatible(fdt, node, "xen,domain") )
- rc = process_domain_node(fdt, node, name, address_cells, size_cells);
- else if ( depth <= 3 && device_tree_node_compatible(fdt, node, "xen,domain-shared-memory-v1") )
- rc = process_shm_node(fdt, node, address_cells, size_cells);
-
- if ( rc < 0 )
- printk("fdt: node `%s': parsing failed\n", name);
- return rc;
-}
-
-static void __init early_print_info(void)
-{
- const struct membanks *mi = bootinfo_get_mem();
- const struct membanks *mem_resv = bootinfo_get_reserved_mem();
- struct boot_modules *mods = &bootinfo.modules;
- struct bootcmdlines *cmds = &bootinfo.cmdlines;
- unsigned int i;
-
- for ( i = 0; i < mi->nr_banks; i++ )
- printk("RAM: %"PRIpaddr" - %"PRIpaddr"\n",
- mi->bank[i].start,
- mi->bank[i].start + mi->bank[i].size - 1);
- printk("\n");
- for ( i = 0 ; i < mods->nr_mods; i++ )
- printk("MODULE[%d]: %"PRIpaddr" - %"PRIpaddr" %-12s\n",
- i,
- mods->module[i].start,
- mods->module[i].start + mods->module[i].size - 1,
- boot_module_kind_as_string(mods->module[i].kind));
-
- for ( i = 0; i < mem_resv->nr_banks; i++ )
- {
- printk(" RESVD[%u]: %"PRIpaddr" - %"PRIpaddr"\n", i,
- mem_resv->bank[i].start,
- mem_resv->bank[i].start + mem_resv->bank[i].size - 1);
- }
-#ifdef CONFIG_STATIC_SHM
- early_print_info_shmem();
-#endif
- printk("\n");
- for ( i = 0 ; i < cmds->nr_mods; i++ )
- printk("CMDLINE[%"PRIpaddr"]:%s %s\n", cmds->cmdline[i].start,
- cmds->cmdline[i].dt_name,
- &cmds->cmdline[i].cmdline[0]);
- printk("\n");
-}
-
-/* This function assumes that memory regions are not overlapped */
-static int __init cmp_memory_node(const void *key, const void *elem)
-{
- const struct membank *handler0 = key;
- const struct membank *handler1 = elem;
-
- if ( handler0->start < handler1->start )
- return -1;
-
- if ( handler0->start >= (handler1->start + handler1->size) )
- return 1;
-
- return 0;
-}
-
-static void __init swap_memory_node(void *_a, void *_b, size_t size)
-{
- struct membank *a = _a, *b = _b;
-
- SWAP(*a, *b);
-}
-
-/**
- * boot_fdt_info - initialize bootinfo from a DTB
- * @fdt: flattened device tree binary
- *
- * Returns the size of the DTB.
- */
-size_t __init boot_fdt_info(const void *fdt, paddr_t paddr)
-{
- struct membanks *reserved_mem = bootinfo_get_reserved_mem();
- struct membanks *mem = bootinfo_get_mem();
- unsigned int i;
- int nr_rsvd;
- int ret;
-
- ret = fdt_check_header(fdt);
- if ( ret < 0 )
- panic("No valid device tree\n");
-
- add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), false);
-
- nr_rsvd = fdt_num_mem_rsv(fdt);
- if ( nr_rsvd < 0 )
- panic("Parsing FDT memory reserve map failed (%d)\n", nr_rsvd);
+ dt_start = dt_next_cell(address_cells, cell);
+ dt_size = dt_next_cell(size_cells, cell);
- for ( i = 0; i < nr_rsvd; i++ )
+ if ( dt_start != (paddr_t)dt_start )
{
- struct membank *bank;
- paddr_t s, sz;
-
- if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &s, &sz) < 0 )
- continue;
-
- if ( reserved_mem->nr_banks < reserved_mem->max_banks )
- {
- bank = &reserved_mem->bank[reserved_mem->nr_banks];
- bank->start = s;
- bank->size = sz;
- bank->type = MEMBANK_FDT_RESVMEM;
- reserved_mem->nr_banks++;
- }
- else
- panic("Cannot allocate reserved memory bank\n");
+ printk("Physical address greater than max width supported\n");
+ WARN();
}
- ret = device_tree_for_each_node(fdt, 0, early_scan_node, NULL);
- if ( ret )
- panic("Early FDT parsing failed (%d)\n", ret);
-
- /*
- * On Arm64 setup_directmap_mappings() expects to be called with the lowest
- * bank in memory first. There is no requirement that the DT will provide
- * the banks sorted in ascending order. So sort them through.
- */
- sort(mem->bank, mem->nr_banks, sizeof(struct membank),
- cmp_memory_node, swap_memory_node);
-
- early_print_info();
-
- return fdt_totalsize(fdt);
-}
-
-const __init char *boot_fdt_cmdline(const void *fdt)
-{
- int node;
- const struct fdt_property *prop;
-
- node = fdt_path_offset(fdt, "/chosen");
- if ( node < 0 )
- return NULL;
-
- prop = fdt_get_property(fdt, node, "xen,xen-bootargs", NULL);
- if ( prop == NULL )
+ if ( dt_size != (paddr_t)dt_size )
{
- struct bootcmdline *dom0_cmdline =
- boot_cmdline_find_by_kind(BOOTMOD_KERNEL);
-
- if (fdt_get_property(fdt, node, "xen,dom0-bootargs", NULL) ||
- ( dom0_cmdline && dom0_cmdline->cmdline[0] ) )
- prop = fdt_get_property(fdt, node, "bootargs", NULL);
+ printk("Physical size greater than max width supported\n");
+ WARN();
}
- if ( prop == NULL )
- return NULL;
-
- return prop->data;
-}
-/*
- * Wrapper to convert physical address from paddr_t to uint64_t and
- * invoke fdt_begin_node(). This is required as the physical address
- * provided as part of node name should not contain any leading
- * zeroes. Thus, one should use PRIx64 (instead of PRIpaddr) to append
- * unit (which contains the physical address) with name to generate a
- * node name.
- */
-int __init domain_fdt_begin_node(void *fdt, const char *name, uint64_t unit)
-{
/*
- * The size of the buffer to hold the longest possible string (i.e.
- * interrupt-controller@ + a 64-bit number + \0).
+ * Xen will truncate the address/size if it is greater than the maximum
+ * supported width and it will give an appropriate warning.
*/
- char buf[38];
- int ret;
-
- /* ePAPR 3.4 */
- ret = snprintf(buf, sizeof(buf), "%s@%"PRIx64, name, unit);
-
- if ( ret >= sizeof(buf) )
- {
- printk(XENLOG_ERR
- "Insufficient buffer. Minimum size required is %d\n",
- (ret + 1));
-
- return -FDT_ERR_TRUNCATED;
- }
-
- return fdt_begin_node(fdt, buf);
+ *start = dt_start;
+ *size = dt_size;
}
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/xen/common/device-tree/bootinfo-fdt.c b/xen/common/device-tree/bootinfo-fdt.c
new file mode 100644
index 0000000000..16036472f3
--- /dev/null
+++ b/xen/common/device-tree/bootinfo-fdt.c
@@ -0,0 +1,597 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Early Device Tree with bootinfo hooks
+ *
+ * Copyright (C) 2012-2014 Citrix Systems, Inc.
+ */
+
+#include <xen/bootinfo.h>
+#include <xen/device_tree.h>
+#include <xen/efi.h>
+#include <xen/init.h>
+#include <xen/kernel.h>
+#include <xen/lib.h>
+#include <xen/libfdt/libfdt-xen.h>
+#include <xen/sort.h>
+#include <xen/static-shmem.h>
+#include <xsm/xsm.h>
+#include <asm/setup.h>
+
+static void __init __maybe_unused build_assertions(void)
+{
+ /*
+ * Check that no padding is between struct membanks "bank" flexible array
+ * member and struct meminfo "bank" member
+ */
+ BUILD_BUG_ON((offsetof(struct membanks, bank) !=
+ offsetof(struct meminfo, bank)));
+ /* Ensure "struct membanks" and "struct membank" are equally aligned */
+ BUILD_BUG_ON(alignof(struct membanks) != alignof(struct membank));
+}
+
+static bool __init device_tree_node_is_available(const void *fdt, int node)
+{
+ const char *status;
+ int len;
+
+ status = fdt_getprop(fdt, node, "status", &len);
+ if ( !status )
+ return true;
+
+ if ( len > 0 )
+ {
+ if ( !strcmp(status, "ok") || !strcmp(status, "okay") )
+ return true;
+ }
+
+ return false;
+}
+
+static bool __init device_tree_node_matches(const void *fdt, int node,
+ const char *match)
+{
+ const char *name;
+ size_t match_len;
+
+ name = fdt_get_name(fdt, node, NULL);
+ match_len = strlen(match);
+
+ /* Match both "match" and "match@..." patterns but not
+ "match-foo". */
+ return strncmp(name, match, match_len) == 0
+ && (name[match_len] == '@' || name[match_len] == '\0');
+}
+
+static bool __init device_tree_node_compatible(const void *fdt, int node,
+ const char *match)
+{
+ int len, l;
+ const void *prop;
+
+ prop = fdt_getprop(fdt, node, "compatible", &len);
+ if ( prop == NULL )
+ return false;
+
+ while ( len > 0 ) {
+ if ( !dt_compat_cmp(prop, match) )
+ return true;
+ l = strlen(prop) + 1;
+ prop += l;
+ len -= l;
+ }
+
+ return false;
+}
+
+/*
+ * Check if a node is a proper /memory node according to Devicetree
+ * Specification v0.4, chapter 3.4.
+ */
+static bool __init device_tree_is_memory_node(const void *fdt, int node,
+ int depth)
+{
+ const char *type;
+ int len;
+
+ if ( depth != 1 )
+ return false;
+
+ if ( !device_tree_node_matches(fdt, node, "memory") )
+ return false;
+
+ type = fdt_getprop(fdt, node, "device_type", &len);
+ if ( !type )
+ return false;
+
+ if ( (len <= strlen("memory")) || strcmp(type, "memory") )
+ return false;
+
+ return true;
+}
+
+static int __init device_tree_get_meminfo(const void *fdt, int node,
+ const char *prop_name,
+ u32 address_cells, u32 size_cells,
+ struct membanks *mem,
+ enum membank_type type)
+{
+ const struct fdt_property *prop;
+ unsigned int i, banks;
+ const __be32 *cell;
+ u32 reg_cells = address_cells + size_cells;
+ paddr_t start, size;
+
+ if ( !device_tree_node_is_available(fdt, node) )
+ return 0;
+
+ if ( address_cells < 1 || size_cells < 1 )
+ {
+ printk("fdt: property `%s': invalid #address-cells or #size-cells",
+ prop_name);
+ return -EINVAL;
+ }
+
+ prop = fdt_get_property(fdt, node, prop_name, NULL);
+ if ( !prop )
+ return -ENOENT;
+
+ cell = (const __be32 *)prop->data;
+ banks = fdt32_to_cpu(prop->len) / (reg_cells * sizeof (u32));
+
+ for ( i = 0; i < banks && mem->nr_banks < mem->max_banks; i++ )
+ {
+ device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
+ /*
+ * Some valid device trees, such as those generated by OpenPOWER
+ * skiboot firmware, expose all reserved memory regions in the
+ * FDT memory reservation block AND in the reserved-memory node which
+ * has already been parsed. Thus, any matching overlaps in the
+ * reserved_mem banks should be ignored.
+ */
+ if ( mem == bootinfo_get_reserved_mem() &&
+ check_reserved_regions_overlap(start, size, true) )
+ return -EINVAL;
+ /* Some DT may describe empty bank, ignore them */
+ if ( !size )
+ continue;
+ mem->bank[mem->nr_banks].start = start;
+ mem->bank[mem->nr_banks].size = size;
+ mem->bank[mem->nr_banks].type = type;
+ mem->nr_banks++;
+ }
+
+ if ( i < banks )
+ {
+ printk("Warning: Max number of supported memory regions reached.\n");
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+static int __init process_memory_node(const void *fdt, int node,
+ const char *name, int depth,
+ u32 address_cells, u32 size_cells,
+ struct membanks *mem)
+{
+ return device_tree_get_meminfo(fdt, node, "reg", address_cells, size_cells,
+ mem, MEMBANK_DEFAULT);
+}
+
+static int __init process_reserved_memory_node(const void *fdt, int node,
+ const char *name, int depth,
+ u32 address_cells,
+ u32 size_cells,
+ void *data)
+{
+ int rc = process_memory_node(fdt, node, name, depth, address_cells,
+ size_cells, data);
+
+ if ( rc == -ENOSPC )
+ panic("Max number of supported reserved-memory regions reached.\n");
+ else if ( rc != -ENOENT )
+ return rc;
+ return 0;
+}
+
+static int __init process_reserved_memory(const void *fdt, int node,
+ const char *name, int depth,
+ u32 address_cells, u32 size_cells)
+{
+ return device_tree_for_each_node(fdt, node,
+ process_reserved_memory_node,
+ bootinfo_get_reserved_mem());
+}
+
+static void __init process_multiboot_node(const void *fdt, int node,
+ const char *name,
+ u32 address_cells, u32 size_cells)
+{
+ static int __initdata kind_guess = 0;
+ const struct fdt_property *prop;
+ const __be32 *cell;
+ boot_module_kind kind;
+ paddr_t start, size;
+ int len;
+ /* sizeof("/chosen/") + DT_MAX_NAME + '/' + DT_MAX_NAME + '/0' => 92 */
+ char path[92];
+ int parent_node, ret;
+ bool domU;
+
+ parent_node = fdt_parent_offset(fdt, node);
+ ASSERT(parent_node >= 0);
+
+ /* Check that the node is under "/chosen" (first 7 chars of path) */
+ ret = fdt_get_path(fdt, node, path, sizeof (path));
+ if ( ret != 0 || strncmp(path, "/chosen", 7) )
+ return;
+
+ prop = fdt_get_property(fdt, node, "reg", &len);
+ if ( !prop )
+ panic("node %s missing `reg' property\n", name);
+
+ if ( len < dt_cells_to_size(address_cells + size_cells) )
+ panic("fdt: node `%s': `reg` property length is too short\n",
+ name);
+
+ cell = (const __be32 *)prop->data;
+ device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
+
+ if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
+ fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
+ kind = BOOTMOD_KERNEL;
+ else if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 ||
+ fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 )
+ kind = BOOTMOD_RAMDISK;
+ else if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 )
+ kind = BOOTMOD_XSM;
+ else if ( fdt_node_check_compatible(fdt, node, "multiboot,device-tree") == 0 )
+ kind = BOOTMOD_GUEST_DTB;
+ else if ( fdt_node_check_compatible(fdt, node, "multiboot,microcode") == 0 )
+ kind = BOOTMOD_MICROCODE;
+ else
+ kind = BOOTMOD_UNKNOWN;
+
+ /**
+ * Guess the kind of these first two unknowns respectively:
+ * (1) The first unknown must be kernel.
+ * (2) Detect the XSM Magic from the 2nd unknown:
+ * a. If it's XSM, set the kind as XSM, and that also means we
+ * won't load ramdisk;
+ * b. if it's not XSM, set the kind as ramdisk.
+ * So if user want to load ramdisk, it must be the 2nd unknown.
+ * We also detect the XSM Magic for the following unknowns,
+ * then set its kind according to the return value of has_xsm_magic.
+ */
+ if ( kind == BOOTMOD_UNKNOWN )
+ {
+ switch ( kind_guess++ )
+ {
+ case 0: kind = BOOTMOD_KERNEL; break;
+ case 1: kind = BOOTMOD_RAMDISK; break;
+ default: break;
+ }
+ if ( kind_guess > 1 && has_xsm_magic(start) )
+ kind = BOOTMOD_XSM;
+ }
+
+ domU = fdt_node_check_compatible(fdt, parent_node, "xen,domain") == 0;
+ add_boot_module(kind, start, size, domU);
+
+ prop = fdt_get_property(fdt, node, "bootargs", &len);
+ if ( !prop )
+ return;
+ add_boot_cmdline(fdt_get_name(fdt, parent_node, &len), prop->data,
+ kind, start, domU);
+}
+
+static int __init process_chosen_node(const void *fdt, int node,
+ const char *name,
+ u32 address_cells, u32 size_cells)
+{
+ const struct fdt_property *prop;
+ paddr_t start, end;
+ int len;
+
+ if ( fdt_get_property(fdt, node, "xen,static-heap", NULL) )
+ {
+ int rc;
+
+ printk("Checking for static heap in /chosen\n");
+
+ rc = device_tree_get_meminfo(fdt, node, "xen,static-heap",
+ address_cells, size_cells,
+ bootinfo_get_reserved_mem(),
+ MEMBANK_STATIC_HEAP);
+ if ( rc )
+ return rc;
+
+ using_static_heap = true;
+ }
+
+ printk("Checking for initrd in /chosen\n");
+
+ prop = fdt_get_property(fdt, node, "linux,initrd-start", &len);
+ if ( !prop )
+ /* No initrd present. */
+ return 0;
+ if ( len != sizeof(u32) && len != sizeof(u64) )
+ {
+ printk("linux,initrd-start property has invalid length %d\n", len);
+ return -EINVAL;
+ }
+ start = dt_read_paddr((const void *)&prop->data, dt_size_to_cells(len));
+
+ prop = fdt_get_property(fdt, node, "linux,initrd-end", &len);
+ if ( !prop )
+ {
+ printk("linux,initrd-end not present but -start was\n");
+ return -EINVAL;
+ }
+ if ( len != sizeof(u32) && len != sizeof(u64) )
+ {
+ printk("linux,initrd-end property has invalid length %d\n", len);
+ return -EINVAL;
+ }
+ end = dt_read_paddr((const void *)&prop->data, dt_size_to_cells(len));
+
+ if ( start >= end )
+ {
+ printk("linux,initrd limits invalid: %"PRIpaddr" >= %"PRIpaddr"\n",
+ start, end);
+ return -EINVAL;
+ }
+
+ printk("Initrd %"PRIpaddr"-%"PRIpaddr"\n", start, end - 1);
+
+ add_boot_module(BOOTMOD_RAMDISK, start, end-start, false);
+
+ return 0;
+}
+
+static int __init process_domain_node(const void *fdt, int node,
+ const char *name,
+ u32 address_cells, u32 size_cells)
+{
+ const struct fdt_property *prop;
+
+ printk("Checking for \"xen,static-mem\" in domain node\n");
+
+ prop = fdt_get_property(fdt, node, "xen,static-mem", NULL);
+ if ( !prop )
+ /* No "xen,static-mem" present. */
+ return 0;
+
+ return device_tree_get_meminfo(fdt, node, "xen,static-mem", address_cells,
+ size_cells, bootinfo_get_reserved_mem(),
+ MEMBANK_STATIC_DOMAIN);
+}
+
+#ifndef CONFIG_STATIC_SHM
+static inline int process_shm_node(const void *fdt, int node,
+ uint32_t address_cells, uint32_t size_cells)
+{
+ printk("CONFIG_STATIC_SHM must be enabled for parsing static shared"
+ " memory nodes\n");
+ return -EINVAL;
+}
+#endif
+
+static int __init early_scan_node(const void *fdt,
+ int node, const char *name, int depth,
+ u32 address_cells, u32 size_cells,
+ void *data)
+{
+ int rc = 0;
+
+ /*
+ * If Xen has been booted via UEFI, the memory banks are
+ * populated. So we should skip the parsing.
+ */
+ if ( !efi_enabled(EFI_BOOT) &&
+ device_tree_is_memory_node(fdt, node, depth) )
+ rc = process_memory_node(fdt, node, name, depth,
+ address_cells, size_cells, bootinfo_get_mem());
+ else if ( depth == 1 && !dt_node_cmp(name, "reserved-memory") )
+ rc = process_reserved_memory(fdt, node, name, depth,
+ address_cells, size_cells);
+ else if ( depth <= 3 && (device_tree_node_compatible(fdt, node, "xen,multiboot-module" ) ||
+ device_tree_node_compatible(fdt, node, "multiboot,module" )))
+ process_multiboot_node(fdt, node, name, address_cells, size_cells);
+ else if ( depth == 1 && device_tree_node_matches(fdt, node, "chosen") )
+ rc = process_chosen_node(fdt, node, name, address_cells, size_cells);
+ else if ( depth == 2 && device_tree_node_compatible(fdt, node, "xen,domain") )
+ rc = process_domain_node(fdt, node, name, address_cells, size_cells);
+ else if ( depth <= 3 && device_tree_node_compatible(fdt, node, "xen,domain-shared-memory-v1") )
+ rc = process_shm_node(fdt, node, address_cells, size_cells);
+
+ if ( rc < 0 )
+ printk("fdt: node `%s': parsing failed\n", name);
+ return rc;
+}
+
+static void __init early_print_info(void)
+{
+ const struct membanks *mi = bootinfo_get_mem();
+ const struct membanks *mem_resv = bootinfo_get_reserved_mem();
+ struct boot_modules *mods = &bootinfo.modules;
+ struct bootcmdlines *cmds = &bootinfo.cmdlines;
+ unsigned int i;
+
+ for ( i = 0; i < mi->nr_banks; i++ )
+ printk("RAM: %"PRIpaddr" - %"PRIpaddr"\n",
+ mi->bank[i].start,
+ mi->bank[i].start + mi->bank[i].size - 1);
+ printk("\n");
+ for ( i = 0 ; i < mods->nr_mods; i++ )
+ printk("MODULE[%d]: %"PRIpaddr" - %"PRIpaddr" %-12s\n",
+ i,
+ mods->module[i].start,
+ mods->module[i].start + mods->module[i].size - 1,
+ boot_module_kind_as_string(mods->module[i].kind));
+
+ for ( i = 0; i < mem_resv->nr_banks; i++ )
+ {
+ printk(" RESVD[%u]: %"PRIpaddr" - %"PRIpaddr"\n", i,
+ mem_resv->bank[i].start,
+ mem_resv->bank[i].start + mem_resv->bank[i].size - 1);
+ }
+#ifdef CONFIG_STATIC_SHM
+ early_print_info_shmem();
+#endif
+ printk("\n");
+ for ( i = 0 ; i < cmds->nr_mods; i++ )
+ printk("CMDLINE[%"PRIpaddr"]:%s %s\n", cmds->cmdline[i].start,
+ cmds->cmdline[i].dt_name,
+ &cmds->cmdline[i].cmdline[0]);
+ printk("\n");
+}
+
+/* This function assumes that memory regions are not overlapped */
+static int __init cmp_memory_node(const void *key, const void *elem)
+{
+ const struct membank *handler0 = key;
+ const struct membank *handler1 = elem;
+
+ if ( handler0->start < handler1->start )
+ return -1;
+
+ if ( handler0->start >= (handler1->start + handler1->size) )
+ return 1;
+
+ return 0;
+}
+
+static void __init swap_memory_node(void *_a, void *_b, size_t size)
+{
+ struct membank *a = _a, *b = _b;
+
+ SWAP(*a, *b);
+}
+
+/**
+ * boot_fdt_info - initialize bootinfo from a DTB
+ * @fdt: flattened device tree binary
+ *
+ * Returns the size of the DTB.
+ */
+size_t __init boot_fdt_info(const void *fdt, paddr_t paddr)
+{
+ struct membanks *reserved_mem = bootinfo_get_reserved_mem();
+ struct membanks *mem = bootinfo_get_mem();
+ unsigned int i;
+ int nr_rsvd;
+ int ret;
+
+ ret = fdt_check_header(fdt);
+ if ( ret < 0 )
+ panic("No valid device tree\n");
+
+ add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), false);
+
+ nr_rsvd = fdt_num_mem_rsv(fdt);
+ if ( nr_rsvd < 0 )
+ panic("Parsing FDT memory reserve map failed (%d)\n", nr_rsvd);
+
+ for ( i = 0; i < nr_rsvd; i++ )
+ {
+ struct membank *bank;
+ paddr_t s, sz;
+
+ if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &s, &sz) < 0 )
+ continue;
+
+ if ( reserved_mem->nr_banks < reserved_mem->max_banks )
+ {
+ bank = &reserved_mem->bank[reserved_mem->nr_banks];
+ bank->start = s;
+ bank->size = sz;
+ bank->type = MEMBANK_FDT_RESVMEM;
+ reserved_mem->nr_banks++;
+ }
+ else
+ panic("Cannot allocate reserved memory bank\n");
+ }
+
+ ret = device_tree_for_each_node(fdt, 0, early_scan_node, NULL);
+ if ( ret )
+ panic("Early FDT parsing failed (%d)\n", ret);
+
+ /*
+ * On Arm64 setup_directmap_mappings() expects to be called with the lowest
+ * bank in memory first. There is no requirement that the DT will provide
+ * the banks sorted in ascending order. So sort them through.
+ */
+ sort(mem->bank, mem->nr_banks, sizeof(struct membank),
+ cmp_memory_node, swap_memory_node);
+
+ early_print_info();
+
+ return fdt_totalsize(fdt);
+}
+
+const __init char *boot_fdt_cmdline(const void *fdt)
+{
+ int node;
+ const struct fdt_property *prop;
+
+ node = fdt_path_offset(fdt, "/chosen");
+ if ( node < 0 )
+ return NULL;
+
+ prop = fdt_get_property(fdt, node, "xen,xen-bootargs", NULL);
+ if ( prop == NULL )
+ {
+ struct bootcmdline *dom0_cmdline =
+ boot_cmdline_find_by_kind(BOOTMOD_KERNEL);
+
+ if (fdt_get_property(fdt, node, "xen,dom0-bootargs", NULL) ||
+ ( dom0_cmdline && dom0_cmdline->cmdline[0] ) )
+ prop = fdt_get_property(fdt, node, "bootargs", NULL);
+ }
+ if ( prop == NULL )
+ return NULL;
+
+ return prop->data;
+}
+
+/*
+ * Wrapper to convert physical address from paddr_t to uint64_t and
+ * invoke fdt_begin_node(). This is required as the physical address
+ * provided as part of node name should not contain any leading
+ * zeroes. Thus, one should use PRIx64 (instead of PRIpaddr) to append
+ * unit (which contains the physical address) with name to generate a
+ * node name.
+ */
+int __init domain_fdt_begin_node(void *fdt, const char *name, uint64_t unit)
+{
+ /*
+ * The size of the buffer to hold the longest possible string (i.e.
+ * interrupt-controller@ + a 64-bit number + \0).
+ */
+ char buf[38];
+ int ret;
+
+ /* ePAPR 3.4 */
+ ret = snprintf(buf, sizeof(buf), "%s@%"PRIx64, name, unit);
+
+ if ( ret >= sizeof(buf) )
+ {
+ printk(XENLOG_ERR
+ "Insufficient buffer. Minimum size required is %d\n",
+ (ret + 1));
+
+ return -FDT_ERR_TRUNCATED;
+ }
+
+ return fdt_begin_node(fdt, buf);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH v5 07/10] xen/dt: Extract helper to map nodes to module kinds
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
` (5 preceding siblings ...)
2025-07-01 10:57 ` [PATCH v5 06/10] xen/dt: Rename bootfdt.c -> bootinfo-fdt.c Alejandro Vallejo
@ 2025-07-01 10:57 ` Alejandro Vallejo
2025-07-01 10:57 ` [PATCH v5 08/10] xen: Split HAS_DEVICE_TREE in two Alejandro Vallejo
` (2 subsequent siblings)
9 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:57 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Daniel P. Smith
This will be required later by x86 code in order to do early identification
of boot modules when booting off a DTB.
Not a functional change.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
xen/common/device-tree/bootfdt.c | 18 ++++++++++++++++++
xen/common/device-tree/bootinfo-fdt.c | 16 +---------------
xen/include/xen/bootfdt.h | 7 +++++++
3 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/xen/common/device-tree/bootfdt.c b/xen/common/device-tree/bootfdt.c
index 0d8d9ea357..8218c0a10b 100644
--- a/xen/common/device-tree/bootfdt.c
+++ b/xen/common/device-tree/bootfdt.c
@@ -4,6 +4,24 @@
#include <xen/lib.h>
#include <xen/libfdt/libfdt.h>
+boot_module_kind __init fdt_node_to_kind(const void *fdt, int node)
+{
+ if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
+ fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
+ return BOOTMOD_KERNEL;
+ if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 ||
+ fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 )
+ return BOOTMOD_RAMDISK;
+ if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 )
+ return BOOTMOD_XSM;
+ if ( fdt_node_check_compatible(fdt, node, "multiboot,device-tree") == 0 )
+ return BOOTMOD_GUEST_DTB;
+ if ( fdt_node_check_compatible(fdt, node, "multiboot,microcode") == 0 )
+ return BOOTMOD_MICROCODE;
+
+ return BOOTMOD_UNKNOWN;
+}
+
u32 __init device_tree_get_u32(const void *fdt, int node,
const char *prop_name, u32 dflt)
{
diff --git a/xen/common/device-tree/bootinfo-fdt.c b/xen/common/device-tree/bootinfo-fdt.c
index 16036472f3..9b426c0a98 100644
--- a/xen/common/device-tree/bootinfo-fdt.c
+++ b/xen/common/device-tree/bootinfo-fdt.c
@@ -236,21 +236,7 @@ static void __init process_multiboot_node(const void *fdt, int node,
cell = (const __be32 *)prop->data;
device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
-
- if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
- fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
- kind = BOOTMOD_KERNEL;
- else if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 ||
- fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 )
- kind = BOOTMOD_RAMDISK;
- else if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 )
- kind = BOOTMOD_XSM;
- else if ( fdt_node_check_compatible(fdt, node, "multiboot,device-tree") == 0 )
- kind = BOOTMOD_GUEST_DTB;
- else if ( fdt_node_check_compatible(fdt, node, "multiboot,microcode") == 0 )
- kind = BOOTMOD_MICROCODE;
- else
- kind = BOOTMOD_UNKNOWN;
+ kind = fdt_node_to_kind(fdt, node);
/**
* Guess the kind of these first two unknowns respectively:
diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h
index ad6b11cb6d..bc5fc995b0 100644
--- a/xen/include/xen/bootfdt.h
+++ b/xen/include/xen/bootfdt.h
@@ -143,4 +143,11 @@ u32 device_tree_get_u32(const void *fdt, int node,
void device_tree_get_reg(const __be32 **cell, uint32_t address_cells,
uint32_t size_cells, paddr_t *start, paddr_t *size);
+/*
+ * Probe an FDT node thought to be a boot module to identify its kind.
+ *
+ * If correctly identified, returns the detected kind, otherwise BOOTMOD_UNKNOWN
+ */
+boot_module_kind fdt_node_to_kind(const void *fdt, int node);
+
#endif /* XEN_BOOTFDT_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH v5 08/10] xen: Split HAS_DEVICE_TREE in two
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
` (6 preceding siblings ...)
2025-07-01 10:57 ` [PATCH v5 07/10] xen/dt: Extract helper to map nodes to module kinds Alejandro Vallejo
@ 2025-07-01 10:57 ` Alejandro Vallejo
2025-07-02 13:30 ` Jan Beulich
2025-07-01 10:57 ` [PATCH v5 09/10] xen/dt: ifdef out DEV_DT-related bits from device_tree.{c,h} Alejandro Vallejo
2025-07-01 10:57 ` [PATCH v5 10/10] xen/dt: Allow CONFIG_DEVICE_TREE_PARSE to include device-tree/ Alejandro Vallejo
9 siblings, 1 reply; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:57 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Andrew Cooper, Anthony PERARD, Michal Orzel,
Jan Beulich, Julien Grall, Roger Pau Monné,
Stefano Stabellini, Bertrand Marquis, Volodymyr Babchuk,
Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
Oleksii Kurochko, Daniel P. Smith,
Marek Marczykowski-Górecki, Dario Faggioli, Juergen Gross,
George Dunlap
Moving forward the idea is for there to be:
1. Basic DT support: used by dom0less/hyperlaunch.
2. Full DT support: used for device discovery and HW setup.
Rename HAS_DEVICE_TREE to HAS_DEVICE_TREE_DISCOVERY to describe (2) and
create a new DEVICE_TREE_PARSE to describe (1).
Have DEVICE_TREE_PARSE selected by both HAS_DEVICE_TREE_DISCOVERY and
DOM0LESS_BOOT.
Add a dependency on STATIC_MEMORY for discovery, as it relies on
the memory map itself being described on the DTB.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
---
v5:
* Replaces the old "xen: Rename CONFIG_HAS_DEVICE_TREE
to CONFIG_HAS_DEVICE_TREE_DISCOVERY", though it renames
largely a rename.
One could imagine STATIC_MEMORY being adapted for x86, but it's
no small amount of work, so I shan't.
I didn't add Stefano's R-by because the patch seems functionally
different even if its diff is very similar.
---
xen/Kconfig.debug | 2 +-
xen/arch/arm/Kconfig | 2 +-
xen/arch/ppc/Kconfig | 2 +-
xen/arch/riscv/Kconfig | 2 +-
xen/common/Kconfig | 13 +++++++++----
xen/common/Makefile | 4 ++--
xen/common/device.c | 4 ++--
xen/common/efi/boot.c | 2 +-
xen/common/sched/Kconfig | 2 +-
xen/drivers/char/ns16550.c | 6 +++---
xen/drivers/passthrough/Makefile | 2 +-
xen/drivers/passthrough/iommu.c | 2 +-
xen/include/asm-generic/device.h | 10 +++++-----
xen/include/xen/iommu.h | 8 ++++----
xen/include/xsm/dummy.h | 4 ++--
xen/include/xsm/xsm.h | 12 ++++++------
xen/xsm/dummy.c | 2 +-
xen/xsm/flask/hooks.c | 6 +++---
xen/xsm/xsm_core.c | 4 ++--
xen/xsm/xsm_policy.c | 4 ++--
20 files changed, 49 insertions(+), 44 deletions(-)
diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
index 38a134fa3b..d900d926c5 100644
--- a/xen/Kconfig.debug
+++ b/xen/Kconfig.debug
@@ -92,7 +92,7 @@ config VERBOSE_DEBUG
config DEVICE_TREE_DEBUG
bool "Device tree debug messages"
- depends on HAS_DEVICE_TREE
+ depends on DEVICE_TREE_PARSE
help
Device tree parsing and DOM0 device tree building messages are
logged in the Xen ring buffer.
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 3f25da3ca5..74b16f7167 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -15,7 +15,7 @@ config ARM
select FUNCTION_ALIGNMENT_4B
select GENERIC_UART_INIT
select HAS_ALTERNATIVE if HAS_VMAP
- select HAS_DEVICE_TREE
+ select HAS_DEVICE_TREE_DISCOVERY
select HAS_DOM0LESS
select HAS_GRANT_CACHE_FLUSH if GRANT_TABLE
select HAS_STACK_PROTECTOR
diff --git a/xen/arch/ppc/Kconfig b/xen/arch/ppc/Kconfig
index 917f5d53a6..5bedf6055e 100644
--- a/xen/arch/ppc/Kconfig
+++ b/xen/arch/ppc/Kconfig
@@ -1,7 +1,7 @@
config PPC
def_bool y
select FUNCTION_ALIGNMENT_4B
- select HAS_DEVICE_TREE
+ select HAS_DEVICE_TREE_DISCOVERY
select HAS_UBSAN
select HAS_VMAP
diff --git a/xen/arch/riscv/Kconfig b/xen/arch/riscv/Kconfig
index 62c5b7ba34..8fd3c314ea 100644
--- a/xen/arch/riscv/Kconfig
+++ b/xen/arch/riscv/Kconfig
@@ -2,7 +2,7 @@ config RISCV
def_bool y
select FUNCTION_ALIGNMENT_16B
select GENERIC_BUG_FRAME
- select HAS_DEVICE_TREE
+ select HAS_DEVICE_TREE_DISCOVERY
select HAS_PMAP
select HAS_UBSAN
select HAS_VMAP
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index 6d784da839..98f6ea8764 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -14,7 +14,8 @@ config CORE_PARKING
config DOM0LESS_BOOT
bool "Dom0less boot support" if EXPERT
- depends on HAS_DOM0LESS && HAS_DEVICE_TREE && DOMAIN_BUILD_HELPERS
+ depends on HAS_DOM0LESS && DOMAIN_BUILD_HELPERS
+ select DEVICE_TREE_PARSE
default y
help
Dom0less boot support enables Xen to create and start domU guests during
@@ -85,7 +86,11 @@ config HAS_ALTERNATIVE
config HAS_COMPAT
bool
-config HAS_DEVICE_TREE
+config HAS_DEVICE_TREE_DISCOVERY
+ bool
+ select DEVICE_TREE_PARSE
+
+config DEVICE_TREE_PARSE
bool
select LIBFDT
@@ -154,7 +159,7 @@ config NUMA
config STATIC_MEMORY
bool "Static Allocation Support (UNSUPPORTED)" if UNSUPPORTED
- depends on DOM0LESS_BOOT
+ depends on DOM0LESS_BOOT && HAS_DEVICE_TREE_DISCOVERY
help
Static Allocation refers to system or sub-system(domains) for
which memory areas are pre-defined by configuration using physical
@@ -553,7 +558,7 @@ config DOM0_MEM
config DTB_FILE
string "Absolute path to device tree blob"
- depends on HAS_DEVICE_TREE
+ depends on HAS_DEVICE_TREE_DISCOVERY
help
When using a bootloader that has no device tree support or when there
is no bootloader at all, use this option to specify the absolute path
diff --git a/xen/common/Makefile b/xen/common/Makefile
index 98f0873056..d541fbcf49 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -6,9 +6,9 @@ obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
obj-$(CONFIG_CORE_PARKING) += core_parking.o
obj-y += cpu.o
obj-$(CONFIG_DEBUG_TRACE) += debugtrace.o
-obj-$(CONFIG_HAS_DEVICE_TREE) += device.o
+obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += device.o
obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device.o
-obj-$(CONFIG_HAS_DEVICE_TREE) += device-tree/
+obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += device-tree/
obj-$(CONFIG_IOREQ_SERVER) += dm.o
obj-y += domain.o
obj-y += event_2l.o
diff --git a/xen/common/device.c b/xen/common/device.c
index 33e0d58f2f..0c0afad49f 100644
--- a/xen/common/device.c
+++ b/xen/common/device.c
@@ -11,7 +11,7 @@
#include <asm/device.h>
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
extern const struct device_desc _sdevice[], _edevice[];
@@ -56,7 +56,7 @@ enum device_class device_get_class(const struct dt_device_node *dev)
return DEVICE_UNKNOWN;
}
-#endif
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
#ifdef CONFIG_ACPI
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 9306dc8953..31b4039049 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -623,7 +623,7 @@ static int __init __maybe_unused set_color(uint32_t mask, int bpp,
return max(*pos + *sz, bpp);
}
-#ifndef CONFIG_HAS_DEVICE_TREE
+#ifndef CONFIG_HAS_DEVICE_TREE_DISCOVERY
static int __init efi_check_dt_boot(const EFI_LOADED_IMAGE *loaded_image)
{
return 0;
diff --git a/xen/common/sched/Kconfig b/xen/common/sched/Kconfig
index 18ca1ce7ab..1fb622e6cf 100644
--- a/xen/common/sched/Kconfig
+++ b/xen/common/sched/Kconfig
@@ -67,7 +67,7 @@ endmenu
config BOOT_TIME_CPUPOOLS
bool "Create cpupools at boot time"
- depends on HAS_DEVICE_TREE
+ depends on HAS_DEVICE_TREE_DISCOVERY
help
Creates cpupools during boot time and assigns cpus to them. Cpupools
options can be specified in the device tree.
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 6b4fb4ad31..c1c08b235e 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -34,7 +34,7 @@
#include <xen/8250-uart.h>
#include <xen/vmap.h>
#include <asm/io.h>
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
#include <asm/device.h>
#endif
#ifdef CONFIG_X86
@@ -1766,7 +1766,7 @@ void __init ns16550_init(int index, struct ns16550_defaults *defaults)
#endif /* CONFIG_X86 */
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
const void *data)
{
@@ -1845,7 +1845,7 @@ DT_DEVICE_START(ns16550, "NS16550 UART", DEVICE_SERIAL)
.init = ns16550_uart_dt_init,
DT_DEVICE_END
-#endif /* HAS_DEVICE_TREE */
+#endif /* HAS_DEVICE_TREE_DISCOVERY */
#if defined(CONFIG_ACPI) && defined(CONFIG_ARM)
#include <xen/acpi.h>
diff --git a/xen/drivers/passthrough/Makefile b/xen/drivers/passthrough/Makefile
index a1621540b7..eb4aeafb42 100644
--- a/xen/drivers/passthrough/Makefile
+++ b/xen/drivers/passthrough/Makefile
@@ -5,6 +5,6 @@ obj-$(CONFIG_ARM) += arm/
obj-y += iommu.o
obj-$(CONFIG_HAS_PCI) += pci.o
-obj-$(CONFIG_HAS_DEVICE_TREE) += device_tree.o
+obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += device_tree.o
obj-$(CONFIG_HAS_PCI) += ats.o
obj-$(CONFIG_HAS_PCI_MSI) += msi.o
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 16aad86973..c9425d6971 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -638,7 +638,7 @@ int iommu_do_domctl(
ret = iommu_do_pci_domctl(domctl, d, u_domctl);
#endif
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
if ( ret == -ENODEV )
ret = iommu_do_dt_domctl(domctl, d, u_domctl);
#endif
diff --git a/xen/include/asm-generic/device.h b/xen/include/asm-generic/device.h
index 1acd1ba1d8..3bd97e33c5 100644
--- a/xen/include/asm-generic/device.h
+++ b/xen/include/asm-generic/device.h
@@ -6,7 +6,7 @@
enum device_type
{
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
DEV_DT,
#endif
DEV_PCI
@@ -26,7 +26,7 @@ enum device_class
struct device
{
enum device_type type;
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
struct dt_device_node *of_node; /* Used by drivers imported from Linux */
#endif
#ifdef CONFIG_HAS_PASSTHROUGH
@@ -37,7 +37,7 @@ struct device
typedef struct device device_t;
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
#include <xen/device_tree.h>
@@ -87,9 +87,9 @@ struct device_desc {
int (*init)(struct dt_device_node *dev, const void *data);
};
-#else /* !CONFIG_HAS_DEVICE_TREE */
+#else /* !CONFIG_HAS_DEVICE_TREE_DISCOVERY */
#define dev_is_dt(dev) ((void)(dev), false)
-#endif /* CONFIG_HAS_DEVICE_TREE */
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
#define dev_is_pci(dev) ((dev)->type == DEV_PCI)
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index 832775754b..5483840645 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -230,7 +230,7 @@ struct msi_msg;
#define PT_IRQ_TIME_OUT MILLISECS(8)
#endif /* HAS_PCI */
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
#include <xen/device_tree.h>
#ifdef CONFIG_HAS_PASSTHROUGH
@@ -288,7 +288,7 @@ static inline int iommu_release_dt_devices(struct domain *d)
#endif /* HAS_PASSTHROUGH */
-#endif /* HAS_DEVICE_TREE */
+#endif /* HAS_DEVICE_TREE_DISCOVERY */
struct page_info;
@@ -355,7 +355,7 @@ struct iommu_ops {
int (*get_reserved_device_memory)(iommu_grdm_t *func, void *ctxt);
void (*dump_page_tables)(struct domain *d);
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
/*
* All IOMMU drivers which support generic IOMMU DT bindings should use
* this callback. This is a way for the framework to provide the driver
@@ -403,7 +403,7 @@ struct domain_iommu {
/* iommu_ops */
const struct iommu_ops *platform_ops;
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
/* List of DT devices assigned to this domain */
struct list_head dt_devices;
#endif
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 9227205fcd..12792c3a43 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -423,7 +423,7 @@ static XSM_INLINE int cf_check xsm_deassign_device(
#endif /* HAS_PASSTHROUGH && HAS_PCI */
-#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
+#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
static XSM_INLINE int cf_check xsm_assign_dtdevice(
XSM_DEFAULT_ARG struct domain *d, const char *dtpath)
{
@@ -438,7 +438,7 @@ static XSM_INLINE int cf_check xsm_deassign_dtdevice(
return xsm_default_action(action, current->domain, d);
}
-#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
+#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
static XSM_INLINE int cf_check xsm_resource_plug_core(XSM_DEFAULT_VOID)
{
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 24acc16125..abeb4b04ad 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -125,7 +125,7 @@ struct xsm_ops {
int (*deassign_device)(struct domain *d, uint32_t machine_bdf);
#endif
-#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
+#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
int (*assign_dtdevice)(struct domain *d, const char *dtpath);
int (*deassign_dtdevice)(struct domain *d, const char *dtpath);
#endif
@@ -535,7 +535,7 @@ static inline int xsm_deassign_device(
}
#endif /* HAS_PASSTHROUGH && HAS_PCI) */
-#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
+#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
static inline int xsm_assign_dtdevice(
xsm_default_t def, struct domain *d, const char *dtpath)
{
@@ -548,7 +548,7 @@ static inline int xsm_deassign_dtdevice(
return alternative_call(xsm_ops.deassign_dtdevice, d, dtpath);
}
-#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
+#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
static inline int xsm_resource_plug_pci(xsm_default_t def, uint32_t machine_bdf)
{
@@ -789,7 +789,7 @@ int xsm_multiboot_policy_init(
struct boot_info *bi, void **policy_buffer, size_t *policy_size);
#endif
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
/*
* Initialize XSM
*
@@ -839,7 +839,7 @@ static inline int xsm_multiboot_init(struct boot_info *bi)
}
#endif
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
static inline int xsm_dt_init(void)
{
return 0;
@@ -849,7 +849,7 @@ static inline bool has_xsm_magic(paddr_t start)
{
return false;
}
-#endif /* CONFIG_HAS_DEVICE_TREE */
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
#endif /* CONFIG_XSM */
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 93fbfc43cc..7f67683839 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -81,7 +81,7 @@ static const struct xsm_ops __initconst_cf_clobber dummy_ops = {
.deassign_device = xsm_deassign_device,
#endif
-#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
+#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
.assign_dtdevice = xsm_assign_dtdevice,
.deassign_dtdevice = xsm_deassign_dtdevice,
#endif
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 6a53487ea4..78bad6e56b 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1456,7 +1456,7 @@ static int cf_check flask_deassign_device(
}
#endif /* HAS_PASSTHROUGH && HAS_PCI */
-#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
+#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
static int flask_test_assign_dtdevice(const char *dtpath)
{
uint32_t rsid;
@@ -1517,7 +1517,7 @@ static int cf_check flask_deassign_dtdevice(
return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE,
NULL);
}
-#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
+#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
static int cf_check flask_platform_op(uint32_t op)
{
@@ -1981,7 +1981,7 @@ static const struct xsm_ops __initconst_cf_clobber flask_ops = {
.deassign_device = flask_deassign_device,
#endif
-#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
+#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
.assign_dtdevice = flask_assign_dtdevice,
.deassign_dtdevice = flask_deassign_dtdevice,
#endif
diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c
index f255fb63bf..b7e864a874 100644
--- a/xen/xsm/xsm_core.c
+++ b/xen/xsm/xsm_core.c
@@ -25,7 +25,7 @@
#include <asm/setup.h>
#endif
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
#include <asm/setup.h>
#endif
@@ -166,7 +166,7 @@ int __init xsm_multiboot_init(struct boot_info *bi)
}
#endif
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
int __init xsm_dt_init(void)
{
int ret = 0;
diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c
index 1b4030edb4..3f04375347 100644
--- a/xen/xsm/xsm_policy.c
+++ b/xen/xsm/xsm_policy.c
@@ -24,7 +24,7 @@
#include <asm/setup.h>
#endif
#include <xen/bitops.h>
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
# include <asm/setup.h>
# include <xen/device_tree.h>
#endif
@@ -65,7 +65,7 @@ int __init xsm_multiboot_policy_init(
}
#endif
-#ifdef CONFIG_HAS_DEVICE_TREE
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
int __init xsm_dt_policy_init(void **policy_buffer, size_t *policy_size)
{
struct boot_module *mod = boot_module_find_by_kind(BOOTMOD_XSM);
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [PATCH v5 08/10] xen: Split HAS_DEVICE_TREE in two
2025-07-01 10:57 ` [PATCH v5 08/10] xen: Split HAS_DEVICE_TREE in two Alejandro Vallejo
@ 2025-07-02 13:30 ` Jan Beulich
2025-07-02 15:28 ` Alejandro Vallejo
0 siblings, 1 reply; 28+ messages in thread
From: Jan Beulich @ 2025-07-02 13:30 UTC (permalink / raw)
To: Alejandro Vallejo
Cc: Andrew Cooper, Anthony PERARD, Michal Orzel, Julien Grall,
Roger Pau Monné, Stefano Stabellini, Bertrand Marquis,
Volodymyr Babchuk, Shawn Anastasio, Alistair Francis,
Bob Eshleman, Connor Davis, Oleksii Kurochko, Daniel P. Smith,
Marek Marczykowski-Górecki, Dario Faggioli, Juergen Gross,
George Dunlap, xen-devel
On 01.07.2025 12:57, Alejandro Vallejo wrote:
> @@ -85,7 +86,11 @@ config HAS_ALTERNATIVE
> config HAS_COMPAT
> bool
>
> -config HAS_DEVICE_TREE
> +config HAS_DEVICE_TREE_DISCOVERY
> + bool
> + select DEVICE_TREE_PARSE
> +
> +config DEVICE_TREE_PARSE
> bool
> select LIBFDT
>
We're in the middle of various ([almost] alphabetically sorted) HAS_* here.
Thus DEVICE_TREE_PARSE wants to move elsewhere. Or we want to move back to
naming it HAS_DEVICE_TREE_PARSE, but I think there was a reason why we didn't
want it like that? Just that I don't recall what that reason was ...
> --- a/xen/common/sched/Kconfig
> +++ b/xen/common/sched/Kconfig
> @@ -67,7 +67,7 @@ endmenu
>
> config BOOT_TIME_CPUPOOLS
> bool "Create cpupools at boot time"
> - depends on HAS_DEVICE_TREE
> + depends on HAS_DEVICE_TREE_DISCOVERY
Is this correct? CPU pool creation isn't driven by DT discovery, I thought,
but is a software-only thing much like dom0less?
> --- a/xen/include/xsm/dummy.h
> +++ b/xen/include/xsm/dummy.h
> @@ -423,7 +423,7 @@ static XSM_INLINE int cf_check xsm_deassign_device(
>
> #endif /* HAS_PASSTHROUGH && HAS_PCI */
>
> -#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
> +#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
> static XSM_INLINE int cf_check xsm_assign_dtdevice(
> XSM_DEFAULT_ARG struct domain *d, const char *dtpath)
> {
> @@ -438,7 +438,7 @@ static XSM_INLINE int cf_check xsm_deassign_dtdevice(
> return xsm_default_action(action, current->domain, d);
> }
>
> -#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
> +#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
Here I'm similarly unsure: Pass-through again isn't a platform thing, is it?
> @@ -789,7 +789,7 @@ int xsm_multiboot_policy_init(
> struct boot_info *bi, void **policy_buffer, size_t *policy_size);
> #endif
>
> -#ifdef CONFIG_HAS_DEVICE_TREE
> +#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
> /*
> * Initialize XSM
> *
> @@ -839,7 +839,7 @@ static inline int xsm_multiboot_init(struct boot_info *bi)
> }
> #endif
>
> -#ifdef CONFIG_HAS_DEVICE_TREE
> +#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
> static inline int xsm_dt_init(void)
> {
> return 0;
> @@ -849,7 +849,7 @@ static inline bool has_xsm_magic(paddr_t start)
> {
> return false;
> }
> -#endif /* CONFIG_HAS_DEVICE_TREE */
> +#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
The situation is yet less clear to me here.
Jan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 08/10] xen: Split HAS_DEVICE_TREE in two
2025-07-02 13:30 ` Jan Beulich
@ 2025-07-02 15:28 ` Alejandro Vallejo
2025-07-03 5:55 ` Jan Beulich
0 siblings, 1 reply; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-02 15:28 UTC (permalink / raw)
To: Jan Beulich
Cc: Andrew Cooper, Anthony PERARD, Michal Orzel, Julien Grall,
Roger Pau Monné, Stefano Stabellini, Bertrand Marquis,
Volodymyr Babchuk, Shawn Anastasio, Alistair Francis,
Bob Eshleman, Connor Davis, Oleksii Kurochko, Daniel P. Smith,
Marek Marczykowski-Górecki, Dario Faggioli, Juergen Gross,
George Dunlap, xen-devel
On Wed Jul 2, 2025 at 3:30 PM CEST, Jan Beulich wrote:
> On 01.07.2025 12:57, Alejandro Vallejo wrote:
>> @@ -85,7 +86,11 @@ config HAS_ALTERNATIVE
>> config HAS_COMPAT
>> bool
>>
>> -config HAS_DEVICE_TREE
>> +config HAS_DEVICE_TREE_DISCOVERY
>> + bool
>> + select DEVICE_TREE_PARSE
>> +
>> +config DEVICE_TREE_PARSE
>> bool
>> select LIBFDT
>>
>
> We're in the middle of various ([almost] alphabetically sorted) HAS_* here.
> Thus DEVICE_TREE_PARSE wants to move elsewhere. Or we want to move back to
> naming it HAS_DEVICE_TREE_PARSE, but I think there was a reason why we didn't
> want it like that? Just that I don't recall what that reason was ...
AIUI, HAS_X are options selected by your architecture. Things that tell you
whether X is supported in your arch or not. In this case, HAS_DEVICE_TREE_PARSE
would be supported everywhere, while DEVICE_TREE_PARSE is not an arch property,
but an option selected by DOM0LESS_BOOT (which appears in menuconfig) and
HAS_DEVICE_TREE_DISCOVERY.
I can move it elsewhere, but it's unfortunate to separate two so closely
related options.
>
>> --- a/xen/common/sched/Kconfig
>> +++ b/xen/common/sched/Kconfig
>> @@ -67,7 +67,7 @@ endmenu
>>
>> config BOOT_TIME_CPUPOOLS
>> bool "Create cpupools at boot time"
>> - depends on HAS_DEVICE_TREE
>> + depends on HAS_DEVICE_TREE_DISCOVERY
>
> Is this correct? CPU pool creation isn't driven by DT discovery, I thought,
> but is a software-only thing much like dom0less?
In principle it would be possible. But I haven't tested the configuration, so
I'd rather err on the side of caution and not enable features prematurely.
In time, this should become DOM0LESS_BOOT || HAS_DEVICE_TREE_DISCOVERY.
>
>> --- a/xen/include/xsm/dummy.h
>> +++ b/xen/include/xsm/dummy.h
>> @@ -423,7 +423,7 @@ static XSM_INLINE int cf_check xsm_deassign_device(
>>
>> #endif /* HAS_PASSTHROUGH && HAS_PCI */
>>
>> -#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
>> +#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
>> static XSM_INLINE int cf_check xsm_assign_dtdevice(
>> XSM_DEFAULT_ARG struct domain *d, const char *dtpath)
>> {
>> @@ -438,7 +438,7 @@ static XSM_INLINE int cf_check xsm_deassign_dtdevice(
>> return xsm_default_action(action, current->domain, d);
>> }
>>
>> -#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
>> +#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
>
> Here I'm similarly unsure: Pass-through again isn't a platform thing, is it?
This has to do strictly with passthrough of devices discovered via DT.
>
>> @@ -789,7 +789,7 @@ int xsm_multiboot_policy_init(
>> struct boot_info *bi, void **policy_buffer, size_t *policy_size);
>> #endif
>>
>> -#ifdef CONFIG_HAS_DEVICE_TREE
>> +#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
>> /*
>> * Initialize XSM
>> *
>> @@ -839,7 +839,7 @@ static inline int xsm_multiboot_init(struct boot_info *bi)
>> }
>> #endif
>>
>> -#ifdef CONFIG_HAS_DEVICE_TREE
>> +#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
>> static inline int xsm_dt_init(void)
>> {
>> return 0;
>> @@ -849,7 +849,7 @@ static inline bool has_xsm_magic(paddr_t start)
>> {
>> return false;
>> }
>> -#endif /* CONFIG_HAS_DEVICE_TREE */
>> +#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
>
> The situation is yet less clear to me here
XSM segregates multibooting and DT-booting, this refers strictly to the latter.
By DT-booting I mean platforms where the DT is given by the platform rather
than the user as a module.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 08/10] xen: Split HAS_DEVICE_TREE in two
2025-07-02 15:28 ` Alejandro Vallejo
@ 2025-07-03 5:55 ` Jan Beulich
2025-07-03 10:04 ` Alejandro Vallejo
0 siblings, 1 reply; 28+ messages in thread
From: Jan Beulich @ 2025-07-03 5:55 UTC (permalink / raw)
To: Alejandro Vallejo
Cc: Andrew Cooper, Anthony PERARD, Michal Orzel, Julien Grall,
Roger Pau Monné, Stefano Stabellini, Bertrand Marquis,
Volodymyr Babchuk, Shawn Anastasio, Alistair Francis,
Bob Eshleman, Connor Davis, Oleksii Kurochko, Daniel P. Smith,
Marek Marczykowski-Górecki, Dario Faggioli, Juergen Gross,
George Dunlap, xen-devel
On 02.07.2025 17:28, Alejandro Vallejo wrote:
> On Wed Jul 2, 2025 at 3:30 PM CEST, Jan Beulich wrote:
>> On 01.07.2025 12:57, Alejandro Vallejo wrote:
>>> @@ -85,7 +86,11 @@ config HAS_ALTERNATIVE
>>> config HAS_COMPAT
>>> bool
>>>
>>> -config HAS_DEVICE_TREE
>>> +config HAS_DEVICE_TREE_DISCOVERY
>>> + bool
>>> + select DEVICE_TREE_PARSE
>>> +
>>> +config DEVICE_TREE_PARSE
>>> bool
>>> select LIBFDT
>>>
>>
>> We're in the middle of various ([almost] alphabetically sorted) HAS_* here.
>> Thus DEVICE_TREE_PARSE wants to move elsewhere. Or we want to move back to
>> naming it HAS_DEVICE_TREE_PARSE, but I think there was a reason why we didn't
>> want it like that? Just that I don't recall what that reason was ...
>
> AIUI, HAS_X are options selected by your architecture. Things that tell you
> whether X is supported in your arch or not. In this case, HAS_DEVICE_TREE_PARSE
> would be supported everywhere, while DEVICE_TREE_PARSE is not an arch property,
> but an option selected by DOM0LESS_BOOT (which appears in menuconfig) and
> HAS_DEVICE_TREE_DISCOVERY.
It's on the edge here, I agree. Yet we have other cases where one HAS_* selects
another HAS_*, and I think we're in the process of gaining more.
> I can move it elsewhere, but it's unfortunate to separate two so closely
> related options.
Imo there's only one of two options - move it or rename it.
>>> --- a/xen/common/sched/Kconfig
>>> +++ b/xen/common/sched/Kconfig
>>> @@ -67,7 +67,7 @@ endmenu
>>>
>>> config BOOT_TIME_CPUPOOLS
>>> bool "Create cpupools at boot time"
>>> - depends on HAS_DEVICE_TREE
>>> + depends on HAS_DEVICE_TREE_DISCOVERY
>>
>> Is this correct? CPU pool creation isn't driven by DT discovery, I thought,
>> but is a software-only thing much like dom0less?
>
> In principle it would be possible. But I haven't tested the configuration, so
> I'd rather err on the side of caution and not enable features prematurely.
>
> In time, this should become DOM0LESS_BOOT || HAS_DEVICE_TREE_DISCOVERY.
DEVICE_TREE_PARSE, that is?
>>> --- a/xen/include/xsm/dummy.h
>>> +++ b/xen/include/xsm/dummy.h
>>> @@ -423,7 +423,7 @@ static XSM_INLINE int cf_check xsm_deassign_device(
>>>
>>> #endif /* HAS_PASSTHROUGH && HAS_PCI */
>>>
>>> -#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
>>> +#if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
>>> static XSM_INLINE int cf_check xsm_assign_dtdevice(
>>> XSM_DEFAULT_ARG struct domain *d, const char *dtpath)
>>> {
>>> @@ -438,7 +438,7 @@ static XSM_INLINE int cf_check xsm_deassign_dtdevice(
>>> return xsm_default_action(action, current->domain, d);
>>> }
>>>
>>> -#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
>>> +#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
>>
>> Here I'm similarly unsure: Pass-through again isn't a platform thing, is it?
>
> This has to do strictly with passthrough of devices discovered via DT.
Wait, no. You discover devices via DT, but you don't "discover" what domain
to pass them through. For the latter, DT is again only a vehicle.
>>> @@ -789,7 +789,7 @@ int xsm_multiboot_policy_init(
>>> struct boot_info *bi, void **policy_buffer, size_t *policy_size);
>>> #endif
>>>
>>> -#ifdef CONFIG_HAS_DEVICE_TREE
>>> +#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
>>> /*
>>> * Initialize XSM
>>> *
>>> @@ -839,7 +839,7 @@ static inline int xsm_multiboot_init(struct boot_info *bi)
>>> }
>>> #endif
>>>
>>> -#ifdef CONFIG_HAS_DEVICE_TREE
>>> +#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
>>> static inline int xsm_dt_init(void)
>>> {
>>> return 0;
>>> @@ -849,7 +849,7 @@ static inline bool has_xsm_magic(paddr_t start)
>>> {
>>> return false;
>>> }
>>> -#endif /* CONFIG_HAS_DEVICE_TREE */
>>> +#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
>>
>> The situation is yet less clear to me here
>
> XSM segregates multibooting and DT-booting, this refers strictly to the latter.
>
> By DT-booting I mean platforms where the DT is given by the platform rather
> than the user as a module.
Yet the platform as such hardly even knows of XSM (or in fact any of the software
that's going to run there).
I think we need DT maintainer input here.
Jan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v5 08/10] xen: Split HAS_DEVICE_TREE in two
2025-07-03 5:55 ` Jan Beulich
@ 2025-07-03 10:04 ` Alejandro Vallejo
0 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-03 10:04 UTC (permalink / raw)
To: Jan Beulich, Alejandro Vallejo
Cc: Andrew Cooper, Anthony PERARD, Michal Orzel, Julien Grall,
Roger Pau Monné, Stefano Stabellini, Bertrand Marquis,
Volodymyr Babchuk, Shawn Anastasio, Alistair Francis,
Bob Eshleman, Connor Davis, Oleksii Kurochko, Daniel P. Smith,
Marek Marczykowski-Górecki, Dario Faggioli, Juergen Gross,
George Dunlap, xen-devel
On Thu Jul 3, 2025 at 7:55 AM CEST, Jan Beulich wrote:
> On 02.07.2025 17:28, Alejandro Vallejo wrote:
>> On Wed Jul 2, 2025 at 3:30 PM CEST, Jan Beulich wrote:
>>> On 01.07.2025 12:57, Alejandro Vallejo wrote:
>>>> @@ -85,7 +86,11 @@ config HAS_ALTERNATIVE
>>>> config HAS_COMPAT
>>>> bool
>>>>
>>>> -config HAS_DEVICE_TREE
>>>> +config HAS_DEVICE_TREE_DISCOVERY
>>>> + bool
>>>> + select DEVICE_TREE_PARSE
>>>> +
>>>> +config DEVICE_TREE_PARSE
>>>> bool
>>>> select LIBFDT
>>>>
>>>
>>> We're in the middle of various ([almost] alphabetically sorted) HAS_* here.
>>> Thus DEVICE_TREE_PARSE wants to move elsewhere. Or we want to move back to
>>> naming it HAS_DEVICE_TREE_PARSE, but I think there was a reason why we didn't
>>> want it like that? Just that I don't recall what that reason was ...
>>
>> AIUI, HAS_X are options selected by your architecture. Things that tell you
>> whether X is supported in your arch or not. In this case, HAS_DEVICE_TREE_PARSE
>> would be supported everywhere, while DEVICE_TREE_PARSE is not an arch property,
>> but an option selected by DOM0LESS_BOOT (which appears in menuconfig) and
>> HAS_DEVICE_TREE_DISCOVERY.
>
> It's on the edge here, I agree. Yet we have other cases where one HAS_* selects
> another HAS_*, and I think we're in the process of gaining more.
HAS_* selecting another HAS_* makes sense to me, but that's not what would be
going on here. On x86:
HAS_DOM0LESS => DOM0LESS_BOOT[y] => HAS_DEVICE_TREE_PARSE
thus leading to HAS_DEVICE_TREE_PARSE being indirectly selectable via
DOM0LESS_BOOT, which is hardly a HAS_* relationship.
>
>> I can move it elsewhere, but it's unfortunate to separate two so closely
>> related options.
>
> Imo there's only one of two options - move it or rename it.
I'll just move it elsewhere then.
>
>>>> --- a/xen/common/sched/Kconfig
>>>> +++ b/xen/common/sched/Kconfig
>>>> @@ -67,7 +67,7 @@ endmenu
>>>>
>>>> config BOOT_TIME_CPUPOOLS
>>>> bool "Create cpupools at boot time"
>>>> - depends on HAS_DEVICE_TREE
>>>> + depends on HAS_DEVICE_TREE_DISCOVERY
>>>
>>> Is this correct? CPU pool creation isn't driven by DT discovery, I thought,
>>> but is a software-only thing much like dom0less?
>>
>> In principle it would be possible. But I haven't tested the configuration, so
>> I'd rather err on the side of caution and not enable features prematurely.
>>
>> In time, this should become DOM0LESS_BOOT || HAS_DEVICE_TREE_DISCOVERY.
>
> DEVICE_TREE_PARSE, that is?
Yes :)
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v5 09/10] xen/dt: ifdef out DEV_DT-related bits from device_tree.{c,h}
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
` (7 preceding siblings ...)
2025-07-01 10:57 ` [PATCH v5 08/10] xen: Split HAS_DEVICE_TREE in two Alejandro Vallejo
@ 2025-07-01 10:57 ` Alejandro Vallejo
2025-07-01 10:57 ` [PATCH v5 10/10] xen/dt: Allow CONFIG_DEVICE_TREE_PARSE to include device-tree/ Alejandro Vallejo
9 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:57 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel
Architectures that don't discover devices via DT may skip anything to
do with device_t during the DT unflattening phase. Make device-tree.c
stop requiring CONFIG_HAS_DEVICE_TREE_DISCOVERY so it may function with
CONFIG_DEVICE_TREE_PARSE alone.
This allows CONFIG_DEVICE_TREE_PARSE to unflatten a DT ignoring its
devices if CONFIG_HAS_DEVICE_TREE_DISCOVERY is not selected.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
v5:
* New commit message to make it more general
---
xen/common/device-tree/device-tree.c | 2 ++
xen/include/xen/device_tree.h | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/xen/common/device-tree/device-tree.c b/xen/common/device-tree/device-tree.c
index 725ff71646..741e2ce585 100644
--- a/xen/common/device-tree/device-tree.c
+++ b/xen/common/device-tree/device-tree.c
@@ -2029,9 +2029,11 @@ static unsigned long unflatten_dt_node(const void *fdt,
((char *)pp->value)[sz - 1] = 0;
dt_dprintk("fixed up name for %s -> %s\n", pathp,
(char *)pp->value);
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
/* Generic device initialization */
np->dev.type = DEV_DT;
np->dev.of_node = np;
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
}
}
if ( allnextpp )
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index b6d16756fc..ace7fc3274 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -108,9 +108,12 @@ struct dt_device_node {
*/
struct list_head domain_list;
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
struct device dev;
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
};
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
#define dt_to_dev(dt_node) (&(dt_node)->dev)
static inline struct dt_device_node *dev_to_dt(struct device *dev)
@@ -119,6 +122,7 @@ static inline struct dt_device_node *dev_to_dt(struct device *dev)
return container_of(dev, struct dt_device_node, dev);
}
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
#define MAX_PHANDLE_ARGS 16
struct dt_phandle_args {
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH v5 10/10] xen/dt: Allow CONFIG_DEVICE_TREE_PARSE to include device-tree/
2025-07-01 10:56 [PATCH v5 00/10] Allow x86 to unflatten DTs Alejandro Vallejo
` (8 preceding siblings ...)
2025-07-01 10:57 ` [PATCH v5 09/10] xen/dt: ifdef out DEV_DT-related bits from device_tree.{c,h} Alejandro Vallejo
@ 2025-07-01 10:57 ` Alejandro Vallejo
9 siblings, 0 replies; 28+ messages in thread
From: Alejandro Vallejo @ 2025-07-01 10:57 UTC (permalink / raw)
To: xen-devel
Cc: Alejandro Vallejo, Andrew Cooper, Anthony PERARD, Michal Orzel,
Jan Beulich, Julien Grall, Roger Pau Monné,
Stefano Stabellini, Bertrand Marquis
This allows bootfdt.c and device-tree.c to be usable without
CONFIG_HAS_DEVICE_TREE_DISCOVERY.
Gate everything else on CONFIG_HAS_DEVICE_TREE_DISCOVERY.
Signed-off-by: Alejandro Vallejo <agarciav@amd.com>
---
xen/common/Makefile | 2 +-
xen/common/device-tree/Makefile | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/xen/common/Makefile b/xen/common/Makefile
index d541fbcf49..265468d751 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -8,7 +8,7 @@ obj-y += cpu.o
obj-$(CONFIG_DEBUG_TRACE) += debugtrace.o
obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += device.o
obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device.o
-obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += device-tree/
+obj-$(CONFIG_DEVICE_TREE_PARSE) += device-tree/
obj-$(CONFIG_IOREQ_SERVER) += dm.o
obj-y += domain.o
obj-y += event_2l.o
diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makefile
index 8abc069c4b..e399242cdf 100644
--- a/xen/common/device-tree/Makefile
+++ b/xen/common/device-tree/Makefile
@@ -1,11 +1,11 @@
obj-y += bootfdt.init.o
-obj-y += bootinfo-fdt.init.o
-obj-y += bootinfo.init.o
+obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += bootinfo-fdt.init.o
+obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += bootinfo.init.o
obj-y += device-tree.o
obj-$(CONFIG_DOMAIN_BUILD_HELPERS) += domain-build.init.o
obj-$(CONFIG_DOM0LESS_BOOT) += dom0less-build.init.o
obj-$(CONFIG_OVERLAY_DTB) += dt-overlay.o
-obj-y += intc.o
+obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += intc.o
obj-$(CONFIG_DOMAIN_BUILD_HELPERS) += kernel.o
obj-$(CONFIG_STATIC_EVTCHN) += static-evtchn.init.o
obj-$(CONFIG_STATIC_MEMORY) += static-memory.init.o
--
2.43.0
^ permalink raw reply related [flat|nested] 28+ messages in thread