mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
IOMMU: also pass p2m_access_t to p2m_get_iommu_flags()
A subsequent change will want to customize the IOMMU permissions based on this. This is part of XSA-378. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Paul Durrant <paul@xen.org>
This commit is contained in:
1 parent
34750a3eb0
commit
d1bb6c97c3
3 files changed
+21
-7
No files matched your search
@@ -808,7 +808,7 @@ ept_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
bool_t entry_written = 0;
|
||||
bool_t need_modify_vtd_table = 1;
|
||||
bool_t vtd_pte_present = 0;
|
||||
unsigned int iommu_flags = p2m_get_iommu_flags(p2mt, mfn);
|
||||
unsigned int iommu_flags = p2m_get_iommu_flags(p2mt, p2ma, mfn);
|
||||
bool_t needs_sync = 1;
|
||||
ept_entry_t old_entry = { .epte = 0 };
|
||||
ept_entry_t new_entry = { .epte = 0 };
|
||||
@@ -938,8 +938,8 @@ ept_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
|
||||
/* Safe to read-then-write because we hold the p2m lock */
|
||||
if ( ept_entry->mfn == new_entry.mfn &&
|
||||
p2m_get_iommu_flags(ept_entry->sa_p2mt, _mfn(ept_entry->mfn)) ==
|
||||
iommu_flags )
|
||||
p2m_get_iommu_flags(ept_entry->sa_p2mt, ept_entry->access,
|
||||
_mfn(ept_entry->mfn)) == iommu_flags )
|
||||
need_modify_vtd_table = 0;
|
||||
|
||||
ept_p2m_type_to_flags(p2m, &new_entry);
|
||||
|
||||
@@ -545,6 +545,16 @@ int p2m_pt_handle_deferred_changes(uint64_t gpa)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Reconstruct a fake p2m_access_t from stored PTE flags. */
|
||||
static p2m_access_t p2m_flags_to_access(unsigned int flags)
|
||||
{
|
||||
if ( flags & _PAGE_PRESENT )
|
||||
return p2m_access_n;
|
||||
|
||||
/* No need to look at _PAGE_NX for now. */
|
||||
return flags & _PAGE_RW ? p2m_access_rw : p2m_access_r;
|
||||
}
|
||||
|
||||
/* Checks only applicable to entries with order > PAGE_ORDER_4K */
|
||||
static void check_entry(mfn_t mfn, p2m_type_t new, p2m_type_t old,
|
||||
unsigned int order)
|
||||
@@ -579,7 +589,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
l2_pgentry_t l2e_content;
|
||||
l3_pgentry_t l3e_content;
|
||||
int rc;
|
||||
unsigned int iommu_pte_flags = p2m_get_iommu_flags(p2mt, mfn);
|
||||
unsigned int iommu_pte_flags = p2m_get_iommu_flags(p2mt, p2ma, mfn);
|
||||
/*
|
||||
* old_mfn and iommu_old_flags control possible flush/update needs on the
|
||||
* IOMMU: We need to flush when MFN or flags (i.e. permissions) change.
|
||||
@@ -642,6 +652,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
old_mfn = l1e_get_pfn(*p2m_entry);
|
||||
iommu_old_flags =
|
||||
p2m_get_iommu_flags(p2m_flags_to_type(flags),
|
||||
p2m_flags_to_access(flags),
|
||||
_mfn(old_mfn));
|
||||
}
|
||||
else
|
||||
@@ -684,9 +695,10 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
0, L1_PAGETABLE_ENTRIES);
|
||||
ASSERT(p2m_entry);
|
||||
old_mfn = l1e_get_pfn(*p2m_entry);
|
||||
flags = l1e_get_flags(*p2m_entry);
|
||||
iommu_old_flags =
|
||||
p2m_get_iommu_flags(p2m_flags_to_type(l1e_get_flags(*p2m_entry)),
|
||||
_mfn(old_mfn));
|
||||
p2m_get_iommu_flags(p2m_flags_to_type(flags),
|
||||
p2m_flags_to_access(flags), _mfn(old_mfn));
|
||||
|
||||
if ( mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt) )
|
||||
entry_content = p2m_l1e_from_pfn(mfn_x(mfn),
|
||||
@@ -714,6 +726,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
old_mfn = l1e_get_pfn(*p2m_entry);
|
||||
iommu_old_flags =
|
||||
p2m_get_iommu_flags(p2m_flags_to_type(flags),
|
||||
p2m_flags_to_access(flags),
|
||||
_mfn(old_mfn));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -891,7 +891,8 @@ static inline void p2m_altp2m_check(struct vcpu *v, uint16_t idx) {}
|
||||
/*
|
||||
* p2m type to IOMMU flags
|
||||
*/
|
||||
static inline unsigned int p2m_get_iommu_flags(p2m_type_t p2mt, mfn_t mfn)
|
||||
static inline unsigned int p2m_get_iommu_flags(p2m_type_t p2mt,
|
||||
p2m_access_t p2ma, mfn_t mfn)
|
||||
{
|
||||
unsigned int flags;
|
||||
|
||||
|
||||