Skip to content

Commit b0c3eab

Browse files
committed
[ot] hw/opentitan: ot_vmapper: Fix range sort comparator logic
This commit fixes the comparator logic for sorting address ranges as used by the vmapper device. The current logic uses the difference between the `start` and `end` addresses of each range, which are stored as `uint32_t` values (which is correct, as virtual address ranges can cover any valid 32 bit address). By subtracting the addresses in unsigned arithmetic we will underflow in the case that the first address is smaller than the second. Furthermore, the conversion to a signed `gint` (`int`) means that for large address differences (e.g. consider a region starts at `0x00000000` and another at 0x80000001 or higher) the result will when cast overflow the 32-bit signed domain to become a negative value. Replace this logic with comparisons that return simple unit sign values. This now performs the intended sorting without risking overflow. Signed-off-by: Alex Jones <[email protected]>
1 parent 7b28086 commit b0c3eab

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

hw/opentitan/ot_vmapper.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,13 @@ static gint ot_vmapper_compare(gconstpointer a, gconstpointer b)
113113
const OtRegionRange *ra = (const OtRegionRange *)a;
114114
const OtRegionRange *rb = (const OtRegionRange *)b;
115115

116-
return (gint)((ra->start == rb->start) ?
117-
((ra->end == rb->end) ? (ra->prio - rb->prio) :
118-
(ra->end - rb->end)) :
119-
(ra->start - rb->start));
116+
if (ra->start == rb->start) {
117+
if (ra->end == rb->end) {
118+
return (gint)ra->prio - (gint)rb->prio;
119+
}
120+
return (ra->end < rb->end) ? -1 : 1;
121+
}
122+
return (ra->start < rb->start) ? -1 : 1;
120123
}
121124

122125
/*

0 commit comments

Comments
 (0)