From e95b316dd06401fb70ebe07c116045c66d960763 Mon Sep 17 00:00:00 2001 From: Shiqing Gao Date: Wed, 4 Dec 2019 14:44:05 +0800 Subject: [PATCH] hv: vtd: fix improper use of DMAR_GCMD_REG The initialization of "dmar_unit->gcmd" shall be done via reading from Global Status Register rather than Global Command Register. Rationale: According to Chapter 10.4.4 Global Command Register in VT-d spec, Global Command Register is a write-only register to control remapping hardware. Global Status Register is the corresponding read-only register to report remapping hardware status. Tracked-On: #1842 Signed-off-by: Shiqing Gao --- hypervisor/arch/x86/vtd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hypervisor/arch/x86/vtd.c b/hypervisor/arch/x86/vtd.c index 3f8c7ea57..987ba2e8c 100644 --- a/hypervisor/arch/x86/vtd.c +++ b/hypervisor/arch/x86/vtd.c @@ -471,7 +471,15 @@ static int32_t dmar_register_hrhd(struct dmar_drhd_rt *dmar_unit) dmar_unit->cap = iommu_read64(dmar_unit, DMAR_CAP_REG); dmar_unit->ecap = iommu_read64(dmar_unit, DMAR_ECAP_REG); - dmar_unit->gcmd = iommu_read32(dmar_unit, DMAR_GCMD_REG); + + /* + * The initialization of "dmar_unit->gcmd" shall be done via reading from Global Status Register rather than + * Global Command Register. + * According to Chapter 10.4.4 Global Command Register in VT-d spec, Global Command Register is a write-only + * register to control remapping hardware. Global Status Register is the corresponding read-only register to + * report remapping hardware status. + */ + dmar_unit->gcmd = iommu_read32(dmar_unit, DMAR_GSTS_REG); dmar_unit->cap_msagaw = dmar_unit_get_msagw(dmar_unit);