[PATCH] ppc/vof: Make nextprop behave more like Open Firmware

BALATON Zoltan posted 1 patch 7 months, 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20250330223442.930724E6036@zero.eik.bme.hu
Maintainers: Alexey Kardashevskiy <aik@ozlabs.ru>
There is a newer version of this series
hw/ppc/vof.c | 56 ++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 41 insertions(+), 15 deletions(-)
[PATCH] ppc/vof: Make nextprop behave more like Open Firmware
Posted by BALATON Zoltan 7 months, 2 weeks ago
The FDT does not normally store name properties but reconsrtucts it
from path but each node in Open Firmware should at least have this
property. This is correctly handled in getprop but nextprop should
also return it even if not present as a property. This patch fixes
that and also skips phandle which does not appear in Open Firmware
and only added for internal use by VOF.

Explicit name properties are still allowed because they are needed
e.g. on the root node that guests expect to have specific names as
seen on real machines instead of being empty so sometimes the node
name may need to be overriden.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
I've tested this with pegasos2 but don't know how to test spapr.

 hw/ppc/vof.c | 56 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c
index 09cb77de93..2c00d11521 100644
--- a/hw/ppc/vof.c
+++ b/hw/ppc/vof.c
@@ -353,34 +353,60 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle,
 {
     int offset, nodeoff = fdt_node_offset_by_phandle(fdt, phandle);
     char prev[OF_PROPNAME_LEN_MAX + 1];
-    const char *tmp;
+    const char *tmp = NULL;
 
     if (readstr(prevaddr, prev, sizeof(prev))) {
         return PROM_ERROR;
     }
-
-    fdt_for_each_property_offset(offset, fdt, nodeoff) {
-        if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
-            return 0;
+    /*
+     * "name" may or may not be present in fdt but we should still return it.
+     * Do that first and then skip it if seen later. Also skip phandle which is
+     * an internal value we added in vof_build_dt but should not appear here.
+     */
+    if (prev[0] == '\0') {
+        tmp = "name";
+    } else {
+        if (strcmp(prev, "name") == 0) {
+            prev[0] = '\0';
         }
-        if (prev[0] == '\0' || strcmp(prev, tmp) == 0) {
-            if (prev[0] != '\0') {
+        fdt_for_each_property_offset(offset, fdt, nodeoff) {
+            if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
+                return 0;
+            }
+            if (strcmp(tmp, "name") == 0 || strcmp(tmp, "phandle") == 0) {
+                continue;
+            }
+            if (prev[0] == '\0') {
+                break;
+            }
+            if (strcmp(prev, tmp) == 0) {
                 offset = fdt_next_property_offset(fdt, offset);
-                if (offset < 0) {
-                    return 0;
-                }
+                break;
             }
+        }
+        if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
+            return 0;
+        }
+        if (strcmp(tmp, "name") == 0 || strcmp(tmp, "phandle") == 0) {
+            offset = fdt_next_property_offset(fdt, offset);
             if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
                 return 0;
             }
-
-            if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) {
-                return PROM_ERROR;
+        }
+        /* name and phandle can follow each other so check again */
+        if (strcmp(tmp, "name") == 0 || strcmp(tmp, "phandle") == 0) {
+            offset = fdt_next_property_offset(fdt, offset);
+            if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
+                return 0;
             }
-            return 1;
         }
     }
-
+    if (tmp) {
+        if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) {
+            return PROM_ERROR;
+        }
+        return 1;
+    }
     return 0;
 }
 
-- 
2.41.3