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 <[email protected]> > --- > 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
