diff options
author | Laurentiu Tudor <laurentiu.tudor@nxp.com> | 2016-07-26 15:43:43 +0300 |
---|---|---|
committer | Dong Aisheng <aisheng.dong@nxp.com> | 2021-11-02 16:57:49 +0800 |
commit | 3f399019810155070acd34b073432f1c03515100 (patch) | |
tree | 933d29a12756d29423976725c677f53c3b79b87d /arch/arm64/kvm/hyp | |
parent | fcc052a740b800c8d799f62e78a94bfb18208d57 (diff) |
arm64: KVM: support flushing device memory
In the current implementation, trying to flush
memory not covered by the linear map (e.g. device memory) causes
a crash.
The QMAN region, even though it is a device region, it's cacheable.
However, as we map the qman region with the same attributes as
the guest, there is no need for cache flush. Use some reserved
bits (reserved for software use) from the descriptor to mark this
type of memory.
This allows dropping the special checks for qman
cacheable region when doing cache flushes.
Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
[rebased on upstream changes in KVM memory management -
using generic page table API + hyp memory isolation]
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
Diffstat (limited to 'arch/arm64/kvm/hyp')
-rw-r--r-- | arch/arm64/kvm/hyp/pgtable.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index f8ceebe4982e..43793c746ab8 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -46,6 +46,8 @@ KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \ KVM_PTE_LEAF_ATTR_HI_S2_XN) +#define KVM_PTE_LEAF_ATTR_S2_DEVICE BIT(55) + #define KVM_INVALID_PTE_OWNER_MASK GENMASK(9, 2) #define KVM_MAX_OWNER_ID 1 @@ -686,7 +688,8 @@ static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, } /* Perform CMOs before installation of the guest stage-2 PTE */ - if (mm_ops->dcache_clean_inval_poc && stage2_pte_cacheable(pgt, new)) + if (mm_ops->dcache_clean_inval_poc && stage2_pte_cacheable(pgt, new) && + !(new & KVM_PTE_LEAF_ATTR_S2_DEVICE)) mm_ops->dcache_clean_inval_poc(kvm_pte_follow(new, mm_ops), granule); @@ -1091,7 +1094,8 @@ static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, kvm_pte_t pte = *ptep; kvm_pte_t *pte_follow; - if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte)) + if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte) || + (pte & KVM_PTE_LEAF_ATTR_S2_DEVICE)) return 0; pte_follow = kvm_pte_follow(pte, mm_ops); |