Blame SOURCES/kvm-spapr-Fold-h_cas_compose_response-into-h_client_arch.patch

a19a21
From cb9d5380b1376b2a44d91d84eaf09f948ef1e165 Mon Sep 17 00:00:00 2001
a19a21
From: Greg Kurz <gkurz@redhat.com>
a19a21
Date: Tue, 19 Jan 2021 15:09:50 -0500
a19a21
Subject: [PATCH 2/9] spapr: Fold h_cas_compose_response() into
a19a21
 h_client_architecture_support()
a19a21
a19a21
RH-Author: Greg Kurz <gkurz@redhat.com>
a19a21
Message-id: <20210119150954.1017058-3-gkurz@redhat.com>
a19a21
Patchwork-id: 100687
a19a21
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH v2 2/6] spapr: Fold h_cas_compose_response() into h_client_architecture_support()
a19a21
Bugzilla: 1901837
a19a21
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
a19a21
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
a19a21
RH-Acked-by: David Gibson <dgibson@redhat.com>
a19a21
a19a21
From: David Gibson <david@gibson.dropbear.id.au>
a19a21
a19a21
spapr_h_cas_compose_response() handles the last piece of the PAPR feature
a19a21
negotiation process invoked via the ibm,client-architecture-support OF
a19a21
call.  Its only caller is h_client_architecture_support() which handles
a19a21
most of the rest of that process.
a19a21
a19a21
I believe it was placed in a separate file originally to handle some
a19a21
fiddly dependencies between functions, but mostly it's just confusing
a19a21
to have the CAS process split into two pieces like this.  Now that
a19a21
compose response is simplified (by just generating the whole device
a19a21
tree anew), it's cleaner to just fold it into
a19a21
h_client_architecture_support().
a19a21
a19a21
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
a19a21
Reviewed-by: Cedric Le Goater <clg@fr.ibm.com>
a19a21
Reviewed-by: Greg Kurz <groug@kaod.org>
a19a21
(cherry picked from commit 0c21e073541cc093b4cb8744640e24f130e6f8ba)
a19a21
Signed-off-by: Greg Kurz <gkurz@redhat.com>
a19a21
Signed-off-by: Jon Maloy <jmaloy.redhat.com>
a19a21
---
a19a21
 hw/ppc/spapr.c         | 61 +-----------------------------------------
a19a21
 hw/ppc/spapr_hcall.c   | 55 ++++++++++++++++++++++++++++++++++---
a19a21
 include/hw/ppc/spapr.h |  4 +--
a19a21
 3 files changed, 54 insertions(+), 66 deletions(-)
a19a21
a19a21
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
a19a21
index 92f63ad035..992bd08aaa 100644
a19a21
--- a/hw/ppc/spapr.c
a19a21
+++ b/hw/ppc/spapr.c
a19a21
@@ -76,7 +76,6 @@
a19a21
 #include "hw/nmi.h"
a19a21
 #include "hw/intc/intc.h"
a19a21
 
a19a21
-#include "qemu/cutils.h"
a19a21
 #include "hw/ppc/spapr_cpu_core.h"
a19a21
 #include "hw/mem/memory-device.h"
a19a21
 #include "hw/ppc/spapr_tpm_proxy.h"
a19a21
@@ -898,63 +897,6 @@ out:
a19a21
     return ret;
a19a21
 }
a19a21
 
a19a21
-static bool spapr_hotplugged_dev_before_cas(void)
a19a21
-{
a19a21
-    Object *drc_container, *obj;
a19a21
-    ObjectProperty *prop;
a19a21
-    ObjectPropertyIterator iter;
a19a21
-
a19a21
-    drc_container = container_get(object_get_root(), "/dr-connector");
a19a21
-    object_property_iter_init(&iter, drc_container);
a19a21
-    while ((prop = object_property_iter_next(&iter))) {
a19a21
-        if (!strstart(prop->type, "link<", NULL)) {
a19a21
-            continue;
a19a21
-        }
a19a21
-        obj = object_property_get_link(drc_container, prop->name, NULL);
a19a21
-        if (spapr_drc_needed(obj)) {
a19a21
-            return true;
a19a21
-        }
a19a21
-    }
a19a21
-    return false;
a19a21
-}
a19a21
-
a19a21
-static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset,
a19a21
-                             size_t space);
a19a21
-
a19a21
-int spapr_h_cas_compose_response(SpaprMachineState *spapr,
a19a21
-                                 target_ulong addr, target_ulong size,
a19a21
-                                 SpaprOptionVector *ov5_updates)
a19a21
-{
a19a21
-    void *fdt;
a19a21
-    SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
a19a21
-
a19a21
-    if (spapr_hotplugged_dev_before_cas()) {
a19a21
-        return 1;
a19a21
-    }
a19a21
-
a19a21
-    if (size < sizeof(hdr)) {
a19a21
-        error_report("SLOF provided insufficient CAS buffer "
a19a21
-                     TARGET_FMT_lu " (min: %zu)", size, sizeof(hdr));
a19a21
-        exit(EXIT_FAILURE);
a19a21
-    }
a19a21
-
a19a21
-    size -= sizeof(hdr);
a19a21
-
a19a21
-    fdt = spapr_build_fdt(spapr, false, size);
a19a21
-    _FDT((fdt_pack(fdt)));
a19a21
-
a19a21
-    cpu_physical_memory_write(addr, &hdr, sizeof(hdr));
a19a21
-    cpu_physical_memory_write(addr + sizeof(hdr), fdt, fdt_totalsize(fdt));
a19a21
-    trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr));
a19a21
-
a19a21
-    g_free(spapr->fdt_blob);
a19a21
-    spapr->fdt_size = fdt_totalsize(fdt);
a19a21
-    spapr->fdt_initial_size = spapr->fdt_size;
a19a21
-    spapr->fdt_blob = fdt;
a19a21
-
a19a21
-    return 0;
a19a21
-}
a19a21
-
a19a21
 static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
a19a21
 {
a19a21
     MachineState *ms = MACHINE(spapr);
a19a21
@@ -1192,8 +1134,7 @@ static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt)
a19a21
     }
a19a21
 }
a19a21
 
a19a21
-static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset,
a19a21
-                             size_t space)
a19a21
+void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space)
a19a21
 {
a19a21
     MachineState *machine = MACHINE(spapr);
a19a21
     MachineClass *mc = MACHINE_GET_CLASS(machine);
a19a21
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
a19a21
index 05a7ca275b..0f19be794c 100644
a19a21
--- a/hw/ppc/spapr_hcall.c
a19a21
+++ b/hw/ppc/spapr_hcall.c
a19a21
@@ -1,4 +1,5 @@
a19a21
 #include "qemu/osdep.h"
a19a21
+#include "qemu/cutils.h"
a19a21
 #include "qapi/error.h"
a19a21
 #include "sysemu/hw_accel.h"
a19a21
 #include "sysemu/runstate.h"
a19a21
@@ -15,6 +16,7 @@
a19a21
 #include "cpu-models.h"
a19a21
 #include "trace.h"
a19a21
 #include "kvm_ppc.h"
a19a21
+#include "hw/ppc/fdt.h"
a19a21
 #include "hw/ppc/spapr_ovec.h"
a19a21
 #include "mmu-book3s-v3.h"
a19a21
 #include "hw/mem/memory-device.h"
a19a21
@@ -1638,6 +1640,26 @@ static uint32_t cas_check_pvr(SpaprMachineState *spapr, PowerPCCPU *cpu,
a19a21
     return best_compat;
a19a21
 }
a19a21
 
a19a21
+static bool spapr_hotplugged_dev_before_cas(void)
a19a21
+{
a19a21
+    Object *drc_container, *obj;
a19a21
+    ObjectProperty *prop;
a19a21
+    ObjectPropertyIterator iter;
a19a21
+
a19a21
+    drc_container = container_get(object_get_root(), "/dr-connector");
a19a21
+    object_property_iter_init(&iter, drc_container);
a19a21
+    while ((prop = object_property_iter_next(&iter))) {
a19a21
+        if (!strstart(prop->type, "link<", NULL)) {
a19a21
+            continue;
a19a21
+        }
a19a21
+        obj = object_property_get_link(drc_container, prop->name, NULL);
a19a21
+        if (spapr_drc_needed(obj)) {
a19a21
+            return true;
a19a21
+        }
a19a21
+    }
a19a21
+    return false;
a19a21
+}
a19a21
+
a19a21
 static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
a19a21
                                                   SpaprMachineState *spapr,
a19a21
                                                   target_ulong opcode,
a19a21
@@ -1645,6 +1667,8 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
a19a21
 {
a19a21
     /* Working address in data buffer */
a19a21
     target_ulong addr = ppc64_phys_to_real(args[0]);
a19a21
+    target_ulong fdt_buf = args[1];
a19a21
+    target_ulong fdt_bufsize = args[2];
a19a21
     target_ulong ov_table;
a19a21
     uint32_t cas_pvr;
a19a21
     SpaprOptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
a19a21
@@ -1788,16 +1812,41 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
a19a21
 
a19a21
     spapr_irq_update_active_intc(spapr);
a19a21
 
a19a21
+    if (spapr_hotplugged_dev_before_cas()) {
a19a21
+        spapr->cas_reboot = true;
a19a21
+    }
a19a21
+
a19a21
     if (!spapr->cas_reboot) {
a19a21
+        void *fdt;
a19a21
+        SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
a19a21
+
a19a21
         /* If spapr_machine_reset() did not set up a HPT but one is necessary
a19a21
          * (because the guest isn't going to use radix) then set it up here. */
a19a21
         if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
a19a21
             /* legacy hash or new hash: */
a19a21
             spapr_setup_hpt_and_vrma(spapr);
a19a21
         }
a19a21
-        spapr->cas_reboot =
a19a21
-            (spapr_h_cas_compose_response(spapr, args[1], args[2],
a19a21
-                                          ov5_updates) != 0);
a19a21
+
a19a21
+        if (fdt_bufsize < sizeof(hdr)) {
a19a21
+            error_report("SLOF provided insufficient CAS buffer "
a19a21
+                         TARGET_FMT_lu " (min: %zu)", fdt_bufsize, sizeof(hdr));
a19a21
+            exit(EXIT_FAILURE);
a19a21
+        }
a19a21
+
a19a21
+        fdt_bufsize -= sizeof(hdr);
a19a21
+
a19a21
+        fdt = spapr_build_fdt(spapr, false, fdt_bufsize);
a19a21
+        _FDT((fdt_pack(fdt)));
a19a21
+
a19a21
+        cpu_physical_memory_write(fdt_buf, &hdr, sizeof(hdr));
a19a21
+        cpu_physical_memory_write(fdt_buf + sizeof(hdr), fdt,
a19a21
+                                  fdt_totalsize(fdt));
a19a21
+        trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr));
a19a21
+
a19a21
+        g_free(spapr->fdt_blob);
a19a21
+        spapr->fdt_size = fdt_totalsize(fdt);
a19a21
+        spapr->fdt_initial_size = spapr->fdt_size;
a19a21
+        spapr->fdt_blob = fdt;
a19a21
     }
a19a21
 
a19a21
     spapr_ovec_cleanup(ov5_updates);
a19a21
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
a19a21
index e047dabf30..e5e2a99046 100644
a19a21
--- a/include/hw/ppc/spapr.h
a19a21
+++ b/include/hw/ppc/spapr.h
a19a21
@@ -767,11 +767,9 @@ struct SpaprEventLogEntry {
a19a21
     QTAILQ_ENTRY(SpaprEventLogEntry) next;
a19a21
 };
a19a21
 
a19a21
+void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space);
a19a21
 void spapr_events_init(SpaprMachineState *sm);
a19a21
 void spapr_dt_events(SpaprMachineState *sm, void *fdt);
a19a21
-int spapr_h_cas_compose_response(SpaprMachineState *sm,
a19a21
-                                 target_ulong addr, target_ulong size,
a19a21
-                                 SpaprOptionVector *ov5_updates);
a19a21
 void close_htab_fd(SpaprMachineState *spapr);
a19a21
 void spapr_setup_hpt_and_vrma(SpaprMachineState *spapr);
a19a21
 void spapr_free_hpt(SpaprMachineState *spapr);
a19a21
-- 
a19a21
2.18.2
a19a21