All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 0/2] spapr-rtas: add ibm, get-vpd RTAS interface
@ 2019-03-11 22:57 Maxiwell S. Garcia
  2019-03-11 22:57 ` [Qemu-devel] [PATCH v5 1/2] spapr: helper functions to get valid host fields Maxiwell S. Garcia
  2019-03-11 22:57 ` [Qemu-devel] [PATCH v5 2/2] spapr-rtas: add ibm, get-vpd RTAS interface Maxiwell S. Garcia
  0 siblings, 2 replies; 3+ messages in thread
From: Maxiwell S. Garcia @ 2019-03-11 22:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: david, qemu-ppc, Maxiwell S. Garcia

Here are two patches to add a handler for ibm,get-vpd RTAS calls.
This RTAS exposes host information in case of set QEMU options
'host-serial' and 'host-model' as 'passthrough'.

The patch 1 creates helper functions to get valid 'host-serial'
and 'host-model' parameters, guided by QEMU command line. These
parameters are useful to build the guest device tree and to return
get-vpd RTAS calls. The patch 2 adds the ibm,get-vpd itself.


Maxiwell S. Garcia (2):
  spapr: helper functions to get valid host fields
  spapr-rtas: add ibm,get-vpd RTAS interface

 hw/ppc/spapr.c         |  58 +++++++++++++---------
 hw/ppc/spapr_rtas.c    | 110 +++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h |  15 +++++-
 3 files changed, 160 insertions(+), 23 deletions(-)

-- 
2.20.1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Qemu-devel] [PATCH v5 1/2] spapr: helper functions to get valid host fields
  2019-03-11 22:57 [Qemu-devel] [PATCH v5 0/2] spapr-rtas: add ibm, get-vpd RTAS interface Maxiwell S. Garcia
@ 2019-03-11 22:57 ` Maxiwell S. Garcia
  2019-03-11 22:57 ` [Qemu-devel] [PATCH v5 2/2] spapr-rtas: add ibm, get-vpd RTAS interface Maxiwell S. Garcia
  1 sibling, 0 replies; 3+ messages in thread
From: Maxiwell S. Garcia @ 2019-03-11 22:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: david, qemu-ppc, Maxiwell S. Garcia

The pseries options 'host-serial' and 'host-model' accepts
'none', 'passthrough', or <string> content. The helper
functions in this commit return a valid host field based on
user options.

Signed-off-by: Maxiwell S. Garcia <maxiwell@linux.ibm.com>
---
 hw/ppc/spapr.c         | 58 ++++++++++++++++++++++++++----------------
 include/hw/ppc/spapr.h |  3 +++
 2 files changed, 39 insertions(+), 22 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9e01226e18..a3078f0261 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1202,6 +1202,34 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt)
     g_free(bootlist);
 }
 
+char *spapr_get_valid_host_serial(sPAPRMachineState *spapr)
+{
+    char *host_serial = NULL;
+    if (spapr->host_serial && !g_str_equal(spapr->host_serial, "none")) {
+        if (g_str_equal(spapr->host_serial, "passthrough")) {
+            /* -M host-serial=passthrough */
+            kvmppc_get_host_serial(&host_serial);
+        } else {
+            host_serial = g_strdup(spapr->host_serial);
+        }
+    }
+    return host_serial;
+}
+
+char *spapr_get_valid_host_model(sPAPRMachineState *spapr)
+{
+    char *host_model = NULL;
+    if (spapr->host_model && !g_str_equal(spapr->host_model, "none")) {
+        if (g_str_equal(spapr->host_model, "passthrough")) {
+            /* -M host-model=passthrough */
+            kvmppc_get_host_model(&host_model);
+        } else {
+            host_model = g_strdup(spapr->host_model);
+        }
+    }
+    return host_model;
+}
+
 static void spapr_dt_hypervisor(sPAPRMachineState *spapr, void *fdt)
 {
     /* The /hypervisor node isn't in PAPR - this is a hack to allow PR
@@ -1247,30 +1275,16 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr)
      * Add info to guest to indentify which host is it being run on
      * and what is the uuid of the guest
      */
-    if (spapr->host_model && !g_str_equal(spapr->host_model, "none")) {
-        if (g_str_equal(spapr->host_model, "passthrough")) {
-            /* -M host-model=passthrough */
-            if (kvmppc_get_host_model(&buf)) {
-                _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
-                g_free(buf);
-            }
-        } else {
-            /* -M host-model=<user-string> */
-            _FDT(fdt_setprop_string(fdt, 0, "host-model", spapr->host_model));
-        }
+    buf = spapr_get_valid_host_model(spapr);
+    if (buf) {
+        _FDT(fdt_setprop_string(fdt, 0, "host-model", buf));
+        g_free(buf);
     }
 
-    if (spapr->host_serial && !g_str_equal(spapr->host_serial, "none")) {
-        if (g_str_equal(spapr->host_serial, "passthrough")) {
-            /* -M host-serial=passthrough */
-            if (kvmppc_get_host_serial(&buf)) {
-                _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
-                g_free(buf);
-            }
-        } else {
-            /* -M host-serial=<user-string> */
-            _FDT(fdt_setprop_string(fdt, 0, "host-serial", spapr->host_serial));
-        }
+    buf = spapr_get_valid_host_serial(spapr);
+    if (buf) {
+        _FDT(fdt_setprop_string(fdt, 0, "host-serial", buf));
+        g_free(buf);
     }
 
     buf = qemu_uuid_unparse_strdup(&qemu_uuid);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 59073a7579..f7ea99dc69 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -842,6 +842,9 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr);
 
 void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
                           Error **errp);
+
+char *spapr_get_valid_host_serial(sPAPRMachineState *spapr);
+char *spapr_get_valid_host_model(sPAPRMachineState *spapr);
 /*
  * XIVE definitions
  */
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [Qemu-devel] [PATCH v5 2/2] spapr-rtas: add ibm, get-vpd RTAS interface
  2019-03-11 22:57 [Qemu-devel] [PATCH v5 0/2] spapr-rtas: add ibm, get-vpd RTAS interface Maxiwell S. Garcia
  2019-03-11 22:57 ` [Qemu-devel] [PATCH v5 1/2] spapr: helper functions to get valid host fields Maxiwell S. Garcia
@ 2019-03-11 22:57 ` Maxiwell S. Garcia
  1 sibling, 0 replies; 3+ messages in thread
From: Maxiwell S. Garcia @ 2019-03-11 22:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: david, qemu-ppc, Maxiwell S. Garcia

This adds a handler for ibm,get-vpd RTAS calls, allowing pseries guest
to collect host information. It is disabled by default to avoid unwanted
information leakage. To enable it, use:

‘-M pseries,host-serial={passthrough|string},host-model={passthrough|string}’

Only the SE and TM keywords are returned at the moment.
SE for Machine or Cabinet Serial Number and
TM for Machine Type and Model

The SE and TM keywords are controlled by 'host-serial' and 'host-model'
options, respectively. In the case of 'passthrough', the SE shows the
host 'system-id' information and the TM shows the host 'model' information.

Powerpc-utils tools can dispatch RTAS calls to retrieve host
information using this ibm,get-vpd interface. The 'host-serial'
and 'host-model' nodes of device-tree hold the same information but
in a static manner, which is useless after a migration operation.

Signed-off-by: Maxiwell S. Garcia <maxiwell@linux.ibm.com>
---
 hw/ppc/spapr_rtas.c    | 110 +++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h |  12 ++++-
 2 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 7a2cb786a3..778abcef91 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -287,6 +287,112 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
     rtas_st(rets, 0, ret);
 }
 
+static inline int vpd_st(target_ulong addr, target_ulong len,
+                         const void *val, uint16_t val_len)
+{
+    hwaddr phys = ppc64_phys_to_real(addr);
+    if (len < val_len) {
+        return RTAS_OUT_PARAM_ERROR;
+    }
+    cpu_physical_memory_write(phys, val, val_len);
+    return RTAS_OUT_SUCCESS;
+}
+
+static inline void vpd_ret(target_ulong rets, const int status,
+                           const int next_seq_number, const int bytes_returned)
+{
+    rtas_st(rets, 0, status);
+    rtas_st(rets, 1, next_seq_number);
+    rtas_st(rets, 2, bytes_returned);
+}
+
+static struct {
+    char *keyword;
+    char *value;
+} rtas_get_vpd_fields[RTAS_IBM_GET_VPD_KEYWORDS_MAX + 1];
+
+static void rtas_ibm_get_vpd_fields_register(sPAPRMachineState *sm)
+{
+    int i = 0;
+    char *buf = NULL;
+
+    memset(rtas_get_vpd_fields, 0, sizeof(rtas_get_vpd_fields));
+
+    buf = spapr_get_valid_host_serial(sm);
+    if (buf) {
+        rtas_get_vpd_fields[i].keyword = g_strdup("SE");
+        rtas_get_vpd_fields[i++].value = g_strdup(buf);
+        g_free(buf);
+    }
+    buf = spapr_get_valid_host_model(sm);
+    if (buf) {
+        rtas_get_vpd_fields[i].keyword = g_strdup("TM");
+        rtas_get_vpd_fields[i++].value = g_strdup(buf);
+        g_free(buf);
+    }
+}
+
+static void rtas_ibm_get_vpd(PowerPCCPU *cpu,
+                             sPAPRMachineState *spapr,
+                             uint32_t token, uint32_t nargs,
+                             target_ulong args,
+                             uint32_t nret, target_ulong rets)
+{
+    target_ulong loc_code_addr;
+    target_ulong work_area_addr;
+    target_ulong work_area_size;
+    target_ulong seq_number;
+    unsigned char loc_code = 0;
+    unsigned int next_seq_number = 1;
+    int status = RTAS_IBM_GET_VPD_PARAMETER_ERROR;
+    int ret = RTAS_OUT_PARAM_ERROR;
+    char *vpd_field = NULL;
+    unsigned int vpd_field_len = 0;
+
+    /* RTAS not authorized if no keywords have been registered */
+    if (!rtas_get_vpd_fields[0].keyword) {
+        vpd_ret(rets, RTAS_OUT_NOT_AUTHORIZED, 1, 0);
+        return;
+    }
+
+    loc_code_addr = rtas_ld(args, 0);
+    work_area_addr = rtas_ld(args, 1);
+    work_area_size = rtas_ld(args, 2);
+    seq_number = rtas_ld(args, 3);
+
+    /* Specific Location Code is not supported and seq_number */
+    /* must be checked to avoid out of bound index error */
+    cpu_physical_memory_read(loc_code_addr, &loc_code, 1);
+    if ((loc_code != 0) || (seq_number <= 0) ||
+        (seq_number > RTAS_IBM_GET_VPD_KEYWORDS_MAX)) {
+        vpd_ret(rets, RTAS_IBM_GET_VPD_PARAMETER_ERROR, 1, 0);
+        return;
+    }
+
+    vpd_field = g_strdup_printf("%s %s",
+                rtas_get_vpd_fields[seq_number - 1].keyword,
+                rtas_get_vpd_fields[seq_number - 1].value);
+
+    if (vpd_field) {
+        vpd_field_len = strlen(vpd_field);
+        ret = vpd_st(work_area_addr, work_area_size,
+                     vpd_field, vpd_field_len + 1);
+
+        if (ret == 0) {
+            next_seq_number = seq_number + 1;
+            if (rtas_get_vpd_fields[next_seq_number - 1].keyword) {
+                status = RTAS_IBM_GET_VPD_CONTINUE;
+            } else {
+                status = RTAS_IBM_GET_VPD_SUCCESS;
+                next_seq_number = 1;
+            }
+        }
+    }
+
+    vpd_ret(rets, status, next_seq_number, vpd_field_len);
+    g_free(vpd_field);
+}
+
 static void rtas_ibm_os_term(PowerPCCPU *cpu,
                             sPAPRMachineState *spapr,
                             uint32_t token, uint32_t nargs,
@@ -464,6 +570,8 @@ void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr)
                      fdt_strerror(ret));
         exit(1);
     }
+
+    rtas_ibm_get_vpd_fields_register(spapr);
 }
 
 static void core_rtas_register_types(void)
@@ -485,6 +593,8 @@ static void core_rtas_register_types(void)
                         rtas_ibm_set_system_parameter);
     spapr_rtas_register(RTAS_IBM_OS_TERM, "ibm,os-term",
                         rtas_ibm_os_term);
+    spapr_rtas_register(RTAS_IBM_GET_VPD, "ibm,get-vpd",
+                        rtas_ibm_get_vpd);
     spapr_rtas_register(RTAS_SET_POWER_LEVEL, "set-power-level",
                         rtas_set_power_level);
     spapr_rtas_register(RTAS_GET_POWER_LEVEL, "get-power-level",
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index f7ea99dc69..84e57c3f34 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -608,14 +608,24 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
 #define RTAS_IBM_CREATE_PE_DMA_WINDOW           (RTAS_TOKEN_BASE + 0x27)
 #define RTAS_IBM_REMOVE_PE_DMA_WINDOW           (RTAS_TOKEN_BASE + 0x28)
 #define RTAS_IBM_RESET_PE_DMA_WINDOW            (RTAS_TOKEN_BASE + 0x29)
+#define RTAS_IBM_GET_VPD                        (RTAS_TOKEN_BASE + 0x2A)
 
-#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x2A)
+#define RTAS_TOKEN_MAX                          (RTAS_TOKEN_BASE + 0x2B)
 
 /* RTAS ibm,get-system-parameter token values */
 #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS      20
 #define RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE        42
 #define RTAS_SYSPARM_UUID                        48
 
+/* RTAS ibm,get-vpd status values */
+#define RTAS_IBM_GET_VPD_VPD_CHANGED     -4
+#define RTAS_IBM_GET_VPD_PARAMETER_ERROR -3
+#define RTAS_IBM_GET_VPD_HARDWARE_ERROR  -1
+#define RTAS_IBM_GET_VPD_SUCCESS          0
+#define RTAS_IBM_GET_VPD_CONTINUE         1
+
+#define RTAS_IBM_GET_VPD_KEYWORDS_MAX     2
+
 /* RTAS indicator/sensor types
  *
  * as defined by PAPR+ 2.7 7.3.5.4, Table 41
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-03-11 23:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-11 22:57 [Qemu-devel] [PATCH v5 0/2] spapr-rtas: add ibm, get-vpd RTAS interface Maxiwell S. Garcia
2019-03-11 22:57 ` [Qemu-devel] [PATCH v5 1/2] spapr: helper functions to get valid host fields Maxiwell S. Garcia
2019-03-11 22:57 ` [Qemu-devel] [PATCH v5 2/2] spapr-rtas: add ibm, get-vpd RTAS interface Maxiwell S. Garcia

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.