Skip to content

Commit 5834816

Browse files
committed
Merge tag 'kvmarm-fixes-6.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 fixes for 6.1, take #1 - Fix for stage-2 invalidation holding the VM MMU lock for too long by limiting the walk to the largest block mapping size - Enable stack protection and branch profiling for VHE - Two selftest fixes
2 parents 9abf231 + 05c2224 commit 5834816

File tree

7 files changed

+28
-33
lines changed

7 files changed

+28
-33
lines changed

arch/arm64/include/asm/kvm_pgtable.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313

1414
#define KVM_PGTABLE_MAX_LEVELS 4U
1515

16+
/*
17+
* The largest supported block sizes for KVM (no 52-bit PA support):
18+
* - 4K (level 1): 1GB
19+
* - 16K (level 2): 32MB
20+
* - 64K (level 2): 512MB
21+
*/
22+
#ifdef CONFIG_ARM64_4K_PAGES
23+
#define KVM_PGTABLE_MIN_BLOCK_LEVEL 1U
24+
#else
25+
#define KVM_PGTABLE_MIN_BLOCK_LEVEL 2U
26+
#endif
27+
1628
static inline u64 kvm_get_parange(u64 mmfr0)
1729
{
1830
u64 parange = cpuid_feature_extract_unsigned_field(mmfr0,
@@ -58,11 +70,7 @@ static inline u64 kvm_granule_size(u32 level)
5870

5971
static inline bool kvm_level_supports_block_mapping(u32 level)
6072
{
61-
/*
62-
* Reject invalid block mappings and don't bother with 4TB mappings for
63-
* 52-bit PAs.
64-
*/
65-
return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
73+
return level >= KVM_PGTABLE_MIN_BLOCK_LEVEL;
6674
}
6775

6876
/**

arch/arm64/include/asm/stage2_pgtable.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010

1111
#include <linux/pgtable.h>
1212

13-
/*
14-
* PGDIR_SHIFT determines the size a top-level page table entry can map
15-
* and depends on the number of levels in the page table. Compute the
16-
* PGDIR_SHIFT for a given number of levels.
17-
*/
18-
#define pt_levels_pgdir_shift(lvls) ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - (lvls))
19-
2013
/*
2114
* The hardware supports concatenation of up to 16 tables at stage2 entry
2215
* level and we use the feature whenever possible, which means we resolve 4
@@ -30,24 +23,11 @@
3023
#define stage2_pgtable_levels(ipa) ARM64_HW_PGTABLE_LEVELS((ipa) - 4)
3124
#define kvm_stage2_levels(kvm) VTCR_EL2_LVLS(kvm->arch.vtcr)
3225

33-
/* stage2_pgdir_shift() is the size mapped by top-level stage2 entry for the VM */
34-
#define stage2_pgdir_shift(kvm) pt_levels_pgdir_shift(kvm_stage2_levels(kvm))
35-
#define stage2_pgdir_size(kvm) (1ULL << stage2_pgdir_shift(kvm))
36-
#define stage2_pgdir_mask(kvm) ~(stage2_pgdir_size(kvm) - 1)
37-
3826
/*
3927
* kvm_mmmu_cache_min_pages() is the number of pages required to install
4028
* a stage-2 translation. We pre-allocate the entry level page table at
4129
* the VM creation.
4230
*/
4331
#define kvm_mmu_cache_min_pages(kvm) (kvm_stage2_levels(kvm) - 1)
4432

45-
static inline phys_addr_t
46-
stage2_pgd_addr_end(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
47-
{
48-
phys_addr_t boundary = (addr + stage2_pgdir_size(kvm)) & stage2_pgdir_mask(kvm);
49-
50-
return (boundary - 1 < end - 1) ? boundary : end;
51-
}
52-
5333
#endif /* __ARM64_S2_PGTABLE_H_ */

arch/arm64/kvm/hyp/Makefile

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55

66
incdir := $(srctree)/$(src)/include
77
subdir-asflags-y := -I$(incdir)
8-
subdir-ccflags-y := -I$(incdir) \
9-
-fno-stack-protector \
10-
-DDISABLE_BRANCH_PROFILING \
11-
$(DISABLE_STACKLEAK_PLUGIN)
8+
subdir-ccflags-y := -I$(incdir)
129

1310
obj-$(CONFIG_KVM) += vhe/ nvhe/ pgtable.o

arch/arm64/kvm/hyp/nvhe/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ asflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
1010
# will explode instantly (Words of Marc Zyngier). So introduce a generic flag
1111
# __DISABLE_TRACE_MMIO__ to disable MMIO tracing for nVHE KVM.
1212
ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS -D__DISABLE_TRACE_MMIO__
13+
ccflags-y += -fno-stack-protector \
14+
-DDISABLE_BRANCH_PROFILING \
15+
$(DISABLE_STACKLEAK_PLUGIN)
1316

1417
hostprogs := gen-hyprel
1518
HOST_EXTRACFLAGS += -I$(objtree)/include

arch/arm64/kvm/mmu.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ static phys_addr_t hyp_idmap_vector;
3131

3232
static unsigned long io_map_base;
3333

34+
static phys_addr_t stage2_range_addr_end(phys_addr_t addr, phys_addr_t end)
35+
{
36+
phys_addr_t size = kvm_granule_size(KVM_PGTABLE_MIN_BLOCK_LEVEL);
37+
phys_addr_t boundary = ALIGN_DOWN(addr + size, size);
38+
39+
return (boundary - 1 < end - 1) ? boundary : end;
40+
}
3441

3542
/*
3643
* Release kvm_mmu_lock periodically if the memory region is large. Otherwise,
@@ -52,7 +59,7 @@ static int stage2_apply_range(struct kvm *kvm, phys_addr_t addr,
5259
if (!pgt)
5360
return -EINVAL;
5461

55-
next = stage2_pgd_addr_end(kvm, addr, end);
62+
next = stage2_range_addr_end(addr, end);
5663
ret = fn(pgt, addr, next - addr);
5764
if (ret)
5865
break;

tools/testing/selftests/kvm/aarch64/vgic_init.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,8 @@ int test_kvm_device(uint32_t gic_dev_type)
662662
: KVM_DEV_TYPE_ARM_VGIC_V2;
663663

664664
if (!__kvm_test_create_device(v.vm, other)) {
665-
ret = __kvm_test_create_device(v.vm, other);
666-
TEST_ASSERT(ret && (errno == EINVAL || errno == EEXIST),
665+
ret = __kvm_create_device(v.vm, other);
666+
TEST_ASSERT(ret < 0 && (errno == EINVAL || errno == EEXIST),
667667
"create GIC device while other version exists");
668668
}
669669

tools/testing/selftests/kvm/memslot_modification_stress_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct memslot_antagonist_args {
6767
static void add_remove_memslot(struct kvm_vm *vm, useconds_t delay,
6868
uint64_t nr_modifications)
6969
{
70-
const uint64_t pages = 1;
70+
uint64_t pages = max_t(int, vm->page_size, getpagesize()) / vm->page_size;
7171
uint64_t gpa;
7272
int i;
7373

0 commit comments

Comments
 (0)