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);
}
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(),
};
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;