diff --git a/automation/eclair_analysis/ECLAIR/deviations.ecl b/automation/eclair_analysis/ECLAIR/deviations.ecl index 30c3239069..1ceb65819e 100644 --- a/automation/eclair_analysis/ECLAIR/deviations.ecl +++ b/automation/eclair_analysis/ECLAIR/deviations.ecl @@ -629,8 +629,10 @@ of the IS_ENABLED or STATIC_IF/STATIC_IF_NOT macros, so it always receives a lit not in scope for compliance are allowed, as that is imported code." -file_tag+={gnu_efi_include, "^xen/include/efi/.*$"} -file_tag+={acpi_cpu_idle, "^xen/arch/x86/acpi/cpu_idle\\.c$"} +-file_tag+={libfdt, "^xen/include/xen/libfdt/libfdt\\.h$"} -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(libfdt))))"} -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 f203e189f5..fd171333c6 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 "/: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;