summaryrefslogtreecommitdiffstats
path: root/hw/i386
diff options
context:
space:
mode:
authorDavid Woodhouse2022-03-14 15:25:42 +0100
committerMichael S. Tsirkin2022-05-16 10:38:39 +0200
commit8646d9c773d88c3f9a20919a96afa35e6230c1ee (patch)
tree7e9883f6dc99ebfe2cccd9cde44778dd16954c65 /hw/i386
parenttarget/i386: Fix sanity check on max APIC ID / X2APIC enablement (diff)
downloadqemu-8646d9c773d88c3f9a20919a96afa35e6230c1ee.tar.gz
qemu-8646d9c773d88c3f9a20919a96afa35e6230c1ee.tar.xz
qemu-8646d9c773d88c3f9a20919a96afa35e6230c1ee.zip
intel_iommu: Support IR-only mode without DMA translation
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> Reviewed-by: Peter Xu <peterx@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com> Message-Id: <20220314142544.150555-2-dwmw2@infradead.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386')
-rw-r--r--hw/i386/intel_iommu.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index e05d69a2c0..b22376a45d 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2214,7 +2214,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);
}
@@ -3122,6 +3122,7 @@ static Property vtd_properties[] = {
DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE),
DEFINE_PROP_BOOL("snoop-control", IntelIOMMUState, snoop_control, false),
DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),
+ DEFINE_PROP_BOOL("dma-translation", IntelIOMMUState, dma_translation, true),
DEFINE_PROP_END_OF_LIST(),
};
@@ -3627,12 +3628,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;