PnvPsi needs to be able to save/load snapshots. Add VMSTATE information
to the device class and a post_load() method to restore dynamic data items and
memory region mappings.
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
Signed-off-by: Caleb Schlossin <calebs@linux.ibm.com>
---
hw/ppc/pnv_psi.c | 36 ++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 5d947d8b52..67bc911e4b 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -25,6 +25,7 @@
#include "qemu/module.h"
#include "system/reset.h"
#include "qapi/error.h"
+#include "migration/vmstate.h"
#include "hw/ppc/fdt.h"
@@ -130,12 +131,11 @@ static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
{
PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
MemoryRegion *sysmem = get_system_memory();
- uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);
/* Update MR, always remove it first */
- if (old & PSIHB_BAR_EN) {
+ if (memory_region_is_mapped(&psi->regs_mr)) {
memory_region_del_subregion(sysmem, &psi->regs_mr);
}
@@ -919,6 +919,37 @@ static const TypeInfo pnv_psi_power9_info = {
},
};
+static int vmstate_pnv_psi_post_load(void *opaque, int version_id)
+{
+ PnvPsi *psi = PNV_PSI(opaque);
+ Pnv9Psi *psi9 = PNV9_PSI(psi);
+ MemoryRegion *sysmem = get_system_memory();
+ uint64_t esb_bar;
+ hwaddr esb_addr;
+
+ /* Set the ESB MMIO mapping */
+ esb_bar = psi->regs[PSIHB_REG(PSIHB9_ESB_CI_BASE)];
+
+ if (esb_bar & PSIHB9_ESB_CI_VALID) {
+ esb_addr = esb_bar & PSIHB9_ESB_CI_ADDR_MASK;
+ memory_region_add_subregion(sysmem, esb_addr,
+ &psi9->source.esb_mmio);
+ }
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_pnv_psi = {
+ .name = TYPE_PNV_PSI,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = vmstate_pnv_psi_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT64_ARRAY(regs, PnvPsi, PSIHB_XSCOM_MAX),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void pnv_psi_power10_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -926,6 +957,7 @@ static void pnv_psi_power10_class_init(ObjectClass *klass, const void *data)
static const char compat[] = "ibm,power10-psihb-x\0ibm,psihb-x";
dc->desc = "PowerNV PSI Controller POWER10";
+ dc->vmsd = &vmstate_pnv_psi;
ppc->xscom_pcba = PNV10_XSCOM_PSIHB_BASE;
ppc->xscom_size = PNV10_XSCOM_PSIHB_SIZE;
--
2.47.3
Reviewed-by: Glenn Miles <milesg@linux.ibm.com>
Thanks,
Glenn
On Tue, 2025-12-16 at 09:13 -0600, Caleb Schlossin wrote:
> PnvPsi needs to be able to save/load snapshots. Add VMSTATE information
> to the device class and a post_load() method to restore dynamic data items and
> memory region mappings.
>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
> Signed-off-by: Caleb Schlossin <calebs@linux.ibm.com>
> ---
> hw/ppc/pnv_psi.c | 36 ++++++++++++++++++++++++++++++++++--
> 1 file changed, 34 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
> index 5d947d8b52..67bc911e4b 100644
> --- a/hw/ppc/pnv_psi.c
> +++ b/hw/ppc/pnv_psi.c
> @@ -25,6 +25,7 @@
> #include "qemu/module.h"
> #include "system/reset.h"
> #include "qapi/error.h"
> +#include "migration/vmstate.h"
>
>
> #include "hw/ppc/fdt.h"
> @@ -130,12 +131,11 @@ static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
> {
> PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
> MemoryRegion *sysmem = get_system_memory();
> - uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
>
> psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);
>
> /* Update MR, always remove it first */
> - if (old & PSIHB_BAR_EN) {
> + if (memory_region_is_mapped(&psi->regs_mr)) {
> memory_region_del_subregion(sysmem, &psi->regs_mr);
> }
>
> @@ -919,6 +919,37 @@ static const TypeInfo pnv_psi_power9_info = {
> },
> };
>
> +static int vmstate_pnv_psi_post_load(void *opaque, int version_id)
> +{
> + PnvPsi *psi = PNV_PSI(opaque);
> + Pnv9Psi *psi9 = PNV9_PSI(psi);
> + MemoryRegion *sysmem = get_system_memory();
> + uint64_t esb_bar;
> + hwaddr esb_addr;
> +
> + /* Set the ESB MMIO mapping */
> + esb_bar = psi->regs[PSIHB_REG(PSIHB9_ESB_CI_BASE)];
> +
> + if (esb_bar & PSIHB9_ESB_CI_VALID) {
> + esb_addr = esb_bar & PSIHB9_ESB_CI_ADDR_MASK;
> + memory_region_add_subregion(sysmem, esb_addr,
> + &psi9->source.esb_mmio);
> + }
> +
> + return 0;
> +}
> +
> +static const VMStateDescription vmstate_pnv_psi = {
> + .name = TYPE_PNV_PSI,
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .post_load = vmstate_pnv_psi_post_load,
> + .fields = (const VMStateField[]) {
> + VMSTATE_UINT64_ARRAY(regs, PnvPsi, PSIHB_XSCOM_MAX),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> static void pnv_psi_power10_class_init(ObjectClass *klass, const void *data)
> {
> DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -926,6 +957,7 @@ static void pnv_psi_power10_class_init(ObjectClass *klass, const void *data)
> static const char compat[] = "ibm,power10-psihb-x\0ibm,psihb-x";
>
> dc->desc = "PowerNV PSI Controller POWER10";
> + dc->vmsd = &vmstate_pnv_psi;
>
> ppc->xscom_pcba = PNV10_XSCOM_PSIHB_BASE;
> ppc->xscom_size = PNV10_XSCOM_PSIHB_SIZE;
Reviewed-by: Michael Kowal<kowal@linux.ibm.com>
Thanks, MAK
On 12/16/2025 10:24 AM, Miles Glenn wrote:
> Reviewed-by: Glenn Miles<milesg@linux.ibm.com>
>
> Thanks,
>
> Glenn
>
> On Tue, 2025-12-16 at 09:13 -0600, Caleb Schlossin wrote:
>> PnvPsi needs to be able to save/load snapshots. Add VMSTATE information
>> to the device class and a post_load() method to restore dynamic data items and
>> memory region mappings.
>>
>> Signed-off-by: Michael Kowal<kowal@linux.ibm.com>
>> Signed-off-by: Caleb Schlossin<calebs@linux.ibm.com>
>> ---
>> hw/ppc/pnv_psi.c | 36 ++++++++++++++++++++++++++++++++++--
>> 1 file changed, 34 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
>> index 5d947d8b52..67bc911e4b 100644
>> --- a/hw/ppc/pnv_psi.c
>> +++ b/hw/ppc/pnv_psi.c
>> @@ -25,6 +25,7 @@
>> #include "qemu/module.h"
>> #include "system/reset.h"
>> #include "qapi/error.h"
>> +#include "migration/vmstate.h"
>>
>>
>> #include "hw/ppc/fdt.h"
>> @@ -130,12 +131,11 @@ static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
>> {
>> PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
>> MemoryRegion *sysmem = get_system_memory();
>> - uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
>>
>> psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);
>>
>> /* Update MR, always remove it first */
>> - if (old & PSIHB_BAR_EN) {
>> + if (memory_region_is_mapped(&psi->regs_mr)) {
>> memory_region_del_subregion(sysmem, &psi->regs_mr);
>> }
>>
>> @@ -919,6 +919,37 @@ static const TypeInfo pnv_psi_power9_info = {
>> },
>> };
>>
>> +static int vmstate_pnv_psi_post_load(void *opaque, int version_id)
>> +{
>> + PnvPsi *psi = PNV_PSI(opaque);
>> + Pnv9Psi *psi9 = PNV9_PSI(psi);
>> + MemoryRegion *sysmem = get_system_memory();
>> + uint64_t esb_bar;
>> + hwaddr esb_addr;
>> +
>> + /* Set the ESB MMIO mapping */
>> + esb_bar = psi->regs[PSIHB_REG(PSIHB9_ESB_CI_BASE)];
>> +
>> + if (esb_bar & PSIHB9_ESB_CI_VALID) {
>> + esb_addr = esb_bar & PSIHB9_ESB_CI_ADDR_MASK;
>> + memory_region_add_subregion(sysmem, esb_addr,
>> + &psi9->source.esb_mmio);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static const VMStateDescription vmstate_pnv_psi = {
>> + .name = TYPE_PNV_PSI,
>> + .version_id = 1,
>> + .minimum_version_id = 1,
>> + .post_load = vmstate_pnv_psi_post_load,
>> + .fields = (const VMStateField[]) {
>> + VMSTATE_UINT64_ARRAY(regs, PnvPsi, PSIHB_XSCOM_MAX),
>> + VMSTATE_END_OF_LIST()
>> + }
>> +};
>> +
>> static void pnv_psi_power10_class_init(ObjectClass *klass, const void *data)
>> {
>> DeviceClass *dc = DEVICE_CLASS(klass);
>> @@ -926,6 +957,7 @@ static void pnv_psi_power10_class_init(ObjectClass *klass, const void *data)
>> static const char compat[] = "ibm,power10-psihb-x\0ibm,psihb-x";
>>
>> dc->desc = "PowerNV PSI Controller POWER10";
>> + dc->vmsd = &vmstate_pnv_psi;
>>
>> ppc->xscom_pcba = PNV10_XSCOM_PSIHB_BASE;
>> ppc->xscom_size = PNV10_XSCOM_PSIHB_SIZE;
© 2016 - 2025 Red Hat, Inc.