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

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