On Mon, Mar 21, 2016 at 06:46:55PM +1100, Alexey Kardashevskiy wrote: > The source guest could have reallocated the default TCE table and > migrate bigger/smaller table. This adds reallocation in post_load() > if the default table size is different on source and destination. > > Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> > --- > Changes: > v14: > * new to the series > --- > hw/ppc/spapr_iommu.c | 36 ++++++++++++++++++++++++++++++++++-- > include/hw/ppc/spapr.h | 2 ++ > 2 files changed, 36 insertions(+), 2 deletions(-) > > diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c > index 9bcd3f6..549cd94 100644 > --- a/hw/ppc/spapr_iommu.c > +++ b/hw/ppc/spapr_iommu.c > @@ -137,6 +137,16 @@ static IOMMUTLBEntry > spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr, > return ret; > } > > +static void spapr_tce_table_pre_save(void *opaque) > +{ > + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); > + > + tcet->mig_table = tcet->table;
Don't you need to set mig_nb_table here as well? I can't see anywhere else it's initialized. > +} > + > +static void spapr_tce_table_do_enable(sPAPRTCETable *tcet); > +static void spapr_tce_table_do_disable(sPAPRTCETable *tcet); > + > static int spapr_tce_table_post_load(void *opaque, int version_id) > { > sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); > @@ -145,6 +155,26 @@ static int spapr_tce_table_post_load(void *opaque, int > version_id) > spapr_vio_set_bypass(tcet->vdev, tcet->bypass); > } > > + if (tcet->enabled) { > + if (tcet->nb_table != tcet->mig_nb_table) { > + if (tcet->nb_table) { > + spapr_tce_table_do_disable(tcet); > + } > + tcet->nb_table = tcet->mig_nb_table; > + spapr_tce_table_do_enable(tcet); > + } > + > + memcpy(tcet->table, tcet->mig_table, > + tcet->nb_table * sizeof(tcet->table[0])); > + > + free(tcet->mig_table); > + tcet->mig_table = NULL; > + > + } else if (tcet->table) { > + /* Destination guest has a default table but source does not -> free > */ > + spapr_tce_table_do_disable(tcet); > + } > + Clunky, but I don't know of a better way. > return 0; > } > > @@ -152,15 +182,17 @@ static const VMStateDescription vmstate_spapr_tce_table > = { > .name = "spapr_iommu", > .version_id = 2, > .minimum_version_id = 2, > + .pre_save = spapr_tce_table_pre_save, > .post_load = spapr_tce_table_post_load, > .fields = (VMStateField []) { > /* Sanity check */ > VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable), > - VMSTATE_UINT32_EQUAL(nb_table, sPAPRTCETable), > > /* IOMMU state */ > + VMSTATE_UINT32(mig_nb_table, sPAPRTCETable), > VMSTATE_BOOL(bypass, sPAPRTCETable), > - VMSTATE_VARRAY_UINT32(table, sPAPRTCETable, nb_table, 0, > vmstate_info_uint64, uint64_t), > + VMSTATE_VARRAY_UINT32_ALLOC(mig_table, sPAPRTCETable, nb_table, 0, > + vmstate_info_uint64, uint64_t), > > VMSTATE_END_OF_LIST() > }, > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index 75b0b55..c1ea49c 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -545,6 +545,8 @@ struct sPAPRTCETable { > uint64_t bus_offset; > uint32_t page_shift; > uint64_t *table; > + uint32_t mig_nb_table; > + uint64_t *mig_table; > bool bypass; > bool need_vfio; > int fd; -- 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
signature.asc
Description: PGP signature