mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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. Signed-off-by: Michal Orzel <michal.orzel@amd.com> Reviewed-by: Luca Fancellu <luca.fancellu@arm.com> Acked-by: Stefano Stabellini <sstabellini@kernel.org> Reviewed-by: Nicola Vetrini <nicola.vetrini@bugseng.com>
This commit is contained in:
1 parent
9b1acd8124
commit
16579c5503
2 files changed
+61
-6
No files matched your search
@@ -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."
|
not in scope for compliance are allowed, as that is imported code."
|
||||||
-file_tag+={gnu_efi_include, "^xen/include/efi/.*$"}
|
-file_tag+={gnu_efi_include, "^xen/include/efi/.*$"}
|
||||||
-file_tag+={acpi_cpu_idle, "^xen/arch/x86/acpi/cpu_idle\\.c$"}
|
-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(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(file(acpi_cpu_idle)))"}
|
||||||
|
-config=MC3A2.R20.7,reports+={safe, "any_area(any_loc(any_exp(file(libfdt))))"}
|
||||||
-doc_end
|
-doc_end
|
||||||
|
|
||||||
-doc_begin="To avoid compromising readability, the macros alternative_(v)?call[0-9] are allowed
|
-doc_begin="To avoid compromising readability, the macros alternative_(v)?call[0-9] are allowed
|
||||||
|
|||||||
@@ -286,6 +286,63 @@ static unsigned int overlay_node_count(const void *overlay_fdt)
|
|||||||
return num_overlay_nodes;
|
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
|
* 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
|
* 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)
|
fdt_for_each_subnode(fragment, fdto, 0)
|
||||||
{
|
{
|
||||||
int target;
|
|
||||||
int overlay;
|
int overlay;
|
||||||
int subnode;
|
int subnode;
|
||||||
const char *target_path;
|
const char *target_path;
|
||||||
@@ -307,11 +363,8 @@ static int overlay_get_nodes_info(const void *fdto, char **nodes_full_path)
|
|||||||
if ( overlay < 0 )
|
if ( overlay < 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
target = fdt_overlay_target_offset(device_tree_flattened, fdto,
|
target_path = overlay_get_target_path(device_tree_flattened, fdto,
|
||||||
fragment, &target_path);
|
fragment);
|
||||||
if ( target < 0 )
|
|
||||||
return target;
|
|
||||||
|
|
||||||
if ( target_path == NULL )
|
if ( target_path == NULL )
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|||||||