Skip to content

Commit 26e013b

Browse files
author
Marc Zyngier
committed
Merge branch kvm-arm64/fwb-for-all into kvmarm-master/next
* kvm-arm64/fwb-for-all: : . : Allow pKVM's host stage-2 mappings to use the Force Write Back version : of the memory attributes by using the "pass-through' encoding. : : This avoids having two separate encodings for S2 on a given platform. : . KVM: arm64: Simplify PAGE_S2_MEMATTR KVM: arm64: Kill KVM_PGTABLE_S2_NOFWB KVM: arm64: Switch pKVM host S2 over to KVM_PGTABLE_S2_AS_S1 KVM: arm64: Add KVM_PGTABLE_S2_AS_S1 flag arm64: Add MT_S2{,_FWB}_AS_S1 encodings Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents 183ac2b + 65d00e3 commit 26e013b

5 files changed

Lines changed: 30 additions & 22 deletions

File tree

arch/arm64/include/asm/kvm_pgtable.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,12 @@ struct kvm_pgtable_mm_ops {
231231

232232
/**
233233
* enum kvm_pgtable_stage2_flags - Stage-2 page-table flags.
234-
* @KVM_PGTABLE_S2_NOFWB: Don't enforce Normal-WB even if the CPUs have
235-
* ARM64_HAS_STAGE2_FWB.
236234
* @KVM_PGTABLE_S2_IDMAP: Only use identity mappings.
235+
* @KVM_PGTABLE_S2_AS_S1: Final memory attributes are that of Stage-1.
237236
*/
238237
enum kvm_pgtable_stage2_flags {
239-
KVM_PGTABLE_S2_NOFWB = BIT(0),
240-
KVM_PGTABLE_S2_IDMAP = BIT(1),
238+
KVM_PGTABLE_S2_IDMAP = BIT(0),
239+
KVM_PGTABLE_S2_AS_S1 = BIT(1),
241240
};
242241

243242
/**

arch/arm64/include/asm/memory.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,19 +175,24 @@
175175
#define MT_DEVICE_nGnRE 4
176176

177177
/*
178-
* Memory types for Stage-2 translation
178+
* Memory types for Stage-2 translation when HCR_EL2.FWB=0. See R_HMNDG,
179+
* R_TNHFM, R_GQFSF and I_MCQKW for the details on how these attributes get
180+
* combined with Stage-1.
179181
*/
180182
#define MT_S2_NORMAL 0xf
181183
#define MT_S2_NORMAL_NC 0x5
182184
#define MT_S2_DEVICE_nGnRE 0x1
185+
#define MT_S2_AS_S1 MT_S2_NORMAL
183186

184187
/*
185-
* Memory types for Stage-2 translation when ID_AA64MMFR2_EL1.FWB is 0001
186-
* Stage-2 enforces Normal-WB and Device-nGnRE
188+
* Memory types for Stage-2 translation when HCR_EL2.FWB=1. Stage-2 enforces
189+
* Normal-WB and Device-nGnRE, unless we actively say that S1 wins. See
190+
* R_VRJSW and R_RHWZM for details.
187191
*/
188192
#define MT_S2_FWB_NORMAL 6
189193
#define MT_S2_FWB_NORMAL_NC 5
190194
#define MT_S2_FWB_DEVICE_nGnRE 1
195+
#define MT_S2_FWB_AS_S1 7
191196

192197
#ifdef CONFIG_ARM64_4K_PAGES
193198
#define IOREMAP_MAX_ORDER (PUD_SHIFT)

arch/arm64/include/asm/pgtable-prot.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,10 @@ static inline bool __pure lpa2_is_enabled(void)
109109
#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
110110
#define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_KERNEL_EXEC_CONT)
111111

112-
#define PAGE_S2_MEMATTR(attr, has_fwb) \
112+
#define PAGE_S2_MEMATTR(attr) \
113113
({ \
114114
u64 __val; \
115-
if (has_fwb) \
115+
if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB)) \
116116
__val = PTE_S2_MEMATTR(MT_S2_FWB_ ## attr); \
117117
else \
118118
__val = PTE_S2_MEMATTR(MT_S2_ ## attr); \

arch/arm64/kvm/hyp/nvhe/mem_protect.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <nvhe/mem_protect.h>
2020
#include <nvhe/mm.h>
2121

22-
#define KVM_HOST_S2_FLAGS (KVM_PGTABLE_S2_NOFWB | KVM_PGTABLE_S2_IDMAP)
22+
#define KVM_HOST_S2_FLAGS (KVM_PGTABLE_S2_AS_S1 | KVM_PGTABLE_S2_IDMAP)
2323

2424
struct host_mmu host_mmu;
2525

@@ -324,6 +324,8 @@ int __pkvm_prot_finalize(void)
324324
params->vttbr = kvm_get_vttbr(mmu);
325325
params->vtcr = mmu->vtcr;
326326
params->hcr_el2 |= HCR_VM;
327+
if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
328+
params->hcr_el2 |= HCR_FWB;
327329

328330
/*
329331
* The CMO below not only cleans the updated params to the

arch/arm64/kvm/hyp/pgtable.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -647,14 +647,6 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
647647
return vtcr;
648648
}
649649

650-
static bool stage2_has_fwb(struct kvm_pgtable *pgt)
651-
{
652-
if (!cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
653-
return false;
654-
655-
return !(pgt->flags & KVM_PGTABLE_S2_NOFWB);
656-
}
657-
658650
void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
659651
phys_addr_t addr, size_t size)
660652
{
@@ -675,7 +667,17 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
675667
}
676668
}
677669

678-
#define KVM_S2_MEMATTR(pgt, attr) PAGE_S2_MEMATTR(attr, stage2_has_fwb(pgt))
670+
#define KVM_S2_MEMATTR(pgt, attr) \
671+
({ \
672+
kvm_pte_t __attr; \
673+
\
674+
if ((pgt)->flags & KVM_PGTABLE_S2_AS_S1) \
675+
__attr = PAGE_S2_MEMATTR(AS_S1); \
676+
else \
677+
__attr = PAGE_S2_MEMATTR(attr); \
678+
\
679+
__attr; \
680+
})
679681

680682
static int stage2_set_xn_attr(enum kvm_pgtable_prot prot, kvm_pte_t *attr)
681683
{
@@ -884,7 +886,7 @@ static bool stage2_unmap_defer_tlb_flush(struct kvm_pgtable *pgt)
884886
* system supporting FWB as the optimization is entirely
885887
* pointless when the unmap walker needs to perform CMOs.
886888
*/
887-
return system_supports_tlb_range() && stage2_has_fwb(pgt);
889+
return system_supports_tlb_range() && cpus_have_final_cap(ARM64_HAS_STAGE2_FWB);
888890
}
889891

890892
static void stage2_unmap_put_pte(const struct kvm_pgtable_visit_ctx *ctx,
@@ -1164,7 +1166,7 @@ static int stage2_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,
11641166
if (mm_ops->page_count(childp) != 1)
11651167
return 0;
11661168
} else if (stage2_pte_cacheable(pgt, ctx->old)) {
1167-
need_flush = !stage2_has_fwb(pgt);
1169+
need_flush = !cpus_have_final_cap(ARM64_HAS_STAGE2_FWB);
11681170
}
11691171

11701172
/*
@@ -1395,7 +1397,7 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
13951397
.arg = pgt,
13961398
};
13971399

1398-
if (stage2_has_fwb(pgt))
1400+
if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
13991401
return 0;
14001402

14011403
return kvm_pgtable_walk(pgt, addr, size, &walker);

0 commit comments

Comments
 (0)