[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 05/26] spapr_iommu: Migrate full state
From: |
David Gibson |
Subject: |
[Qemu-devel] [PULL 05/26] spapr_iommu: Migrate full state |
Date: |
Tue, 7 Jun 2016 20:47:52 +1000 |
From: Alexey Kardashevskiy <address@hidden>
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 <address@hidden>
Signed-off-by: David Gibson <address@hidden>
---
hw/ppc/spapr_iommu.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++---
include/hw/ppc/spapr.h | 3 +++
trace-events | 2 ++
3 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index de63467..28991bc 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -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;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 26c327d..f849714 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -539,6 +539,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;
@@ -565,6 +567,7 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner,
uint32_t liobn);
void spapr_tce_table_enable(sPAPRTCETable *tcet,
uint32_t page_shift, uint64_t bus_offset,
uint32_t nb_table);
+void spapr_tce_table_disable(sPAPRTCETable *tcet);
void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio);
MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet);
diff --git a/trace-events b/trace-events
index c50b870..44a8664 100644
--- a/trace-events
+++ b/trace-events
@@ -1431,6 +1431,8 @@ spapr_iommu_pci_indirect(uint64_t liobn, uint64_t ioba,
uint64_t tce, uint64_t i
spapr_iommu_pci_stuff(uint64_t liobn, uint64_t ioba, uint64_t tce_value,
uint64_t npages, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64"
tcevalue=0x%"PRIx64" npages=%"PRId64" ret=%"PRId64
spapr_iommu_xlate(uint64_t liobn, uint64_t ioba, uint64_t tce, unsigned perm,
unsigned pgsize) "liobn=%"PRIx64" 0x%"PRIx64" -> 0x%"PRIx64" perm=%u mask=%x"
spapr_iommu_new_table(uint64_t liobn, void *table, int fd) "liobn=%"PRIx64"
table=%p fd=%d"
+spapr_iommu_pre_save(uint64_t liobn, uint32_t nb, uint64_t offs, uint32_t ps)
"liobn=%"PRIx64" %"PRIx32" bus_offset=%"PRIx64" ps=%"PRIu32
+spapr_iommu_post_load(uint64_t liobn, uint32_t pre_nb, uint32_t post_nb,
uint64_t offs, uint32_t ps) "liobn=%"PRIx64" %"PRIx32" => %"PRIx32"
bus_offset=%"PRIx64" ps=%"PRIu32
# hw/ppc/ppc.c
ppc_tb_adjust(uint64_t offs1, uint64_t offs2, int64_t diff, int64_t seconds)
"adjusted from 0x%"PRIx64" to 0x%"PRIx64", diff %"PRId64" (%"PRId64"s)"
--
2.5.5
- [Qemu-devel] [PULL 23/26] ppc: Fix mtmsr decoding, (continued)
- [Qemu-devel] [PULL 23/26] ppc: Fix mtmsr decoding, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 14/26] spapr_pci: Drop cannot_instantiate_with_device_add_yet=false, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 12/26] ppc: Fix hreg_store_msr() so that non-HV mode cannot alter MSR:HV, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 04/26] spapr_iommu: Introduce "enabled" state for TCE table, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 06/26] spapr_iommu: Add root memory region, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 20/26] ppc: Batch TLB flushes on 32-bit 6xx/7xx/7xxx in hash mode, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 24/26] ppc: Fix slbia decode, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 25/26] ppc: Add missing slbfee. instruction on ppc64 BookS processors, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 02/26] kvm: API to obtain max supported mem slots, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 19/26] ppc: Fix tlb invalidations on 6xx/7xx/7xxx 32-bit processors, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 05/26] spapr_iommu: Migrate full state,
David Gibson <=
- [Qemu-devel] [PULL 21/26] ppc: POWER7 had ACOP and PID registers, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 07/26] spapr_pci: Reset DMA config on PHB reset, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 10/26] spapr: Introduce pseries-2.7 machine type, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 26/26] ppc: Do not take exceptions on unknown SPRs in privileged mode, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 08/26] spapr_pci: Add and export DMA resetting helper, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 11/26] ppc: Better figure out if processor has HV mode, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 16/26] macio: use DMA memory interface for non-block ATAPI transfers, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 17/26] dbdma: use DMA memory interface for memory accesses, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 13/26] ppc: fix hrfid, tlbia and slbia privilege, David Gibson, 2016/06/07
- [Qemu-devel] [PULL 22/26] ppc: POWER7 has lq/stq instructions and stq need to check ISA, David Gibson, 2016/06/07