|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2] xen/dt-overlay: support phandle-based targeting in overlay_get_nodes_info
overlay_get_nodes_info() is called before fdt_overlay_apply() to extract target paths from the overlay. This fails for overlays using phandle-based targeting (target = <&label>) because DTC compiles these as unresolved fixups (target = <0xffffffff>), causing fdt_overlay_target_offset() to return -FDT_ERR_BADPHANDLE. Prior to this change users were forced to manually modify the dtbo (even for hwdom) to switch from target to target-phandle by manually inspecting also the host DTB. Introduce overlay_get_target_path() which directly handles the two targeting cases that occur before fixup resolution: - target-path: the string property is returned directly. - target = <&label>: the label is found in the overlay's __fixups__ node, then resolved to a path via the base DTB's __symbols__ node. Libfdt fdt_for_each_property_offset() violates MISRA R20.7. Despite libfdt being excluded from the analysis, this causes ECLAIR scan to report a regression because the violation introduced by a macro is reported at the call site. Deviate R20.7 for libfdt.h. Reviewed-by: Luca Fancellu <luca.fancellu@xxxxxxx> Acked-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> Signed-off-by: Michal Orzel <michal.orzel@xxxxxxx> --- In my pre-push testing I realized ECLAIR allcode reported a violation related to the use of fdt_for_each_property_offset. Libfdt is excluded from analysis but this does not apply to e.g. macros used in other places. Changes in v2: - strip out from series that is ready to be committed - deviate 20.7 for libfdt.h. Discussed with Nicole. https://gitlab.com/xen-project/people/morzel/xen/-/pipelines/2484326830 --- .../eclair_analysis/ECLAIR/deviations.ecl | 1 + xen/common/device-tree/dt-overlay.c | 65 +++++++++++++++++-- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/automation/eclair_analysis/ECLAIR/deviations.ecl b/automation/eclair_analysis/ECLAIR/deviations.ecl index 30c323906924..5f0b73062474 100644 --- a/automation/eclair_analysis/ECLAIR/deviations.ecl +++ b/automation/eclair_analysis/ECLAIR/deviations.ecl @@ -631,6 +631,7 @@ not in scope for compliance are allowed, as that is imported code." -file_tag+={acpi_cpu_idle, "^xen/arch/x86/acpi/cpu_idle\\.c$"} -config=MC3A2.R20.7,reports+={safe, "any_area(any_loc(file(gnu_efi_include)||any_exp(macro(^NextMemoryDescriptor$))))"} -config=MC3A2.R20.7,reports+={safe, "any_area(any_loc(file(acpi_cpu_idle)))"} +-config=MC3A2.R20.7,reports+={safe, "any_area(any_loc(any_exp(file(^xen/include/xen/libfdt/libfdt.h$))))"} -doc_end -doc_begin="To avoid compromising readability, the macros alternative_(v)?call[0-9] are allowed diff --git a/xen/common/device-tree/dt-overlay.c b/xen/common/device-tree/dt-overlay.c index f203e189f5ff..fd171333c6d7 100644 --- a/xen/common/device-tree/dt-overlay.c +++ b/xen/common/device-tree/dt-overlay.c @@ -286,6 +286,63 @@ static unsigned int overlay_node_count(const void *overlay_fdt) return num_overlay_nodes; } +/* + * Resolve the target path for an overlay fragment. + * + * This is called before fdt_overlay_apply(), so phandle-based targets + * (target = <&label>) are still unresolved (compiled as 0xffffffff by DTC). + * Handle the two cases that actually occur: + * - target-path property: the path string is used directly, + * - target = <&label>: the label is looked up in the overlay's __fixups__ + * node, then resolved to a path via the base DTB's __symbols__ node. + * + * Returns a pointer into the FDT on success, NULL on failure. + */ +static const char *overlay_get_target_path(const void *fdt, const void *fdto, + int fragment) +{ + const char *path, *fragment_name; + int fixups_off, symbols_off, property; + int fragment_name_len; + + /* Try target-path first (string-based targeting) */ + path = fdt_getprop(fdto, fragment, "target-path", NULL); + if ( path ) + return path; + + /* Phandle-based target: resolve via __fixups__ and __symbols__ */ + fixups_off = fdt_path_offset(fdto, "/__fixups__"); + if ( fixups_off < 0 ) + return NULL; + + symbols_off = fdt_path_offset(fdt, "/__symbols__"); + if ( symbols_off < 0 ) + return NULL; + + fragment_name = fdt_get_name(fdto, fragment, &fragment_name_len); + if ( !fragment_name ) + return NULL; + + fdt_for_each_property_offset(property, fdto, fixups_off) + { + const char *val, *label, *p; + int val_len; + + val = fdt_getprop_by_offset(fdto, property, &label, &val_len); + if ( !val || !val_len || (val[val_len - 1] != '\0') ) + continue; + + /* Match entries of the form "/<fragment_name>:target:0" */ + for ( p = val; p < (val + val_len); p += (strlen(p) + 1) ) + if ( p[0] == '/' && + !strncmp(p + 1, fragment_name, fragment_name_len) && + !strcmp(p + 1 + fragment_name_len, ":target:0") ) + return fdt_getprop(fdt, symbols_off, label, NULL); + } + + return NULL; +} + /* * overlay_get_nodes_info gets full name with path for all the nodes which * are in one level of __overlay__ tag. This is useful when checking node for @@ -298,7 +355,6 @@ static int overlay_get_nodes_info(const void *fdto, char **nodes_full_path) fdt_for_each_subnode(fragment, fdto, 0) { - int target; int overlay; int subnode; const char *target_path; @@ -307,11 +363,8 @@ static int overlay_get_nodes_info(const void *fdto, char **nodes_full_path) if ( overlay < 0 ) continue; - target = fdt_overlay_target_offset(device_tree_flattened, fdto, - fragment, &target_path); - if ( target < 0 ) - return target; - + target_path = overlay_get_target_path(device_tree_flattened, fdto, + fragment); if ( target_path == NULL ) return -EINVAL; -- 2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |