Skip to content

Commit

Permalink
dtoverlay: Don't mix non-fatal errors and offsets
Browse files Browse the repository at this point in the history
FDT errors are small negative integers, and non-fatal errors are the
positive versions of the same errors. This scheme only works if the
non-fatal error values are never returned from a function where a
positive integer has another interpretation.

dtoverlay_get_target_offset broke this rule, leading eventually to
an invalid DT and failure to boot. Fortunately, finding the offset for
a fragment target is a non-destructive operation and therefore always
non-fatal, so move the NON_FATAL classification to the callers - of
which there are only three.

See: raspberrypi/firmware#1686
  • Loading branch information
pelwell authored and popcornmix committed Feb 2, 2022
1 parent affef1e commit 0957092
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions helpers/dtoverlay/dtoverlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ static int dtoverlay_get_target_offset(DTBLOB_T *base_dtb,
if (target_off < 0)
{
dtoverlay_error("invalid target-path '%.*s'", len, target_path);
return NON_FATAL(target_off);
return target_off;
}
}
else
Expand All @@ -988,11 +988,11 @@ static int dtoverlay_get_target_offset(DTBLOB_T *base_dtb,
if (!target_prop)
{
dtoverlay_error("no target or target-path");
return NON_FATAL(len);
return len;
}

if (len != 4)
return NON_FATAL(FDT_ERR_BADSTRUCTURE);
return -FDT_ERR_BADSTRUCTURE;

phandle = fdt32_to_cpu(*(fdt32_t *)target_prop);
if (!base_dtb)
Expand All @@ -1007,7 +1007,7 @@ static int dtoverlay_get_target_offset(DTBLOB_T *base_dtb,
if (target_off < 0)
{
dtoverlay_error("invalid target (phandle %d)", phandle);
return NON_FATAL(target_off);
return target_off;
}
}

Expand Down Expand Up @@ -1071,7 +1071,7 @@ static int dtoverlay_apply_overlay_paths(DTBLOB_T *base_dtb, int strings_off,
target_off = dtoverlay_get_target_offset(base_dtb, overlay_dtb,
sym_frag_off);
if (target_off < 0)
return target_off;
return NON_FATAL(target_off);

err = fdt_get_path(base_dtb->fdt, target_off,
target_path, sizeof(target_path));
Expand Down Expand Up @@ -1239,7 +1239,7 @@ int dtoverlay_merge_overlay(DTBLOB_T *base_dtb, DTBLOB_T *overlay_dtb)
target_off = dtoverlay_get_target_offset(base_dtb, overlay_dtb, frag_off);
if (target_off < 0)
{
err = target_off;
err = NON_FATAL(target_off);
break;
}

Expand Down

0 comments on commit 0957092

Please sign in to comment.