spapr/ddw: Reset DMA when the last non-default window is removed
PAPR+/LoPAPR says: === The platform must restore the default DMA window for the PE on a call to the ibm,remove-pe-dma-window RTAS call when all of the following are true: a. The call removes the last DMA window remaining for the PE. b. The DMA window being removed is not the default window === This resets DMA as PAPR mandates. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> Message-Id: <20220622052955.1069903-1-aik@ozlabs.ru> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
parent
59f11543e2
commit
31cc81f728
@ -279,7 +279,7 @@ static const VMStateDescription vmstate_spapr_tce_table_ex = {
|
|||||||
|
|
||||||
static const VMStateDescription vmstate_spapr_tce_table = {
|
static const VMStateDescription vmstate_spapr_tce_table = {
|
||||||
.name = "spapr_iommu",
|
.name = "spapr_iommu",
|
||||||
.version_id = 2,
|
.version_id = 3,
|
||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.pre_save = spapr_tce_table_pre_save,
|
.pre_save = spapr_tce_table_pre_save,
|
||||||
.post_load = spapr_tce_table_post_load,
|
.post_load = spapr_tce_table_post_load,
|
||||||
@ -292,6 +292,7 @@ static const VMStateDescription vmstate_spapr_tce_table = {
|
|||||||
VMSTATE_BOOL(bypass, SpaprTceTable),
|
VMSTATE_BOOL(bypass, SpaprTceTable),
|
||||||
VMSTATE_VARRAY_UINT32_ALLOC(mig_table, SpaprTceTable, mig_nb_table, 0,
|
VMSTATE_VARRAY_UINT32_ALLOC(mig_table, SpaprTceTable, mig_nb_table, 0,
|
||||||
vmstate_info_uint64, uint64_t),
|
vmstate_info_uint64, uint64_t),
|
||||||
|
VMSTATE_BOOL_V(def_win, SpaprTceTable, 3),
|
||||||
|
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
},
|
},
|
||||||
|
@ -2067,6 +2067,7 @@ void spapr_phb_dma_reset(SpaprPhbState *sphb)
|
|||||||
tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[0]);
|
tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[0]);
|
||||||
spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr,
|
spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr,
|
||||||
sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT);
|
sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT);
|
||||||
|
tcet->def_win = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spapr_phb_reset(DeviceState *qdev)
|
static void spapr_phb_reset(DeviceState *qdev)
|
||||||
|
@ -215,6 +215,7 @@ static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
|
|||||||
SpaprPhbState *sphb;
|
SpaprPhbState *sphb;
|
||||||
SpaprTceTable *tcet;
|
SpaprTceTable *tcet;
|
||||||
uint32_t liobn;
|
uint32_t liobn;
|
||||||
|
bool def_win_removed;
|
||||||
|
|
||||||
if ((nargs != 1) || (nret != 1)) {
|
if ((nargs != 1) || (nret != 1)) {
|
||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
@ -231,9 +232,23 @@ static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
|
|||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def_win_removed = tcet->def_win;
|
||||||
spapr_tce_table_disable(tcet);
|
spapr_tce_table_disable(tcet);
|
||||||
trace_spapr_iommu_ddw_remove(liobn);
|
trace_spapr_iommu_ddw_remove(liobn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PAPR+/LoPAPR says:
|
||||||
|
* The platform must restore the default DMA window for the PE on a call
|
||||||
|
* to the ibm,remove-pe-dma-window RTAS call when all of the following
|
||||||
|
* are true:
|
||||||
|
* a. The call removes the last DMA window remaining for the PE.
|
||||||
|
* b. The DMA window being removed is not the default window
|
||||||
|
*/
|
||||||
|
if (spapr_phb_get_active_win_num(sphb) == 0 && !def_win_removed) {
|
||||||
|
spapr_phb_dma_reset(sphb);
|
||||||
|
trace_spapr_iommu_ddw_reset(sphb->buid, 0);
|
||||||
|
}
|
||||||
|
|
||||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -902,6 +902,7 @@ struct SpaprTceTable {
|
|||||||
bool bypass;
|
bool bypass;
|
||||||
bool need_vfio;
|
bool need_vfio;
|
||||||
bool skipping_replay;
|
bool skipping_replay;
|
||||||
|
bool def_win;
|
||||||
int fd;
|
int fd;
|
||||||
MemoryRegion root;
|
MemoryRegion root;
|
||||||
IOMMUMemoryRegion iommu;
|
IOMMUMemoryRegion iommu;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user