qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 3/4] tests: ibm, configure-connect


From: Daniel Henrique Barboza
Subject: Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 3/4] tests: ibm, configure-connector RTAS call implementation
Date: Wed, 29 Nov 2017 06:57:34 -0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0



On 11/28/2017 10:02 PM, Michael Roth wrote:
Quoting Daniel Henrique Barboza (2017-11-09 06:35:30)

On 11/06/2017 03:46 PM, Laurent Vivier wrote:
On 31/10/2017 21:43, Daniel Henrique Barboza wrote:
'ibm,configure-connector' hypercall is used by the guest OS
to start the configuration of a given device, where the
machine configures the said device and all its sub-devices,
giving back FDTs to the caller for each sub-device.

This hypercall is supposed to be called multiple times by the
guest OS until it returns RTAS_OUT_SUCESS (code 0), indicating
that the device is now properly configured and ready
to be used, or a return value < 0 when an error occurs.

This patch implements the 'ibm,configure-connector' RTAS
hypercall in tests/libqos/rtas.c, with an extra test
case for it inside tests/rtas-tests.c.

Signed-off-by: Daniel Henrique Barboza <address@hidden>
---
   tests/libqos/rtas.c | 35 +++++++++++++++++++++++++++
   tests/libqos/rtas.h |  1 +
   tests/rtas-test.c   | 68 
+++++++++++++++++++++++++++++++++++++++++++++++++++++
   3 files changed, 104 insertions(+)

diff --git a/tests/libqos/rtas.c b/tests/libqos/rtas.c
index ade572a84f..1cb9e2b495 100644
--- a/tests/libqos/rtas.c
+++ b/tests/libqos/rtas.c
@@ -184,3 +184,38 @@ int qrtas_set_indicator(QGuestAllocator *alloc, uint32_t 
type, uint32_t idx,
return ret[0];
   }
+
+/*
+ * ibm,configure-connector as defined by PAPR 2.7+, 13.5.3.5
+ *
+ * nargs = 2
+ * nrets = 1
+ *
+ * args[0] and args[1] compose the 64 bit Work Area address.
+ *
+ * This call will configure not only the device reported in the first
+ * offset of the Work Area but all of its siblingis as well, returning
+ * the FDT of each configured sub-device as well as a return code
+ * 'Next child', 'Next property' or 'Previous parent'. When the whole
+ * configuration is done, 'Configuration completed' (0) is returned.
+ *
+ * configure-connector will always reply with status code 'Next child'(2)
+ * on the first successful call. The DRC configuration will be
+ * completed when configure-connector returns status 0. Any return
+ * status < 0 indicates an error.
+ */
+int qrtas_ibm_configure_connector(QGuestAllocator *alloc, uintptr_t wa_addr)
+{
+    uint32_t args[2], ret[1];
+    int res;
+
+    args[0] = (uint32_t)(wa_addr);
+    args[1] = (uint32_t)(wa_addr >> 32);
This part looks strange to me. I agree it's what qemu does, but
according to spec args[0] is "Address of work area" and args[1] "0 or
address of additional page":

Linux on Power Architecture Platform Reference
Version 1.1
24 March 2016

13.5.3.5 ibm,configure-connector RTAS Call
The “need more memory” status code, is similar in semantics to the “call
again” status. However, on the next ibm,configure-connector call, the OS
will supply, via the Memory extent parameter, the address of another
page of memory for RTAS to add to the work area in order for
configuration to continue. On all other calls to ibm,configure-connector
the contents of the Memory extent parameter should be 0.
Hmmmmm thinking about it, the reason why it works in QEMU is because
wa_addr >> 32 will always be zero, perhaps?
It looks that way. At least with linux guests the "need more memory"
handling remains unimplemented, so we only ever end up dealing with:

   rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);

which effectively sets args[1] to 0. Still worth fixing though of
course.

Thanks for the info Mike. Yeah, this is a good TODO.


Daniel

At any rate, In this test, makes sense to leave args[1] to be set by the
caller,
setting it to 0 in the non "need more memory" scenario.


+    res = qrtas_call(alloc, "ibm,configure-connector", 2, args, 1, ret);
+    if (res != 0) {
+        return -1;
+    }
+
+    return ret[0];
+}
diff --git a/tests/libqos/rtas.h b/tests/libqos/rtas.h
index 9dfa18f32b..35c44fb967 100644
--- a/tests/libqos/rtas.h
+++ b/tests/libqos/rtas.h
@@ -16,4 +16,5 @@ int qrtas_check_exception(QGuestAllocator *alloc, uint32_t 
mask,
                             uint32_t buf_addr, uint32_t buf_len);
   int qrtas_set_indicator(QGuestAllocator *alloc, uint32_t type, uint32_t idx,
                           uint32_t new_state);
+int qrtas_ibm_configure_connector(QGuestAllocator *alloc, uintptr_t wa_addr);
   #endif /* LIBQOS_RTAS_H */
diff --git a/tests/rtas-test.c b/tests/rtas-test.c
index 2c34b6e83c..b3538bf878 100644
--- a/tests/rtas-test.c
+++ b/tests/rtas-test.c
@@ -15,6 +15,8 @@
   #define SPAPR_DR_ALLOCATION_STATE_USABLE  1
   #define SPAPR_DR_ISOLATION_STATE_UNISOLATED 1
+#define CC_WA_LEN 4096
+
   static void test_rtas_get_time_of_day(void)
   {
       QOSState *qs;
@@ -169,6 +171,70 @@ static void test_rtas_set_indicator(void)
       qtest_shutdown(qs);
   }
+static void test_rtas_ibm_configure_connector(void)
+{
+    QOSState *qs;
+    uint64_t ret;
+    uintptr_t guest_buf_addr, guest_drc_addr;
+    uint32_t drc_index;
+    uint8_t *buf = g_malloc0(EVENT_LOG_LEN);
+
+    qs = qtest_spapr_boot("-machine pseries -cpu POWER8_v2.0 "
+                          "-smp 1,sockets=4,cores=1,threads=1,maxcpus=4");
+
+    guest_buf_addr = guest_alloc(qs->alloc, EVENT_LOG_LEN * sizeof(uint8_t));
+    qtest_qmp_device_add("power8_v2.0-spapr-cpu-core", "id-1",
+                         "'core-id':'1'");
+
+    ret = qrtas_check_exception(qs->alloc, EVENT_MASK_EPOW,
+                                guest_buf_addr, EVENT_LOG_LEN);
+
+    memread(guest_buf_addr, buf, EVENT_LOG_LEN);
+    guest_free(qs->alloc, guest_buf_addr);
+
+    g_assert_cmpint(ret, ==, 0);
+
+    /*
+     * Same 108 bytes offset magic used and explained in
+     * test_rtas_set_indicator.
+     */
+    drc_index = be32toh(*((uint32_t *)(buf + 108)));
+    g_free(buf);
+
+    ret = qrtas_set_indicator(qs->alloc, RTAS_SENSOR_TYPE_ALLOCATION_STATE,
+                              drc_index, SPAPR_DR_ALLOCATION_STATE_USABLE);
+    g_assert_cmpint(ret, ==, 0);
+
+    ret = qrtas_set_indicator(qs->alloc, RTAS_SENSOR_TYPE_ISOLATION_STATE,
+                              drc_index, SPAPR_DR_ISOLATION_STATE_UNISOLATED);
+    g_assert_cmpint(ret, ==, 0);
+
+    /*
+     * Call ibm,configure-connector to finish the hotplugged device
+     * configuration, putting its DRC into 'ready' state.
+     *
+     * We're not interested in the generated FDTs during the config
+     * process, thus we simply keep calling configure-connector
+     * until it returns SUCCESS(0) or an error.
+     *
+     * The full explanation logic behind this process can be found
+     * at PAPR 2.7+, 13.5.3.5.
+     */
+    guest_drc_addr = guest_alloc(qs->alloc, CC_WA_LEN * sizeof(uint32_t));
CC_WA_LEN is already 4096, why "* sizeof(uint32_t"?
It must be aligned to a 4096 bytes boundaries.
Good catch. I'll fix it.

+    writel(guest_drc_addr, drc_index);
+    writel(guest_drc_addr + sizeof(uint32_t), 0)> +
+    do {
+        ret = qrtas_ibm_configure_connector(qs->alloc, guest_drc_addr);
+    } while (ret > 0);
I think it would be interesting to check the result of the call (return
value, node name, property name,...)

And you should also exit with error in the case of ret == 5 (need more
memory).

+    guest_free(qs->alloc, guest_drc_addr);
+
+    g_assert_cmpint(ret, ==, 0);
+
+    qtest_shutdown(qs);
+}
+
   int main(int argc, char *argv[])
   {
       const char *arch = qtest_get_arch();
@@ -185,6 +251,8 @@ int main(int argc, char *argv[])
       qtest_add_func("rtas/rtas-check-exception-hotplug-event",
                      test_rtas_check_exception_hotplug_event);
       qtest_add_func("rtas/test_rtas_set_indicator", test_rtas_set_indicator);
+    qtest_add_func("rtas/test_rtas_ibm_configure_connector",
+                   test_rtas_ibm_configure_connector);
return g_test_run();
   }

Thanks,
Laurent






reply via email to

[Prev in Thread] Current Thread [Next in Thread]