qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH qemu v2] spapr/ddw: Reset DMA when the last non-default windo


From: Daniel Henrique Barboza
Subject: Re: [PATCH qemu v2] spapr/ddw: Reset DMA when the last non-default window is removed
Date: Fri, 24 Jun 2022 09:42:51 -0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.10.0



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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]