mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
spapr_iommu: Migrate full state
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. This adds @bus_offset, @page_shift to the migration stream as a subsection so when DDW is added, migration to older machines will still be possible. As @bus_offset and @page_shift are not used yet, this makes no change in behavior. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
df7625d422
commit
a26fdf3934
3 changed files with 67 additions and 3 deletions
|
@ -138,33 +138,92 @@ 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;
|
||||
tcet->mig_nb_table = tcet->nb_table;
|
||||
|
||||
trace_spapr_iommu_pre_save(tcet->liobn, tcet->mig_nb_table,
|
||||
tcet->bus_offset, tcet->page_shift);
|
||||
}
|
||||
|
||||
static int spapr_tce_table_post_load(void *opaque, int version_id)
|
||||
{
|
||||
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque);
|
||||
uint32_t old_nb_table = tcet->nb_table;
|
||||
uint64_t old_bus_offset = tcet->bus_offset;
|
||||
uint32_t old_page_shift = tcet->page_shift;
|
||||
|
||||
if (tcet->vdev) {
|
||||
spapr_vio_set_bypass(tcet->vdev, tcet->bypass);
|
||||
}
|
||||
|
||||
if (tcet->mig_nb_table != tcet->nb_table) {
|
||||
spapr_tce_table_disable(tcet);
|
||||
}
|
||||
|
||||
if (tcet->mig_nb_table) {
|
||||
if (!tcet->nb_table) {
|
||||
spapr_tce_table_enable(tcet, old_page_shift, old_bus_offset,
|
||||
tcet->mig_nb_table);
|
||||
}
|
||||
|
||||
memcpy(tcet->table, tcet->mig_table,
|
||||
tcet->nb_table * sizeof(tcet->table[0]));
|
||||
|
||||
free(tcet->mig_table);
|
||||
tcet->mig_table = NULL;
|
||||
}
|
||||
|
||||
trace_spapr_iommu_post_load(tcet->liobn, old_nb_table, tcet->nb_table,
|
||||
tcet->bus_offset, tcet->page_shift);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool spapr_tce_table_ex_needed(void *opaque)
|
||||
{
|
||||
sPAPRTCETable *tcet = opaque;
|
||||
|
||||
return tcet->bus_offset || tcet->page_shift != 0xC;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_spapr_tce_table_ex = {
|
||||
.name = "spapr_iommu_ex",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = spapr_tce_table_ex_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(bus_offset, sPAPRTCETable),
|
||||
VMSTATE_UINT32(page_shift, sPAPRTCETable),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
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, mig_nb_table, 0,
|
||||
vmstate_info_uint64, uint64_t),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription*[]) {
|
||||
&vmstate_spapr_tce_table_ex,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
static MemoryRegionIOMMUOps spapr_iommu_ops = {
|
||||
|
@ -264,7 +323,7 @@ void spapr_tce_table_enable(sPAPRTCETable *tcet,
|
|||
(uint64_t)tcet->nb_table << tcet->page_shift);
|
||||
}
|
||||
|
||||
static void spapr_tce_table_disable(sPAPRTCETable *tcet)
|
||||
void spapr_tce_table_disable(sPAPRTCETable *tcet)
|
||||
{
|
||||
if (!tcet->nb_table) {
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue