intel_iommu: allow dev-iotlb context entry conditionally
When device-iotlb is not specified, we should fail this check. A new function vtd_ce_type_check() is introduced. While I'm at it, clean up the vtd_dev_to_context_entry() a bit - replace many "else if" usage into direct if check. That'll make the logic more clear. Signed-off-by: Peter Xu <peterx@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
		
							parent
							
								
									5a38cb5940
								
							
						
					
					
						commit
						f80c98740e
					
				| 
						 | 
				
			
			@ -600,6 +600,26 @@ static inline uint32_t vtd_ce_get_type(VTDContextEntry *ce)
 | 
			
		|||
    return ce->lo & VTD_CONTEXT_ENTRY_TT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return true if check passed, otherwise false */
 | 
			
		||||
static inline bool vtd_ce_type_check(X86IOMMUState *x86_iommu,
 | 
			
		||||
                                     VTDContextEntry *ce)
 | 
			
		||||
{
 | 
			
		||||
    switch (vtd_ce_get_type(ce)) {
 | 
			
		||||
    case VTD_CONTEXT_TT_MULTI_LEVEL:
 | 
			
		||||
        /* Always supported */
 | 
			
		||||
        break;
 | 
			
		||||
    case VTD_CONTEXT_TT_DEV_IOTLB:
 | 
			
		||||
        if (!x86_iommu->dt_supported) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        /* Unknwon type */
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint64_t vtd_iova_limit(VTDContextEntry *ce)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ce_agaw = vtd_ce_get_agaw(ce);
 | 
			
		||||
| 
						 | 
				
			
			@ -836,6 +856,7 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,
 | 
			
		|||
{
 | 
			
		||||
    VTDRootEntry re;
 | 
			
		||||
    int ret_fr;
 | 
			
		||||
    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
 | 
			
		||||
 | 
			
		||||
    ret_fr = vtd_get_root_entry(s, bus_num, &re);
 | 
			
		||||
    if (ret_fr) {
 | 
			
		||||
| 
						 | 
				
			
			@ -846,7 +867,9 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,
 | 
			
		|||
        /* Not error - it's okay we don't have root entry. */
 | 
			
		||||
        trace_vtd_re_not_present(bus_num);
 | 
			
		||||
        return -VTD_FR_ROOT_ENTRY_P;
 | 
			
		||||
    } else if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD)) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD)) {
 | 
			
		||||
        trace_vtd_re_invalid(re.rsvd, re.val);
 | 
			
		||||
        return -VTD_FR_ROOT_ENTRY_RSVD;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -860,26 +883,26 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,
 | 
			
		|||
        /* Not error - it's okay we don't have context entry. */
 | 
			
		||||
        trace_vtd_ce_not_present(bus_num, devfn);
 | 
			
		||||
        return -VTD_FR_CONTEXT_ENTRY_P;
 | 
			
		||||
    } else if ((ce->hi & VTD_CONTEXT_ENTRY_RSVD_HI) ||
 | 
			
		||||
               (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO)) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((ce->hi & VTD_CONTEXT_ENTRY_RSVD_HI) ||
 | 
			
		||||
        (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO)) {
 | 
			
		||||
        trace_vtd_ce_invalid(ce->hi, ce->lo);
 | 
			
		||||
        return -VTD_FR_CONTEXT_ENTRY_RSVD;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Check if the programming of context-entry is valid */
 | 
			
		||||
    if (!vtd_is_level_supported(s, vtd_ce_get_level(ce))) {
 | 
			
		||||
        trace_vtd_ce_invalid(ce->hi, ce->lo);
 | 
			
		||||
        return -VTD_FR_CONTEXT_ENTRY_INV;
 | 
			
		||||
    } else {
 | 
			
		||||
        switch (vtd_ce_get_type(ce)) {
 | 
			
		||||
        case VTD_CONTEXT_TT_MULTI_LEVEL:
 | 
			
		||||
            /* fall through */
 | 
			
		||||
        case VTD_CONTEXT_TT_DEV_IOTLB:
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            trace_vtd_ce_invalid(ce->hi, ce->lo);
 | 
			
		||||
            return -VTD_FR_CONTEXT_ENTRY_INV;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Do translation type check */
 | 
			
		||||
    if (!vtd_ce_type_check(x86_iommu, ce)) {
 | 
			
		||||
        trace_vtd_ce_invalid(ce->hi, ce->lo);
 | 
			
		||||
        return -VTD_FR_CONTEXT_ENTRY_INV;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue