Re: [Qemu-devel] [PATCH] spapr-rtas: add ibm, get-vpd RTAS interface
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 > --- > 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", > +_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, _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 =
[Qemu-devel] [PATCH] spapr-rtas: add ibm,get-vpd RTAS interface
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 --- 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", +_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, _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(_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); +} +