Skip to content

Commit 1a1549b

Browse files
murzinvAlex Shi
authored andcommitted
arm64: KVM: Add support for 16-bit VMID
The ARMv8.1 architecture extension allows to choose between 8-bit and 16-bit of VMID, so use this capability for KVM. Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> (cherry picked from commit 20475f784d29991b3b843c80c38a36f2ebb35ac4) Signed-off-by: Alex Shi <alex.shi@linaro.org> Conflicts: camptiable with LTS 849e28e:arm64: KVM: Configure TCR_EL2.PS at runtime in arch/arm64/kvm/hyp-init.S
1 parent 516f3f7 commit 1a1549b

6 files changed

Lines changed: 32 additions & 4 deletions

File tree

arch/arm/include/asm/kvm_arm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@
164164
#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
165165
#define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
166166
#define VTTBR_VMID_SHIFT _AC(48, ULL)
167-
#define VTTBR_VMID_MASK (_AC(0xff, ULL) << VTTBR_VMID_SHIFT)
167+
#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
168168

169169
/* Hyp Syndrome Register (HSR) bits */
170170
#define HSR_EC_SHIFT (26)

arch/arm/include/asm/kvm_mmu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
279279
pgd_t *merged_hyp_pgd,
280280
unsigned long hyp_idmap_start) { }
281281

282+
static inline unsigned int kvm_get_vmid_bits(void)
283+
{
284+
return 8;
285+
}
286+
282287
#endif /* !__ASSEMBLY__ */
283288

284289
#endif /* __ARM_KVM_MMU_H__ */

arch/arm/kvm/arm.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
5959

6060
/* The VMID used in the VTTBR */
6161
static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
62-
static u8 kvm_next_vmid;
62+
static u32 kvm_next_vmid;
63+
static unsigned int kvm_vmid_bits __read_mostly;
6364
static DEFINE_SPINLOCK(kvm_vmid_lock);
6465

6566
static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
@@ -432,11 +433,12 @@ static void update_vttbr(struct kvm *kvm)
432433
kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen);
433434
kvm->arch.vmid = kvm_next_vmid;
434435
kvm_next_vmid++;
436+
kvm_next_vmid &= (1 << kvm_vmid_bits) - 1;
435437

436438
/* update vttbr to be used with the new vmid */
437439
pgd_phys = virt_to_phys(kvm_get_hwpgd(kvm));
438440
BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK);
439-
vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK;
441+
vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits);
440442
kvm->arch.vttbr = pgd_phys | vmid;
441443

442444
spin_unlock(&kvm_vmid_lock);
@@ -1132,6 +1134,10 @@ static int init_hyp_mode(void)
11321134

11331135
kvm_perf_init();
11341136

1137+
/* set size of VMID supported by CPU */
1138+
kvm_vmid_bits = kvm_get_vmid_bits();
1139+
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
1140+
11351141
kvm_info("Hyp mode initialized successfully\n");
11361142

11371143
return 0;

arch/arm64/include/asm/kvm_arm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
#define VTCR_EL2_SL0_LVL1 (1 << 6)
124124
#define VTCR_EL2_T0SZ_MASK 0x3f
125125
#define VTCR_EL2_T0SZ_40B 24
126+
#define VTCR_EL2_VS 19
126127

127128
/*
128129
* We configure the Stage-2 page tables to always restrict the IPA space to be
@@ -167,7 +168,7 @@
167168
#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
168169
#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
169170
#define VTTBR_VMID_SHIFT (UL(48))
170-
#define VTTBR_VMID_MASK (UL(0xFF) << VTTBR_VMID_SHIFT)
171+
#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
171172

172173
/* Hyp System Trap Register */
173174
#define HSTR_EL2_T(x) (1 << x)

arch/arm64/include/asm/kvm_mmu.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <asm/page.h>
2222
#include <asm/memory.h>
23+
#include <asm/cpufeature.h>
2324

2425
/*
2526
* As we only have the TTBR0_EL2 register, we cannot express
@@ -301,5 +302,12 @@ static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
301302
merged_hyp_pgd[idmap_idx] = __pgd(__pa(boot_hyp_pgd) | PMD_TYPE_TABLE);
302303
}
303304

305+
static inline unsigned int kvm_get_vmid_bits(void)
306+
{
307+
int reg = read_system_reg(SYS_ID_AA64MMFR1_EL1);
308+
309+
return (cpuid_feature_extract_field(reg, ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8;
310+
}
311+
304312
#endif /* __ASSEMBLY__ */
305313
#endif /* __ARM64_KVM_MMU_H__ */

arch/arm64/kvm/hyp-init.S

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ __do_hyp_init:
9696

9797
ldr x4, =VTCR_EL2_FLAGS
9898
bfi x4, x5, #16, #3
99+
/*
100+
* Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS bit in
101+
* VTCR_EL2.
102+
*/
103+
mrs x5, ID_AA64MMFR1_EL1
104+
ubfx x5, x5, #5, #1
105+
lsl x5, x5, #VTCR_EL2_VS
106+
orr x4, x4, x5
99107

100108
msr vtcr_el2, x4
101109

0 commit comments

Comments
 (0)