diff mbox series

[1/2] intel_iommu: Support IR-only mode without DMA translation

Message ID 20201015183457.1719068-1-dwmw2@infradead.org
State New
Headers show
Series [1/2] intel_iommu: Support IR-only mode without DMA translation | expand

Commit Message

David Woodhouse Oct. 15, 2020, 6:34 p.m. UTC
From: David Woodhouse <dwmw@amazon.co.uk>

By setting none of the SAGAW bits we can indicate to a guest that DMA
translation isn't supported. Tested by booting Windows 10, as well as
Linux guests with the fix at https://git.kernel.org/torvalds/c/c40aaaac10

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
 hw/i386/intel_iommu.c         | 14 ++++++++++----
 include/hw/i386/intel_iommu.h |  1 +
 2 files changed, 11 insertions(+), 4 deletions(-)

Comments

David Woodhouse Jan. 22, 2021, 3:14 p.m. UTC | #1
On Thu, 2020-10-15 at 19:34 +0100, David Woodhouse wrote:
> From: David Woodhouse <dwmw@amazon.co.uk>

> 

> By setting none of the SAGAW bits we can indicate to a guest that DMA

> translation isn't supported. Tested by booting Windows 10, as well as

> Linux guests with the fix at https://git.kernel.org/torvalds/c/c40aaaac10

> 

> Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>


Shall I resend these? They still seem to apply cleanly.

> ---

>  hw/i386/intel_iommu.c         | 14 ++++++++++----

>  include/hw/i386/intel_iommu.h |  1 +

>  2 files changed, 11 insertions(+), 4 deletions(-)

> 

> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c

> index 749eb6ad63..f49b4af931 100644

> --- a/hw/i386/intel_iommu.c

> +++ b/hw/i386/intel_iommu.c

> @@ -2189,7 +2189,7 @@ static void vtd_handle_gcmd_write(IntelIOMMUState *s)

>      uint32_t changed = status ^ val;

>  

>      trace_vtd_reg_write_gcmd(status, val);

> -    if (changed & VTD_GCMD_TE) {

> +    if ((changed & VTD_GCMD_TE) && s->dma_translation) {

>          /* Translation enable/disable */

>          vtd_handle_gcmd_te(s, val & VTD_GCMD_TE);

>      }

> @@ -3086,6 +3086,7 @@ static Property vtd_properties[] = {

>      DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE),

>      DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE),

>      DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),

> +    DEFINE_PROP_BOOL("dma-translation", IntelIOMMUState, dma_translation, true),

>      DEFINE_PROP_END_OF_LIST(),

>  };

>  

> @@ -3607,12 +3608,17 @@ static void vtd_init(IntelIOMMUState *s)

>      s->next_frcd_reg = 0;

>      s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND |

>               VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS |

> -             VTD_CAP_SAGAW_39bit | VTD_CAP_MGAW(s->aw_bits);

> +             VTD_CAP_MGAW(s->aw_bits);

>      if (s->dma_drain) {

>          s->cap |= VTD_CAP_DRAIN;

>      }

> -    if (s->aw_bits == VTD_HOST_AW_48BIT) {

> -        s->cap |= VTD_CAP_SAGAW_48bit;

> +    if (s->dma_translation) {

> +            if (s->aw_bits >= VTD_HOST_AW_39BIT) {

> +                    s->cap |= VTD_CAP_SAGAW_39bit;

> +            }

> +            if (s->aw_bits >= VTD_HOST_AW_48BIT) {

> +                    s->cap |= VTD_CAP_SAGAW_48bit;

> +            }

>      }

>      s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;

>  

> diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h

> index 41783ee46d..42d6a6a636 100644

> --- a/include/hw/i386/intel_iommu.h

> +++ b/include/hw/i386/intel_iommu.h

> @@ -266,6 +266,7 @@ struct IntelIOMMUState {

>      bool buggy_eim;                 /* Force buggy EIM unless eim=off */

>      uint8_t aw_bits;                /* Host/IOVA address width (in bits) */

>      bool dma_drain;                 /* Whether DMA r/w draining enabled */

> +    bool dma_translation;           /* Whether DMA translation supported */

>  

>      /*

>       * Protects IOMMU states in general.  Currently it protects the
diff mbox series

Patch

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 749eb6ad63..f49b4af931 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2189,7 +2189,7 @@  static void vtd_handle_gcmd_write(IntelIOMMUState *s)
     uint32_t changed = status ^ val;
 
     trace_vtd_reg_write_gcmd(status, val);
-    if (changed & VTD_GCMD_TE) {
+    if ((changed & VTD_GCMD_TE) && s->dma_translation) {
         /* Translation enable/disable */
         vtd_handle_gcmd_te(s, val & VTD_GCMD_TE);
     }
@@ -3086,6 +3086,7 @@  static Property vtd_properties[] = {
     DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE),
     DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE),
     DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),
+    DEFINE_PROP_BOOL("dma-translation", IntelIOMMUState, dma_translation, true),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -3607,12 +3608,17 @@  static void vtd_init(IntelIOMMUState *s)
     s->next_frcd_reg = 0;
     s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND |
              VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS |
-             VTD_CAP_SAGAW_39bit | VTD_CAP_MGAW(s->aw_bits);
+             VTD_CAP_MGAW(s->aw_bits);
     if (s->dma_drain) {
         s->cap |= VTD_CAP_DRAIN;
     }
-    if (s->aw_bits == VTD_HOST_AW_48BIT) {
-        s->cap |= VTD_CAP_SAGAW_48bit;
+    if (s->dma_translation) {
+            if (s->aw_bits >= VTD_HOST_AW_39BIT) {
+                    s->cap |= VTD_CAP_SAGAW_39bit;
+            }
+            if (s->aw_bits >= VTD_HOST_AW_48BIT) {
+                    s->cap |= VTD_CAP_SAGAW_48bit;
+            }
     }
     s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;
 
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 41783ee46d..42d6a6a636 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -266,6 +266,7 @@  struct IntelIOMMUState {
     bool buggy_eim;                 /* Force buggy EIM unless eim=off */
     uint8_t aw_bits;                /* Host/IOVA address width (in bits) */
     bool dma_drain;                 /* Whether DMA r/w draining enabled */
+    bool dma_translation;           /* Whether DMA translation supported */
 
     /*
      * Protects IOMMU states in general.  Currently it protects the