diff options
author | Vladimir Murzin <vladimir.murzin@arm.com> | 2015-11-16 06:28:18 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2015-12-18 05:15:12 -0500 |
commit | 20475f784d29991b3b843c80c38a36f2ebb35ac4 (patch) | |
tree | fce9116aeb5f04122e323a240daeb5a018feb360 | |
parent | 8420dcd37ef34040c8fc5a27bf66887b3b2faf80 (diff) |
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>
-rw-r--r-- | arch/arm/include/asm/kvm_arm.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/kvm_mmu.h | 5 | ||||
-rw-r--r-- | arch/arm/kvm/arm.c | 10 | ||||
-rw-r--r-- | arch/arm64/include/asm/kvm_arm.h | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/kvm_mmu.h | 8 | ||||
-rw-r--r-- | arch/arm64/kvm/hyp-init.S | 9 |
6 files changed, 33 insertions, 4 deletions
diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index 01d4d7abe34e..e22089fb44dc 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h | |||
@@ -164,7 +164,7 @@ | |||
164 | #define VTTBR_BADDR_SHIFT (VTTBR_X - 1) | 164 | #define VTTBR_BADDR_SHIFT (VTTBR_X - 1) |
165 | #define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) | 165 | #define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) |
166 | #define VTTBR_VMID_SHIFT _AC(48, ULL) | 166 | #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) |
168 | 168 | ||
169 | /* Hyp Syndrome Register (HSR) bits */ | 169 | /* Hyp Syndrome Register (HSR) bits */ |
170 | #define HSR_EC_SHIFT (26) | 170 | #define HSR_EC_SHIFT (26) |
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 405aa1883307..9203c21b4673 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
@@ -279,6 +279,11 @@ static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd, | |||
279 | pgd_t *merged_hyp_pgd, | 279 | pgd_t *merged_hyp_pgd, |
280 | unsigned long hyp_idmap_start) { } | 280 | unsigned long hyp_idmap_start) { } |
281 | 281 | ||
282 | static inline unsigned int kvm_get_vmid_bits(void) | ||
283 | { | ||
284 | return 8; | ||
285 | } | ||
286 | |||
282 | #endif /* !__ASSEMBLY__ */ | 287 | #endif /* !__ASSEMBLY__ */ |
283 | 288 | ||
284 | #endif /* __ARM_KVM_MMU_H__ */ | 289 | #endif /* __ARM_KVM_MMU_H__ */ |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 6e35d1d7893e..f6bcc2e4a133 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -59,7 +59,8 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu); | |||
59 | 59 | ||
60 | /* The VMID used in the VTTBR */ | 60 | /* The VMID used in the VTTBR */ |
61 | static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); | 61 | 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; | ||
63 | static DEFINE_SPINLOCK(kvm_vmid_lock); | 64 | static DEFINE_SPINLOCK(kvm_vmid_lock); |
64 | 65 | ||
65 | static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) | 66 | static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) |
@@ -434,11 +435,12 @@ static void update_vttbr(struct kvm *kvm) | |||
434 | kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen); | 435 | kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen); |
435 | kvm->arch.vmid = kvm_next_vmid; | 436 | kvm->arch.vmid = kvm_next_vmid; |
436 | kvm_next_vmid++; | 437 | kvm_next_vmid++; |
438 | kvm_next_vmid &= (1 << kvm_vmid_bits) - 1; | ||
437 | 439 | ||
438 | /* update vttbr to be used with the new vmid */ | 440 | /* update vttbr to be used with the new vmid */ |
439 | pgd_phys = virt_to_phys(kvm_get_hwpgd(kvm)); | 441 | pgd_phys = virt_to_phys(kvm_get_hwpgd(kvm)); |
440 | BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK); | 442 | BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK); |
441 | vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK; | 443 | vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits); |
442 | kvm->arch.vttbr = pgd_phys | vmid; | 444 | kvm->arch.vttbr = pgd_phys | vmid; |
443 | 445 | ||
444 | spin_unlock(&kvm_vmid_lock); | 446 | spin_unlock(&kvm_vmid_lock); |
@@ -1135,6 +1137,10 @@ static int init_hyp_mode(void) | |||
1135 | 1137 | ||
1136 | kvm_perf_init(); | 1138 | kvm_perf_init(); |
1137 | 1139 | ||
1140 | /* set size of VMID supported by CPU */ | ||
1141 | kvm_vmid_bits = kvm_get_vmid_bits(); | ||
1142 | kvm_info("%d-bit VMID\n", kvm_vmid_bits); | ||
1143 | |||
1138 | kvm_info("Hyp mode initialized successfully\n"); | 1144 | kvm_info("Hyp mode initialized successfully\n"); |
1139 | 1145 | ||
1140 | return 0; | 1146 | return 0; |
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 5e6857b6bdc4..738a95f93e49 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h | |||
@@ -125,6 +125,7 @@ | |||
125 | #define VTCR_EL2_SL0_LVL1 (1 << 6) | 125 | #define VTCR_EL2_SL0_LVL1 (1 << 6) |
126 | #define VTCR_EL2_T0SZ_MASK 0x3f | 126 | #define VTCR_EL2_T0SZ_MASK 0x3f |
127 | #define VTCR_EL2_T0SZ_40B 24 | 127 | #define VTCR_EL2_T0SZ_40B 24 |
128 | #define VTCR_EL2_VS 19 | ||
128 | 129 | ||
129 | /* | 130 | /* |
130 | * We configure the Stage-2 page tables to always restrict the IPA space to be | 131 | * We configure the Stage-2 page tables to always restrict the IPA space to be |
@@ -169,7 +170,7 @@ | |||
169 | #define VTTBR_BADDR_SHIFT (VTTBR_X - 1) | 170 | #define VTTBR_BADDR_SHIFT (VTTBR_X - 1) |
170 | #define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) | 171 | #define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) |
171 | #define VTTBR_VMID_SHIFT (UL(48)) | 172 | #define VTTBR_VMID_SHIFT (UL(48)) |
172 | #define VTTBR_VMID_MASK (UL(0xFF) << VTTBR_VMID_SHIFT) | 173 | #define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT) |
173 | 174 | ||
174 | /* Hyp System Trap Register */ | 175 | /* Hyp System Trap Register */ |
175 | #define HSTR_EL2_T(x) (1 << x) | 176 | #define HSTR_EL2_T(x) (1 << x) |
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 54cba803e2d9..0bf8b4320a91 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <asm/page.h> | 21 | #include <asm/page.h> |
22 | #include <asm/memory.h> | 22 | #include <asm/memory.h> |
23 | #include <asm/cpufeature.h> | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * As we only have the TTBR0_EL2 register, we cannot express | 26 | * 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, | |||
301 | merged_hyp_pgd[idmap_idx] = __pgd(__pa(boot_hyp_pgd) | PMD_TYPE_TABLE); | 302 | merged_hyp_pgd[idmap_idx] = __pgd(__pa(boot_hyp_pgd) | PMD_TYPE_TABLE); |
302 | } | 303 | } |
303 | 304 | ||
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 | |||
304 | #endif /* __ASSEMBLY__ */ | 312 | #endif /* __ASSEMBLY__ */ |
305 | #endif /* __ARM64_KVM_MMU_H__ */ | 313 | #endif /* __ARM64_KVM_MMU_H__ */ |
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index 178ba2248a98..3e568dcd907b 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S | |||
@@ -94,6 +94,15 @@ __do_hyp_init: | |||
94 | */ | 94 | */ |
95 | mrs x5, ID_AA64MMFR0_EL1 | 95 | mrs x5, ID_AA64MMFR0_EL1 |
96 | bfi x4, x5, #16, #3 | 96 | bfi x4, x5, #16, #3 |
97 | /* | ||
98 | * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS bit in | ||
99 | * VTCR_EL2. | ||
100 | */ | ||
101 | mrs x5, ID_AA64MMFR1_EL1 | ||
102 | ubfx x5, x5, #5, #1 | ||
103 | lsl x5, x5, #VTCR_EL2_VS | ||
104 | orr x4, x4, x5 | ||
105 | |||
97 | msr vtcr_el2, x4 | 106 | msr vtcr_el2, x4 |
98 | 107 | ||
99 | mrs x4, mair_el1 | 108 | mrs x4, mair_el1 |