All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] spapr-rtas: add ibm,get-vpd RTAS interface
@ 2019-02-23 14:40 Maxiwell S. Garcia
  2019-02-25  5:11 ` [Qemu-devel] [PATCH] spapr-rtas: add ibm, get-vpd " David Gibson
  0 siblings, 1 reply; 3+ messages in thread
From: Maxiwell S. Garcia @ 2019-02-23 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: Maxiwell S. Garcia, David Gibson, open list:sPAPR

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

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

* Re: [Qemu-devel] [PATCH] spapr-rtas: add ibm, get-vpd RTAS interface
  2019-02-23 14:40 [Qemu-devel] [PATCH] spapr-rtas: add ibm,get-vpd RTAS interface Maxiwell S. Garcia
@ 2019-02-25  5:11 ` David Gibson
  2019-02-25 16:12   ` [Qemu-devel] [Qemu-ppc] " Maxiwell S. Garcia
  0 siblings, 1 reply; 3+ messages in thread
From: David Gibson @ 2019-02-25  5:11 UTC (permalink / raw)
  To: Maxiwell S. Garcia; +Cc: qemu-devel, open list:sPAPR

[-- Attachment #1: Type: text/plain, Size: 9464 bytes --]

On Sat, Feb 23, 2019 at 11:40:57AM -0300, Maxiwell S. Garcia wrote:
> 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';

ITYM
	char *field = "\0";

Assigning field to an empty string.  As it is '\0' is being coerced to
an integer (0) then to a pointer (NULL)...

> +
> +    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));

... which it isn't safe to call strlen() on.

> +    g_free(field);

But.. then again, g_free() is safe to call on NULL, but not safe to
call on a statically allocated string.  Either way, something needs
fixing.

> +}
> +
>  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

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr-rtas: add ibm, get-vpd RTAS interface
  2019-02-25  5:11 ` [Qemu-devel] [PATCH] spapr-rtas: add ibm, get-vpd " David Gibson
@ 2019-02-25 16:12   ` Maxiwell S. Garcia
  0 siblings, 0 replies; 3+ messages in thread
From: Maxiwell S. Garcia @ 2019-02-25 16:12 UTC (permalink / raw)
  To: David Gibson; +Cc: open list:sPAPR, qemu-devel

On Mon, Feb 25, 2019 at 04:11:53PM +1100, David Gibson wrote:
> On Sat, Feb 23, 2019 at 11:40:57AM -0300, Maxiwell S. Garcia wrote:
> > 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';
> 
> ITYM
> 	char *field = "\0";
> 
> Assigning field to an empty string.  As it is '\0' is being coerced to
> an integer (0) then to a pointer (NULL)...
> 
> > +
> > +    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));
> 
> ... which it isn't safe to call strlen() on.
> 
> > +    g_free(field);
> 
> But.. then again, g_free() is safe to call on NULL, but not safe to
> call on a statically allocated string.  Either way, something needs
> fixing.
> 

Ok, I will fix those issues.
Thank you.

> > +}
> > +
> >  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
> 
> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

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

end of thread, other threads:[~2019-02-25 16:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-23 14:40 [Qemu-devel] [PATCH] spapr-rtas: add ibm,get-vpd RTAS interface Maxiwell S. Garcia
2019-02-25  5:11 ` [Qemu-devel] [PATCH] spapr-rtas: add ibm, get-vpd " David Gibson
2019-02-25 16:12   ` [Qemu-devel] [Qemu-ppc] " 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.