|
@@ -796,7 +796,7 @@ static int vtd_get_pdire_from_pdir_table(dma_addr_t pasid_dir_base,
|
|
|
addr = pasid_dir_base + index * entry_size;
|
|
|
if (dma_memory_read(&address_space_memory, addr,
|
|
|
pdire, entry_size, MEMTXATTRS_UNSPECIFIED)) {
|
|
|
- return -VTD_FR_PASID_TABLE_INV;
|
|
|
+ return -VTD_FR_PASID_DIR_ACCESS_ERR;
|
|
|
}
|
|
|
|
|
|
pdire->val = le64_to_cpu(pdire->val);
|
|
@@ -814,6 +814,7 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s,
|
|
|
dma_addr_t addr,
|
|
|
VTDPASIDEntry *pe)
|
|
|
{
|
|
|
+ uint8_t pgtt;
|
|
|
uint32_t index;
|
|
|
dma_addr_t entry_size;
|
|
|
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
|
|
@@ -823,7 +824,7 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s,
|
|
|
addr = addr + index * entry_size;
|
|
|
if (dma_memory_read(&address_space_memory, addr,
|
|
|
pe, entry_size, MEMTXATTRS_UNSPECIFIED)) {
|
|
|
- return -VTD_FR_PASID_TABLE_INV;
|
|
|
+ return -VTD_FR_PASID_TABLE_ACCESS_ERR;
|
|
|
}
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(pe->val); i++) {
|
|
|
pe->val[i] = le64_to_cpu(pe->val[i]);
|
|
@@ -831,11 +832,13 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s,
|
|
|
|
|
|
/* Do translation type check */
|
|
|
if (!vtd_pe_type_check(x86_iommu, pe)) {
|
|
|
- return -VTD_FR_PASID_TABLE_INV;
|
|
|
+ return -VTD_FR_PASID_TABLE_ENTRY_INV;
|
|
|
}
|
|
|
|
|
|
- if (!vtd_is_level_supported(s, VTD_PE_GET_LEVEL(pe))) {
|
|
|
- return -VTD_FR_PASID_TABLE_INV;
|
|
|
+ pgtt = VTD_PE_GET_TYPE(pe);
|
|
|
+ if (pgtt == VTD_SM_PASID_ENTRY_SLT &&
|
|
|
+ !vtd_is_level_supported(s, VTD_PE_GET_LEVEL(pe))) {
|
|
|
+ return -VTD_FR_PASID_TABLE_ENTRY_INV;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -876,7 +879,7 @@ static int vtd_get_pe_from_pasid_table(IntelIOMMUState *s,
|
|
|
}
|
|
|
|
|
|
if (!vtd_pdire_present(&pdire)) {
|
|
|
- return -VTD_FR_PASID_TABLE_INV;
|
|
|
+ return -VTD_FR_PASID_DIR_ENTRY_P;
|
|
|
}
|
|
|
|
|
|
ret = vtd_get_pe_from_pdire(s, pasid, &pdire, pe);
|
|
@@ -885,7 +888,7 @@ static int vtd_get_pe_from_pasid_table(IntelIOMMUState *s,
|
|
|
}
|
|
|
|
|
|
if (!vtd_pe_present(pe)) {
|
|
|
- return -VTD_FR_PASID_TABLE_INV;
|
|
|
+ return -VTD_FR_PASID_ENTRY_P;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -938,7 +941,7 @@ static int vtd_ce_get_pasid_fpd(IntelIOMMUState *s,
|
|
|
}
|
|
|
|
|
|
if (!vtd_pdire_present(&pdire)) {
|
|
|
- return -VTD_FR_PASID_TABLE_INV;
|
|
|
+ return -VTD_FR_PASID_DIR_ENTRY_P;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1795,7 +1798,11 @@ static const bool vtd_qualified_faults[] = {
|
|
|
[VTD_FR_ROOT_ENTRY_RSVD] = false,
|
|
|
[VTD_FR_PAGING_ENTRY_RSVD] = true,
|
|
|
[VTD_FR_CONTEXT_ENTRY_TT] = true,
|
|
|
- [VTD_FR_PASID_TABLE_INV] = false,
|
|
|
+ [VTD_FR_PASID_DIR_ACCESS_ERR] = false,
|
|
|
+ [VTD_FR_PASID_DIR_ENTRY_P] = true,
|
|
|
+ [VTD_FR_PASID_TABLE_ACCESS_ERR] = false,
|
|
|
+ [VTD_FR_PASID_ENTRY_P] = true,
|
|
|
+ [VTD_FR_PASID_TABLE_ENTRY_INV] = true,
|
|
|
[VTD_FR_SM_INTERRUPT_ADDR] = true,
|
|
|
[VTD_FR_MAX] = false,
|
|
|
};
|