[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 08/15] x86/hyperlaunch: locate dom0 kernel with hyperlaunch
On 23.11.2024 19:20, Daniel P. Smith wrote: > Look for a subnode of type `multiboot,kernel` within a domain node. If found, > process the reg property for the MB1 module index. If the bootargs property is > present and there was not an MB1 string, then use the command line from the > device tree definition. Why specifically MB1? > --- a/xen/arch/x86/domain_builder/core.c > +++ b/xen/arch/x86/domain_builder/core.c > @@ -56,6 +56,18 @@ void __init builder_init(struct boot_info *bi) > > printk(XENLOG_INFO " Number of domains: %d\n", bi->nr_domains); > } > + else > + { > + int i; Plain int when ... > + /* Find first unknown boot module to use as Dom0 kernel */ > + printk("Falling back to using first boot module as dom0\n"); > + i = first_boot_module_index(bi, BOOTMOD_UNKNOWN); > + bi->mods[i].type = BOOTMOD_KERNEL; > + bi->domains[0].kernel = &bi->mods[i]; > + bi->nr_domains = 1; > + } ... it's used as array index (and there's no check for the function return value being negative)? > --- a/xen/arch/x86/domain_builder/fdt.c > +++ b/xen/arch/x86/domain_builder/fdt.c > @@ -14,6 +14,122 @@ > > #include "fdt.h" > > +static inline int __init fdt_get_prop_as_reg( What does "reg" stand for here? > + const void *fdt, int node, const char *name, unsigned int ssize, > + unsigned int asize, uint64_t *size, uint64_t *addr) > +{ > + int ret; > + const struct fdt_property *prop; > + fdt32_t *cell; > + > + /* FDT spec max size is 4 (128bit int), but largest arch int size is 64 > */ > + if ( ssize > 2 || asize > 2 ) > + return -EINVAL; > + > + prop = fdt_get_property(fdt, node, name, &ret); > + if ( !prop || ret < sizeof(u32) ) > + return ret < 0 ? ret : -EINVAL; > + > + /* read address field */ > + cell = (fdt32_t *)prop->data; > + > + if ( asize == 1 ) > + { > + uint32_t val; > + fdt_cell_as_u32(cell, &val); > + *addr = (uint64_t)val; No need for a cast here nor ... > + } > + else > + fdt_cell_as_u64(cell, addr); > + > + /* read size field */ > + cell += asize; > + > + if ( ssize == 1 ) > + { > + uint32_t val; > + fdt_cell_as_u32(cell, &val); > + *size = (uint64_t)val; ... here? > + } > + else > + fdt_cell_as_u64(cell, size); > + > + return 0; > +} This whole function reads very much like a library one. Does it really need adding here, rather than to the FDT library code we already have? In any event there's nothing x86-specific about it, afaics. > +static int __init dom0less_module_node( > + void *fdt, int node, int size_size, int address_size) Three times plain int, when ... > +{ > + uint64_t size, addr; > + int ret = fdt_get_prop_as_reg(fdt, node, "reg", size_size, address_size, ... two get converted to unsigned int in the course of the function call here? > + &size, &addr); > + /* An FDT error value may have been returned, translate to -EINVAL */ > + if ( ret < 0 ) > + return -EINVAL; > + > + if ( size != 0 ) > + return -EOPNOTSUPP; Not knowing much about DT: What does 0 represent here? > + if ( addr > MAX_NR_BOOTMODS ) > + return -ERANGE; > + > + /* > + * MAX_NR_BOOTMODS cannot exceed the max for MB1, represented by a u32, > + * thus the cast down to a u32 will be safe due to the prior check. > + */ > + return (int)addr; Comment and cast contradict one another. DYM u32 (really: uint32_t), or plain int? If you mean to return a plain int (for the sake of the -errno values further up), MAX_NR_BOOTMODS needs to stay below 2**31. > +static int __init process_domain_node( > + struct boot_info *bi, void *fdt, int dom_node) > +{ > + int node; > + struct boot_domain *bd = &bi->domains[bi->nr_domains]; > + const char *name = fdt_get_name(fdt, dom_node, NULL); > + int address_size = fdt_address_cells(fdt, dom_node); > + int size_size = fdt_size_cells(fdt, dom_node); > + > + if ( address_size < 0 || size_size < 0 ) > + { > + printk(" failed processing #address or #size for domain %s)\n", > + name == NULL ? "unknown" : name); > + return -EINVAL; > + } > + > + fdt_for_each_subnode(node, fdt, dom_node) > + { > + if ( fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 ) > + { > + int idx = dom0less_module_node(fdt, node, size_size, > address_size); > + if ( idx < 0 ) > + { > + printk(" failed processing kernel module for domain %s)\n", > + name == NULL ? "unknown" : name); > + return idx; > + } > + > + if ( idx > bi->nr_modules ) > + { > + printk(" invalid kernel module index for domain node > (%d)\n", > + bi->nr_domains); > + return -EINVAL; > + } > + > + printk(" kernel: boot module %d\n", idx); > + bi->mods[idx].type = BOOTMOD_KERNEL; > + bd->kernel = &bi->mods[idx]; > + } > + } What if you find two? > --- a/xen/arch/x86/domain_builder/fdt.h > +++ b/xen/arch/x86/domain_builder/fdt.h > @@ -3,6 +3,7 @@ > #define __XEN_X86_FDT_H__ > > #include <xen/init.h> > +#include <xen/libfdt/libfdt.h> > > #include <asm/bootinfo.h> > > @@ -10,6 +11,22 @@ > #define HYPERLAUNCH_MODULE_IDX 0 > > #ifdef CONFIG_DOMAIN_BUILDER > + > +static inline int __init fdt_cell_as_u32(const fdt32_t *cell, uint32_t *val) > +{ > + *val = fdt32_to_cpu(*cell); > + > + return 0; > +} > + > +static inline int __init fdt_cell_as_u64(const fdt32_t *cell, uint64_t *val) > +{ > + *val = ((uint64_t)fdt32_to_cpu(cell[0]) << 32) | > + (uint64_t)fdt32_to_cpu(cell[1]); > + > + return 0; > +} Basic library routines again? Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |