Patchwork [02/12] qtest: add spapr hypercall support

login
register
mail settings
Submitter Anthony Liguori
Date June 19, 2013, 8:40 p.m.
Message ID <1371674435-14973-3-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/252664/
State New
Headers show

Comments

Anthony Liguori - June 19, 2013, 8:40 p.m.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 qtest.c          | 29 +++++++++++++++++++++++++++++
 tests/libqtest.c | 18 ++++++++++++++++++
 tests/libqtest.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+)
Andreas Färber - June 20, 2013, 3:20 p.m.
Am 19.06.2013 22:40, schrieb Anthony Liguori:
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  qtest.c          | 29 +++++++++++++++++++++++++++++
>  tests/libqtest.c | 18 ++++++++++++++++++
>  tests/libqtest.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 93 insertions(+)
> 
> diff --git a/qtest.c b/qtest.c
> index 07a9612..f8c8f44 100644
> --- a/qtest.c
> +++ b/qtest.c
> @@ -19,6 +19,9 @@
>  #include "hw/irq.h"
>  #include "sysemu/sysemu.h"
>  #include "sysemu/cpus.h"
> +#ifdef TARGET_PPC64
> +#include "hw/ppc/spapr.h"
> +#endif
>  
>  #define MAX_IRQ 256
>  
> @@ -141,6 +144,13 @@ static bool qtest_opened;
>   * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
>   * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
>   * NUM=0 even though it is remapped to GSI 2).
> + *
> + * Platform specific (sPAPR):
> + *
> + *  > papr_hypercall NR ARG0 ARG1 ... ARG8

The functions are called spapr_hcall*() but the protocol uses
papr_hypercall?

> + *  < OK RET
> + *
> + * where NR, ARG[0-8] and RET are all integers.
>   */
>  
>  static int hex2nib(char ch)
> @@ -425,6 +435,25 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
>          qtest_clock_warp(ns);
>          qtest_send_prefix(chr);
>          qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
> +#ifdef TARGET_PPC64
> +    } else if (strcmp(words[0], "papr_hypercall") == 0) {
> +        uint64_t nr;
> +        uint64_t args[9];
> +        uint64_t ret;
> +        int i;
> +
> +        memset(args, 0, sizeof(args));
> +        g_assert(words[1]);
> +        nr = strtoull(words[1], NULL, 0);
> +        for (i = 0; i < 9; i++) {
> +            if (words[2 + i] == NULL) {
> +                break;
> +            }
> +            args[i] = strtoull(words[2 + i], NULL, 0);
> +        }
> +        ret = spapr_hypercall(ppc_env_get_cpu(first_cpu), nr, args);
> +        qtest_send(chr, "OK 0x%" PRIx64 "\n", ret);
> +#endif
>      } else {
>          qtest_send_prefix(chr);
>          qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
> diff --git a/tests/libqtest.c b/tests/libqtest.c
> index 879ffe9..81107cf 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -544,3 +544,21 @@ void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)
>      qtest_sendf(s, "\n");
>      qtest_rsp(s, 0);
>  }
> +
> +uint64_t qtest_spapr_hcall9(QTestState *s, uint64_t nr, uint64_t a0,
> +                            uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4,
> +                            uint64_t a5, uint64_t a6, uint64_t a7, uint64_t a8)
> +{
> +    gchar **args;
> +    uint64_t value;
> +
> +    qtest_sendf(s, "papr_hypercall 0x%" PRIx64 " 0x%" PRIx64
> +                " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 
> +                " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 
> +                "\n", nr, a0, a1, a2, a3, a4, a5, a6, a7, a8);
> +    args = qtest_rsp(s, 2);
> +    value = strtoull(args[1], NULL, 0);
> +    g_strfreev(args);
> +
> +    return value;
> +}
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index 437bda3..592f035 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -286,6 +286,19 @@ int64_t qtest_clock_step(QTestState *s, int64_t step);
>  int64_t qtest_clock_set(QTestState *s, int64_t val);
>  
>  /**
> + * qtest_spapr_hcall9:
> + * @s: QTestState instance to operate on.
> + * @nr: The hypercall index
> + * @aN: The @Nth hypercall argument
> + *
> + * Issue an sPAPR hypercall
> + *
> + * Returns: The result of the hypercall.
> + */
> +uint64_t qtest_spapr_hcall9(QTestState *s, uint64_t nr, uint64_t a0,
> +                            uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4,
> +                            uint64_t a5, uint64_t a6, uint64_t a7, uint64_t a8);
> +/**
>   * qtest_get_arch:
>   *
>   * Returns: The architecture for the QEMU executable under test.
> @@ -607,4 +620,37 @@ static inline int64_t clock_set(int64_t val)
>      return qtest_clock_set(global_qtest, val);
>  }
>  
> +static inline uint64_t spapr_hcall0(uint64_t nr)
> +{
> +    return qtest_spapr_hcall9(global_qtest, nr, 0, 0, 0, 0, 0, 0, 0, 0, 0);
> +}
> +
> +static inline uint64_t spapr_hcall1(uint64_t nr, uint64_t a0)
> +{
> +    return qtest_spapr_hcall9(global_qtest, nr, a0, 0, 0, 0, 0, 0, 0, 0, 0);
> +}
> +
> +static inline uint64_t spapr_hcall2(uint64_t nr, uint64_t a0, uint64_t a1)
> +{
> +    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, 0, 0, 0, 0, 0, 0, 0);
> +}
> +
> +static inline uint64_t spapr_hcall3(uint64_t nr, uint64_t a0, uint64_t a1,
> +                                    uint64_t a2)
> +{
> +    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, a2, 0, 0, 0, 0, 0, 0);
> +}
> +
> +static inline uint64_t spapr_hcall4(uint64_t nr, uint64_t a0, uint64_t a1,
> +                                    uint64_t a2, uint64_t a3)
> +{
> +    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, a2, a3, 0, 0, 0, 0, 0);
> +}
> +
> +static inline uint64_t spapr_hcall5(uint64_t nr, uint64_t a0, uint64_t a1,
> +                                    uint64_t a2, uint64_t a3, uint64_t a4)
> +{
> +    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, a2, a3, a4, 0, 0, 0, 0);
> +}

While for a large number of almost identical helpers this certainly
sucks, I made an effort to document all functions in that file, so
please keep it that way. :)

Looks very similar to what I had proposed for s390x, so fine with me.

Regards,
Andreas

> +
>  #endif
>
Anthony Liguori - June 20, 2013, 3:42 p.m.
Andreas Färber <afaerber@suse.de> writes:

> Am 19.06.2013 22:40, schrieb Anthony Liguori:
>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>> ---
>>  qtest.c          | 29 +++++++++++++++++++++++++++++
>>  tests/libqtest.c | 18 ++++++++++++++++++
>>  tests/libqtest.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 93 insertions(+)
>> 
>> diff --git a/qtest.c b/qtest.c
>> index 07a9612..f8c8f44 100644
>> --- a/qtest.c
>> +++ b/qtest.c
>> @@ -19,6 +19,9 @@
>>  #include "hw/irq.h"
>>  #include "sysemu/sysemu.h"
>>  #include "sysemu/cpus.h"
>> +#ifdef TARGET_PPC64
>> +#include "hw/ppc/spapr.h"
>> +#endif
>>  
>>  #define MAX_IRQ 256
>>  
>> @@ -141,6 +144,13 @@ static bool qtest_opened;
>>   * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
>>   * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
>>   * NUM=0 even though it is remapped to GSI 2).
>> + *
>> + * Platform specific (sPAPR):
>> + *
>> + *  > papr_hypercall NR ARG0 ARG1 ... ARG8
>
> The functions are called spapr_hcall*() but the protocol uses
> papr_hypercall?

The discrepancy is inherited in the KVM vs. QEMU interfaces.  It's
called papr_hypercall in the KVM interface vs. spapr in QEMU.

I honestly don't know what the distinction between spapr and papr is.

>> +static inline uint64_t spapr_hcall5(uint64_t nr, uint64_t a0, uint64_t a1,
>> +                                    uint64_t a2, uint64_t a3, uint64_t a4)
>> +{
>> +    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, a2, a3, a4, 0, 0, 0, 0);
>> +}
>
> While for a large number of almost identical helpers this certainly
> sucks, I made an effort to document all functions in that file, so
> please keep it that way. :)

Seems a bit redundant to document every one of these but I don't mind
doing it.

Regards,

Anthony Liguori

>
> Looks very similar to what I had proposed for s390x, so fine with me.
>
> Regards,
> Andreas
>
>> +
>>  #endif
>> 
>
>
> -- 
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Alexander Graf - June 20, 2013, 6:43 p.m.
Am 20.06.2013 um 17:42 schrieb Anthony Liguori <aliguori@us.ibm.com>:

> Andreas Färber <afaerber@suse.de> writes:
> 
>> Am 19.06.2013 22:40, schrieb Anthony Liguori:
>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>> ---
>>> qtest.c          | 29 +++++++++++++++++++++++++++++
>>> tests/libqtest.c | 18 ++++++++++++++++++
>>> tests/libqtest.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 93 insertions(+)
>>> 
>>> diff --git a/qtest.c b/qtest.c
>>> index 07a9612..f8c8f44 100644
>>> --- a/qtest.c
>>> +++ b/qtest.c
>>> @@ -19,6 +19,9 @@
>>> #include "hw/irq.h"
>>> #include "sysemu/sysemu.h"
>>> #include "sysemu/cpus.h"
>>> +#ifdef TARGET_PPC64
>>> +#include "hw/ppc/spapr.h"
>>> +#endif
>>> 
>>> #define MAX_IRQ 256
>>> 
>>> @@ -141,6 +144,13 @@ static bool qtest_opened;
>>>  * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
>>>  * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
>>>  * NUM=0 even though it is remapped to GSI 2).
>>> + *
>>> + * Platform specific (sPAPR):
>>> + *
>>> + *  > papr_hypercall NR ARG0 ARG1 ... ARG8
>> 
>> The functions are called spapr_hcall*() but the protocol uses
>> papr_hypercall?
> 
> The discrepancy is inherited in the KVM vs. QEMU interfaces.  It's
> called papr_hypercall in the KVM interface vs. spapr in QEMU.
> 
> I honestly don't know what the distinction between spapr and papr is.

PAPR is what PAPR calls itself. However, there is also an ePAPR for BookE, so in order to distinguish the 2 more easily, we named the server version spapr wherever we remembered to.


Alex
Anthony Liguori - June 20, 2013, 6:58 p.m.
Alexander Graf <agraf@suse.de> writes:

> Am 20.06.2013 um 17:42 schrieb Anthony Liguori <aliguori@us.ibm.com>:
>
>> Andreas Färber <afaerber@suse.de> writes:
>> 
>>> Am 19.06.2013 22:40, schrieb Anthony Liguori:
>>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>>> ---
>>>> qtest.c          | 29 +++++++++++++++++++++++++++++
>>>> tests/libqtest.c | 18 ++++++++++++++++++
>>>> tests/libqtest.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 93 insertions(+)
>>>> 
>>>> diff --git a/qtest.c b/qtest.c
>>>> index 07a9612..f8c8f44 100644
>>>> --- a/qtest.c
>>>> +++ b/qtest.c
>>>> @@ -19,6 +19,9 @@
>>>> #include "hw/irq.h"
>>>> #include "sysemu/sysemu.h"
>>>> #include "sysemu/cpus.h"
>>>> +#ifdef TARGET_PPC64
>>>> +#include "hw/ppc/spapr.h"
>>>> +#endif
>>>> 
>>>> #define MAX_IRQ 256
>>>> 
>>>> @@ -141,6 +144,13 @@ static bool qtest_opened;
>>>>  * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
>>>>  * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
>>>>  * NUM=0 even though it is remapped to GSI 2).
>>>> + *
>>>> + * Platform specific (sPAPR):
>>>> + *
>>>> + *  > papr_hypercall NR ARG0 ARG1 ... ARG8
>>> 
>>> The functions are called spapr_hcall*() but the protocol uses
>>> papr_hypercall?
>> 
>> The discrepancy is inherited in the KVM vs. QEMU interfaces.  It's
>> called papr_hypercall in the KVM interface vs. spapr in QEMU.
>> 
>> I honestly don't know what the distinction between spapr and papr is.
>
> PAPR is what PAPR calls itself. However, there is also an ePAPR for
> BookE, so in order to distinguish the 2 more easily, we named the
> server version spapr wherever we remembered to.

So does it make sense to have papr_hypercall()?  Do hypercalls exist
with the virtualization extensions on BookE?

Regards,

Anthony Liguori

>
>
> Alex
Alexander Graf - June 20, 2013, 9:57 p.m.
On 20.06.2013, at 20:58, Anthony Liguori wrote:

> Alexander Graf <agraf@suse.de> writes:
> 
>> Am 20.06.2013 um 17:42 schrieb Anthony Liguori <aliguori@us.ibm.com>:
>> 
>>> Andreas Färber <afaerber@suse.de> writes:
>>> 
>>>> Am 19.06.2013 22:40, schrieb Anthony Liguori:
>>>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>>>> ---
>>>>> qtest.c          | 29 +++++++++++++++++++++++++++++
>>>>> tests/libqtest.c | 18 ++++++++++++++++++
>>>>> tests/libqtest.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>> 3 files changed, 93 insertions(+)
>>>>> 
>>>>> diff --git a/qtest.c b/qtest.c
>>>>> index 07a9612..f8c8f44 100644
>>>>> --- a/qtest.c
>>>>> +++ b/qtest.c
>>>>> @@ -19,6 +19,9 @@
>>>>> #include "hw/irq.h"
>>>>> #include "sysemu/sysemu.h"
>>>>> #include "sysemu/cpus.h"
>>>>> +#ifdef TARGET_PPC64
>>>>> +#include "hw/ppc/spapr.h"
>>>>> +#endif
>>>>> 
>>>>> #define MAX_IRQ 256
>>>>> 
>>>>> @@ -141,6 +144,13 @@ static bool qtest_opened;
>>>>> * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
>>>>> * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
>>>>> * NUM=0 even though it is remapped to GSI 2).
>>>>> + *
>>>>> + * Platform specific (sPAPR):
>>>>> + *
>>>>> + *  > papr_hypercall NR ARG0 ARG1 ... ARG8
>>>> 
>>>> The functions are called spapr_hcall*() but the protocol uses
>>>> papr_hypercall?
>>> 
>>> The discrepancy is inherited in the KVM vs. QEMU interfaces.  It's
>>> called papr_hypercall in the KVM interface vs. spapr in QEMU.
>>> 
>>> I honestly don't know what the distinction between spapr and papr is.
>> 
>> PAPR is what PAPR calls itself. However, there is also an ePAPR for
>> BookE, so in order to distinguish the 2 more easily, we named the
>> server version spapr wherever we remembered to.
> 
> So does it make sense to have papr_hypercall()?  Do hypercalls exist
> with the virtualization extensions on BookE?

papr_hypercall() really means spapr_hypercall() :). I don't think we should mangle ePAPR and sPAPR together.


Alex

Patch

diff --git a/qtest.c b/qtest.c
index 07a9612..f8c8f44 100644
--- a/qtest.c
+++ b/qtest.c
@@ -19,6 +19,9 @@ 
 #include "hw/irq.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/cpus.h"
+#ifdef TARGET_PPC64
+#include "hw/ppc/spapr.h"
+#endif
 
 #define MAX_IRQ 256
 
@@ -141,6 +144,13 @@  static bool qtest_opened;
  * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
  * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
  * NUM=0 even though it is remapped to GSI 2).
+ *
+ * Platform specific (sPAPR):
+ *
+ *  > papr_hypercall NR ARG0 ARG1 ... ARG8
+ *  < OK RET
+ *
+ * where NR, ARG[0-8] and RET are all integers.
  */
 
 static int hex2nib(char ch)
@@ -425,6 +435,25 @@  static void qtest_process_command(CharDriverState *chr, gchar **words)
         qtest_clock_warp(ns);
         qtest_send_prefix(chr);
         qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+#ifdef TARGET_PPC64
+    } else if (strcmp(words[0], "papr_hypercall") == 0) {
+        uint64_t nr;
+        uint64_t args[9];
+        uint64_t ret;
+        int i;
+
+        memset(args, 0, sizeof(args));
+        g_assert(words[1]);
+        nr = strtoull(words[1], NULL, 0);
+        for (i = 0; i < 9; i++) {
+            if (words[2 + i] == NULL) {
+                break;
+            }
+            args[i] = strtoull(words[2 + i], NULL, 0);
+        }
+        ret = spapr_hypercall(ppc_env_get_cpu(first_cpu), nr, args);
+        qtest_send(chr, "OK 0x%" PRIx64 "\n", ret);
+#endif
     } else {
         qtest_send_prefix(chr);
         qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 879ffe9..81107cf 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -544,3 +544,21 @@  void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)
     qtest_sendf(s, "\n");
     qtest_rsp(s, 0);
 }
+
+uint64_t qtest_spapr_hcall9(QTestState *s, uint64_t nr, uint64_t a0,
+                            uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4,
+                            uint64_t a5, uint64_t a6, uint64_t a7, uint64_t a8)
+{
+    gchar **args;
+    uint64_t value;
+
+    qtest_sendf(s, "papr_hypercall 0x%" PRIx64 " 0x%" PRIx64
+                " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 
+                " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 
+                "\n", nr, a0, a1, a2, a3, a4, a5, a6, a7, a8);
+    args = qtest_rsp(s, 2);
+    value = strtoull(args[1], NULL, 0);
+    g_strfreev(args);
+
+    return value;
+}
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 437bda3..592f035 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -286,6 +286,19 @@  int64_t qtest_clock_step(QTestState *s, int64_t step);
 int64_t qtest_clock_set(QTestState *s, int64_t val);
 
 /**
+ * qtest_spapr_hcall9:
+ * @s: QTestState instance to operate on.
+ * @nr: The hypercall index
+ * @aN: The @Nth hypercall argument
+ *
+ * Issue an sPAPR hypercall
+ *
+ * Returns: The result of the hypercall.
+ */
+uint64_t qtest_spapr_hcall9(QTestState *s, uint64_t nr, uint64_t a0,
+                            uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4,
+                            uint64_t a5, uint64_t a6, uint64_t a7, uint64_t a8);
+/**
  * qtest_get_arch:
  *
  * Returns: The architecture for the QEMU executable under test.
@@ -607,4 +620,37 @@  static inline int64_t clock_set(int64_t val)
     return qtest_clock_set(global_qtest, val);
 }
 
+static inline uint64_t spapr_hcall0(uint64_t nr)
+{
+    return qtest_spapr_hcall9(global_qtest, nr, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+}
+
+static inline uint64_t spapr_hcall1(uint64_t nr, uint64_t a0)
+{
+    return qtest_spapr_hcall9(global_qtest, nr, a0, 0, 0, 0, 0, 0, 0, 0, 0);
+}
+
+static inline uint64_t spapr_hcall2(uint64_t nr, uint64_t a0, uint64_t a1)
+{
+    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, 0, 0, 0, 0, 0, 0, 0);
+}
+
+static inline uint64_t spapr_hcall3(uint64_t nr, uint64_t a0, uint64_t a1,
+                                    uint64_t a2)
+{
+    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, a2, 0, 0, 0, 0, 0, 0);
+}
+
+static inline uint64_t spapr_hcall4(uint64_t nr, uint64_t a0, uint64_t a1,
+                                    uint64_t a2, uint64_t a3)
+{
+    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, a2, a3, 0, 0, 0, 0, 0);
+}
+
+static inline uint64_t spapr_hcall5(uint64_t nr, uint64_t a0, uint64_t a1,
+                                    uint64_t a2, uint64_t a3, uint64_t a4)
+{
+    return qtest_spapr_hcall9(global_qtest, nr, a0, a1, a2, a3, a4, 0, 0, 0, 0);
+}
+
 #endif