diff mbox series

[qemu,v2] spapr/ddw: Reset DMA when the last non-default window is removed

Message ID 20220622052955.1069903-1-aik@ozlabs.ru
State New
Headers show
Series [qemu,v2] spapr/ddw: Reset DMA when the last non-default window is removed | expand

Commit Message

Alexey Kardashevskiy June 22, 2022, 5:29 a.m. UTC
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>
---
Changes:
v2:
* reverted changes to spapr_tce_table_enable()
---
 include/hw/ppc/spapr.h  |  1 +
 hw/ppc/spapr_iommu.c    |  3 ++-
 hw/ppc/spapr_pci.c      |  1 +
 hw/ppc/spapr_rtas_ddw.c | 15 +++++++++++++++
 4 files changed, 19 insertions(+), 1 deletion(-)

Comments

Daniel Henrique Barboza June 24, 2022, 12:42 p.m. UTC | #1
On 6/22/22 02:29, Alexey Kardashevskiy wrote:
> 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>

> Changes:
> v2:
> * reverted changes to spapr_tce_table_enable()
> ---
>   include/hw/ppc/spapr.h  |  1 +
>   hw/ppc/spapr_iommu.c    |  3 ++-
>   hw/ppc/spapr_pci.c      |  1 +
>   hw/ppc/spapr_rtas_ddw.c | 15 +++++++++++++++
>   4 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 072dda2c7265..4ba2b27b8c4f 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -902,6 +902,7 @@ struct SpaprTceTable {
>       bool bypass;
>       bool need_vfio;
>       bool skipping_replay;
> +    bool def_win;
>       int fd;
>       MemoryRegion root;
>       IOMMUMemoryRegion iommu;
> diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
> index 81e5a1aea3a6..63e34d457a0e 100644
> --- a/hw/ppc/spapr_iommu.c
> +++ b/hw/ppc/spapr_iommu.c
> @@ -279,7 +279,7 @@ static const VMStateDescription vmstate_spapr_tce_table_ex = {
>   
>   static const VMStateDescription vmstate_spapr_tce_table = {
>       .name = "spapr_iommu",
> -    .version_id = 2,
> +    .version_id = 3,
>       .minimum_version_id = 2,
>       .pre_save = spapr_tce_table_pre_save,
>       .post_load = spapr_tce_table_post_load,
> @@ -292,6 +292,7 @@ static const VMStateDescription vmstate_spapr_tce_table = {
>           VMSTATE_BOOL(bypass, SpaprTceTable),
>           VMSTATE_VARRAY_UINT32_ALLOC(mig_table, SpaprTceTable, mig_nb_table, 0,
>                                       vmstate_info_uint64, uint64_t),
> +        VMSTATE_BOOL_V(def_win, SpaprTceTable, 3),
>   
>           VMSTATE_END_OF_LIST()
>       },
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index b2f5fbef0c83..5e95d7940fc8 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -2067,6 +2067,7 @@ void spapr_phb_dma_reset(SpaprPhbState *sphb)
>       tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[0]);
>       spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr,
>                              sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT);
> +    tcet->def_win = true;
>   }
>   
>   static void spapr_phb_reset(DeviceState *qdev)
> diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c
> index 13d339c807c1..bb7d91b6d1af 100644
> --- a/hw/ppc/spapr_rtas_ddw.c
> +++ b/hw/ppc/spapr_rtas_ddw.c
> @@ -215,6 +215,7 @@ static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
>       SpaprPhbState *sphb;
>       SpaprTceTable *tcet;
>       uint32_t liobn;
> +    bool def_win_removed;
>   
>       if ((nargs != 1) || (nret != 1)) {
>           goto param_error_exit;
> @@ -231,9 +232,23 @@ static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
>           goto param_error_exit;
>       }
>   
> +    def_win_removed = tcet->def_win;
>       spapr_tce_table_disable(tcet);
>       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);
>       return;
>
Daniel Henrique Barboza June 27, 2022, 9:41 p.m. UTC | #2
Queued in gitlab.com/danielhb/qemu/tree/ppc-next. Thanks,


Daniel

On 6/22/22 02:29, Alexey Kardashevskiy wrote:
> 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>
> ---
> Changes:
> v2:
> * reverted changes to spapr_tce_table_enable()
> ---
>   include/hw/ppc/spapr.h  |  1 +
>   hw/ppc/spapr_iommu.c    |  3 ++-
>   hw/ppc/spapr_pci.c      |  1 +
>   hw/ppc/spapr_rtas_ddw.c | 15 +++++++++++++++
>   4 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 072dda2c7265..4ba2b27b8c4f 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -902,6 +902,7 @@ struct SpaprTceTable {
>       bool bypass;
>       bool need_vfio;
>       bool skipping_replay;
> +    bool def_win;
>       int fd;
>       MemoryRegion root;
>       IOMMUMemoryRegion iommu;
> diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
> index 81e5a1aea3a6..63e34d457a0e 100644
> --- a/hw/ppc/spapr_iommu.c
> +++ b/hw/ppc/spapr_iommu.c
> @@ -279,7 +279,7 @@ static const VMStateDescription vmstate_spapr_tce_table_ex = {
>   
>   static const VMStateDescription vmstate_spapr_tce_table = {
>       .name = "spapr_iommu",
> -    .version_id = 2,
> +    .version_id = 3,
>       .minimum_version_id = 2,
>       .pre_save = spapr_tce_table_pre_save,
>       .post_load = spapr_tce_table_post_load,
> @@ -292,6 +292,7 @@ static const VMStateDescription vmstate_spapr_tce_table = {
>           VMSTATE_BOOL(bypass, SpaprTceTable),
>           VMSTATE_VARRAY_UINT32_ALLOC(mig_table, SpaprTceTable, mig_nb_table, 0,
>                                       vmstate_info_uint64, uint64_t),
> +        VMSTATE_BOOL_V(def_win, SpaprTceTable, 3),
>   
>           VMSTATE_END_OF_LIST()
>       },
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index b2f5fbef0c83..5e95d7940fc8 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -2067,6 +2067,7 @@ void spapr_phb_dma_reset(SpaprPhbState *sphb)
>       tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[0]);
>       spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr,
>                              sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT);
> +    tcet->def_win = true;
>   }
>   
>   static void spapr_phb_reset(DeviceState *qdev)
> diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c
> index 13d339c807c1..bb7d91b6d1af 100644
> --- a/hw/ppc/spapr_rtas_ddw.c
> +++ b/hw/ppc/spapr_rtas_ddw.c
> @@ -215,6 +215,7 @@ static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
>       SpaprPhbState *sphb;
>       SpaprTceTable *tcet;
>       uint32_t liobn;
> +    bool def_win_removed;
>   
>       if ((nargs != 1) || (nret != 1)) {
>           goto param_error_exit;
> @@ -231,9 +232,23 @@ static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
>           goto param_error_exit;
>       }
>   
> +    def_win_removed = tcet->def_win;
>       spapr_tce_table_disable(tcet);
>       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);
>       return;
>
diff mbox series

Patch

diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 072dda2c7265..4ba2b27b8c4f 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -902,6 +902,7 @@  struct SpaprTceTable {
     bool bypass;
     bool need_vfio;
     bool skipping_replay;
+    bool def_win;
     int fd;
     MemoryRegion root;
     IOMMUMemoryRegion iommu;
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 81e5a1aea3a6..63e34d457a0e 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -279,7 +279,7 @@  static const VMStateDescription vmstate_spapr_tce_table_ex = {
 
 static const VMStateDescription vmstate_spapr_tce_table = {
     .name = "spapr_iommu",
-    .version_id = 2,
+    .version_id = 3,
     .minimum_version_id = 2,
     .pre_save = spapr_tce_table_pre_save,
     .post_load = spapr_tce_table_post_load,
@@ -292,6 +292,7 @@  static const VMStateDescription vmstate_spapr_tce_table = {
         VMSTATE_BOOL(bypass, SpaprTceTable),
         VMSTATE_VARRAY_UINT32_ALLOC(mig_table, SpaprTceTable, mig_nb_table, 0,
                                     vmstate_info_uint64, uint64_t),
+        VMSTATE_BOOL_V(def_win, SpaprTceTable, 3),
 
         VMSTATE_END_OF_LIST()
     },
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index b2f5fbef0c83..5e95d7940fc8 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -2067,6 +2067,7 @@  void spapr_phb_dma_reset(SpaprPhbState *sphb)
     tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[0]);
     spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr,
                            sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT);
+    tcet->def_win = true;
 }
 
 static void spapr_phb_reset(DeviceState *qdev)
diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c
index 13d339c807c1..bb7d91b6d1af 100644
--- a/hw/ppc/spapr_rtas_ddw.c
+++ b/hw/ppc/spapr_rtas_ddw.c
@@ -215,6 +215,7 @@  static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
     SpaprPhbState *sphb;
     SpaprTceTable *tcet;
     uint32_t liobn;
+    bool def_win_removed;
 
     if ((nargs != 1) || (nret != 1)) {
         goto param_error_exit;
@@ -231,9 +232,23 @@  static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
         goto param_error_exit;
     }
 
+    def_win_removed = tcet->def_win;
     spapr_tce_table_disable(tcet);
     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);
     return;