All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Maxiwell S. Garcia" <maxiwell@linux.ibm.com>
To: qemu-devel@nongnu.org
Cc: "Maxiwell S. Garcia" <maxiwell@linux.ibm.com>,
	David Gibson <david@gibson.dropbear.id.au>,
	"open list:sPAPR" <qemu-ppc@nongnu.org>
Subject: [Qemu-devel] [PATCH] spapr-rtas: add ibm,get-vpd RTAS interface
Date: Sat, 23 Feb 2019 11:40:57 -0300	[thread overview]
Message-ID: <20190223144057.10509-1-maxiwell@linux.ibm.com> (raw)

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,vpd-export=on’

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.

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.c         | 21 ++++++++++
 hw/ppc/spapr_rtas.c    | 93 ++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h | 17 +++++++-
 3 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index abf9ebce59..09fd9e2ebb 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3026,6 +3026,20 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
     return NULL;
 }
 
+static bool spapr_get_vpd_export(Object *obj, Error **errp)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+
+    return spapr->vpd_export;
+}
+
+static void spapr_set_vpd_export(Object *obj, bool value, Error **errp)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+
+    spapr->vpd_export = value;
+}
+
 static char *spapr_get_kvm_type(Object *obj, Error **errp)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
@@ -3150,6 +3164,7 @@ static void spapr_instance_init(Object *obj)
     sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 
     spapr->htab_fd = -1;
+    spapr->vpd_export = false;
     spapr->use_hotplug_event_source = true;
     object_property_add_str(obj, "kvm-type",
                             spapr_get_kvm_type, spapr_set_kvm_type, NULL);
@@ -3182,6 +3197,12 @@ static void spapr_instance_init(Object *obj)
     object_property_add_bool(obj, "vfio-no-msix-emulation",
                              spapr_get_msix_emulation, NULL, NULL);
 
+    object_property_add_bool(obj, "vpd-export", spapr_get_vpd_export,
+                             spapr_set_vpd_export, NULL);
+    object_property_set_description(obj, "vpd-export",
+                                    "Export Host's VPD information to guest",
+                                    &error_abort);
+
     /* The machine class defines the default interrupt controller mode */
     spapr->irq = smc->irq;
     object_property_add_str(obj, "ic-mode", spapr_get_ic_mode,
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index d6a0952154..214e0edfc5 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -287,6 +287,97 @@ 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 void rtas_ibm_get_vpd(PowerPCCPU *cpu,
+                             sPAPRMachineState *spapr,
+                             uint32_t token, uint32_t nargs,
+                             target_ulong args,
+                             uint32_t nret, target_ulong rets)
+{
+    sPAPRMachineState *sm = SPAPR_MACHINE(spapr);
+    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 = 0;
+    int status = RTAS_IBM_GET_VPD_PARAMETER_ERROR;
+    int ret = 0;
+    char *field = '\0';
+
+    if (!sm->vpd_export) {
+        vpd_ret(rets, RTAS_OUT_NOT_AUTHORIZED, 1, 0);
+        return;
+    }
+
+    /* Specific Location Code is not supported */
+    loc_code_addr = rtas_ld(args, 0);
+    cpu_physical_memory_read(loc_code_addr, &loc_code, 1);
+    if (loc_code != 0) {
+        vpd_ret(rets, RTAS_IBM_GET_VPD_PARAMETER_ERROR, 1, 0);
+        return;
+    }
+
+    work_area_addr = rtas_ld(args, 1);
+    work_area_size = rtas_ld(args, 2);
+    seq_number = rtas_ld(args, 3);
+    switch (seq_number) {
+        case RTAS_IBM_VPD_KEYWORD_SE: {
+            char *host_serial;
+            if (kvmppc_get_host_serial(&host_serial)) {
+                /* LoPAPR: SE for Machine or Cabinet Serial Number */
+                field = g_strdup_printf("SE %s", host_serial);
+                ret = vpd_st(work_area_addr, work_area_size,
+                             field, strlen(field) + 1);
+                g_free(host_serial);
+            }
+            break;
+        }
+        case RTAS_IBM_VPD_KEYWORD_TM: {
+            char *host_model;
+            if (kvmppc_get_host_model(&host_model)) {
+                /* LoPAPR: TM for Machine Type and Model */
+                field = g_strdup_printf("TM %s", host_model);
+                ret = vpd_st(work_area_addr, work_area_size,
+                             field, strlen(field) + 1);
+                g_free(host_model);
+            }
+            break;
+        }
+    }
+
+    if (ret == 0) {
+        if (seq_number == RTAS_IBM_VPD_KEYWORD_LAST) {
+            status = RTAS_IBM_GET_VPD_SUCCESS;
+            next_seq_number = 1;
+        } else {
+            status = RTAS_IBM_GET_VPD_CONTINUE;
+            next_seq_number = seq_number + 1;
+        }
+    }
+
+    vpd_ret(rets, status, next_seq_number, strlen(field));
+    g_free(field);
+}
+
 static void rtas_ibm_os_term(PowerPCCPU *cpu,
                             sPAPRMachineState *spapr,
                             uint32_t token, uint32_t nargs,
@@ -485,6 +576,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 631fc5103b..235b22340d 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -183,6 +183,7 @@ struct sPAPRMachineState {
     sPAPRXive  *xive;
     sPAPRIrq *irq;
     qemu_irq *qirqs;
+    bool vpd_export;
 
     bool cmd_line_caps[SPAPR_CAP_NUM];
     sPAPRCapabilities def, eff, mig;
@@ -605,14 +606,28 @@ 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
+
+/* RTAS ibm,get-vpd keywords index */
+#define RTAS_IBM_VPD_KEYWORD_SE     1
+#define RTAS_IBM_VPD_KEYWORD_TM     2
+
+#define RTAS_IBM_VPD_KEYWORD_LAST   2
+
 /* RTAS indicator/sensor types
  *
  * as defined by PAPR+ 2.7 7.3.5.4, Table 41
-- 
2.20.1

             reply	other threads:[~2019-02-23 14:49 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-23 14:40 Maxiwell S. Garcia [this message]
2019-02-25  5:11 ` [Qemu-devel] [PATCH] spapr-rtas: add ibm, get-vpd RTAS interface David Gibson
2019-02-25 16:12   ` [Qemu-devel] [Qemu-ppc] " Maxiwell S. Garcia

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190223144057.10509-1-maxiwell@linux.ibm.com \
    --to=maxiwell@linux.ibm.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.