Skip to content

Commit e42b4a5

Browse files
committed
Merge tag 'kvmarm-for-v4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm updates for 4.20 - Improved guest IPA space support (32 to 52 bits) - RAS event delivery for 32bit - PMU fixes - Guest entry hardening - Various cleanups
2 parents 1e58e5e + e4e11cc commit e42b4a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1118
-565
lines changed

Documentation/virtual/kvm/api.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,37 @@ memory layout to fit in user mode), check KVM_CAP_MIPS_VZ and use the
123123
flag KVM_VM_MIPS_VZ.
124124

125125

126+
On arm64, the physical address size for a VM (IPA Size limit) is limited
127+
to 40bits by default. The limit can be configured if the host supports the
128+
extension KVM_CAP_ARM_VM_IPA_SIZE. When supported, use
129+
KVM_VM_TYPE_ARM_IPA_SIZE(IPA_Bits) to set the size in the machine type
130+
identifier, where IPA_Bits is the maximum width of any physical
131+
address used by the VM. The IPA_Bits is encoded in bits[7-0] of the
132+
machine type identifier.
133+
134+
e.g, to configure a guest to use 48bit physical address size :
135+
136+
vm_fd = ioctl(dev_fd, KVM_CREATE_VM, KVM_VM_TYPE_ARM_IPA_SIZE(48));
137+
138+
The requested size (IPA_Bits) must be :
139+
0 - Implies default size, 40bits (for backward compatibility)
140+
141+
or
142+
143+
N - Implies N bits, where N is a positive integer such that,
144+
32 <= N <= Host_IPA_Limit
145+
146+
Host_IPA_Limit is the maximum possible value for IPA_Bits on the host and
147+
is dependent on the CPU capability and the kernel configuration. The limit can
148+
be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the KVM_CHECK_EXTENSION
149+
ioctl() at run-time.
150+
151+
Please note that configuring the IPA size does not affect the capability
152+
exposed by the guest CPUs in ID_AA64MMFR0_EL1[PARange]. It only affects
153+
size of the address translated by the stage2 level (guest physical to
154+
host physical address translations).
155+
156+
126157
4.3 KVM_GET_MSR_INDEX_LIST, KVM_GET_MSR_FEATURE_INDEX_LIST
127158

128159
Capability: basic, KVM_CAP_GET_MSR_FEATURES for KVM_GET_MSR_FEATURE_INDEX_LIST

MAINTAINERS

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12260,6 +12260,7 @@ F: Documentation/networking/rds.txt
1226012260

1226112261
RDT - RESOURCE ALLOCATION
1226212262
M: Fenghua Yu <fenghua.yu@intel.com>
12263+
M: Reinette Chatre <reinette.chatre@intel.com>
1226312264
L: linux-kernel@vger.kernel.org
1226412265
S: Supported
1226512266
F: arch/x86/kernel/cpu/intel_rdt*
@@ -15924,6 +15925,7 @@ F: net/x25/
1592415925
X86 ARCHITECTURE (32-BIT AND 64-BIT)
1592515926
M: Thomas Gleixner <tglx@linutronix.de>
1592615927
M: Ingo Molnar <mingo@redhat.com>
15928+
M: Borislav Petkov <bp@alien8.de>
1592715929
R: "H. Peter Anvin" <hpa@zytor.com>
1592815930
M: x86@kernel.org
1592915931
L: linux-kernel@vger.kernel.org
@@ -15952,6 +15954,15 @@ M: Borislav Petkov <bp@alien8.de>
1595215954
S: Maintained
1595315955
F: arch/x86/kernel/cpu/microcode/*
1595415956

15957+
X86 MM
15958+
M: Dave Hansen <dave.hansen@linux.intel.com>
15959+
M: Andy Lutomirski <luto@kernel.org>
15960+
M: Peter Zijlstra <peterz@infradead.org>
15961+
L: linux-kernel@vger.kernel.org
15962+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/mm
15963+
S: Maintained
15964+
F: arch/x86/mm/
15965+
1595515966
X86 PLATFORM DRIVERS
1595615967
M: Darren Hart <dvhart@infradead.org>
1595715968
M: Andy Shevchenko <andy@infradead.org>

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
VERSION = 4
33
PATCHLEVEL = 19
44
SUBLEVEL = 0
5-
EXTRAVERSION = -rc4
5+
EXTRAVERSION = -rc5
66
NAME = Merciless Moray
77

88
# *DOCUMENTATION*

arch/arm/include/asm/kvm_arm.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,7 @@
133133
* space.
134134
*/
135135
#define KVM_PHYS_SHIFT (40)
136-
#define KVM_PHYS_SIZE (_AC(1, ULL) << KVM_PHYS_SHIFT)
137-
#define KVM_PHYS_MASK (KVM_PHYS_SIZE - _AC(1, ULL))
136+
138137
#define PTRS_PER_S2_PGD (_AC(1, ULL) << (KVM_PHYS_SHIFT - 30))
139138

140139
/* Virtualization Translation Control Register (VTCR) bits */

arch/arm/include/asm/kvm_host.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ static inline void __cpu_init_stage2(void)
273273
kvm_call_hyp(__init_stage2_translation);
274274
}
275275

276-
static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
276+
static inline int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext)
277277
{
278278
return 0;
279279
}
@@ -354,4 +354,15 @@ static inline void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu) {}
354354
struct kvm *kvm_arch_alloc_vm(void);
355355
void kvm_arch_free_vm(struct kvm *kvm);
356356

357+
static inline int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type)
358+
{
359+
/*
360+
* On 32bit ARM, VMs get a static 40bit IPA stage2 setup,
361+
* so any non-zero value used as type is illegal.
362+
*/
363+
if (type)
364+
return -EINVAL;
365+
return 0;
366+
}
367+
357368
#endif /* __ARM_KVM_HOST_H__ */

arch/arm/include/asm/kvm_mmu.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,26 @@
3535
addr; \
3636
})
3737

38-
/*
39-
* KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation levels.
40-
*/
41-
#define KVM_MMU_CACHE_MIN_PAGES 2
42-
4338
#ifndef __ASSEMBLY__
4439

4540
#include <linux/highmem.h>
4641
#include <asm/cacheflush.h>
4742
#include <asm/cputype.h>
43+
#include <asm/kvm_arm.h>
4844
#include <asm/kvm_hyp.h>
4945
#include <asm/pgalloc.h>
5046
#include <asm/stage2_pgtable.h>
5147

5248
/* Ensure compatibility with arm64 */
5349
#define VA_BITS 32
5450

51+
#define kvm_phys_shift(kvm) KVM_PHYS_SHIFT
52+
#define kvm_phys_size(kvm) (1ULL << kvm_phys_shift(kvm))
53+
#define kvm_phys_mask(kvm) (kvm_phys_size(kvm) - 1ULL)
54+
#define kvm_vttbr_baddr_mask(kvm) VTTBR_BADDR_MASK
55+
56+
#define stage2_pgd_size(kvm) (PTRS_PER_S2_PGD * sizeof(pgd_t))
57+
5558
int create_hyp_mappings(void *from, void *to, pgprot_t prot);
5659
int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
5760
void __iomem **kaddr,
@@ -355,6 +358,8 @@ static inline int hyp_map_aux_data(void)
355358

356359
#define kvm_phys_to_vttbr(addr) (addr)
357360

361+
static inline void kvm_set_ipa_limit(void) {}
362+
358363
#endif /* !__ASSEMBLY__ */
359364

360365
#endif /* __ARM_KVM_MMU_H__ */

arch/arm/include/asm/stage2_pgtable.h

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,43 +19,53 @@
1919
#ifndef __ARM_S2_PGTABLE_H_
2020
#define __ARM_S2_PGTABLE_H_
2121

22-
#define stage2_pgd_none(pgd) pgd_none(pgd)
23-
#define stage2_pgd_clear(pgd) pgd_clear(pgd)
24-
#define stage2_pgd_present(pgd) pgd_present(pgd)
25-
#define stage2_pgd_populate(pgd, pud) pgd_populate(NULL, pgd, pud)
26-
#define stage2_pud_offset(pgd, address) pud_offset(pgd, address)
27-
#define stage2_pud_free(pud) pud_free(NULL, pud)
28-
29-
#define stage2_pud_none(pud) pud_none(pud)
30-
#define stage2_pud_clear(pud) pud_clear(pud)
31-
#define stage2_pud_present(pud) pud_present(pud)
32-
#define stage2_pud_populate(pud, pmd) pud_populate(NULL, pud, pmd)
33-
#define stage2_pmd_offset(pud, address) pmd_offset(pud, address)
34-
#define stage2_pmd_free(pmd) pmd_free(NULL, pmd)
35-
36-
#define stage2_pud_huge(pud) pud_huge(pud)
22+
/*
23+
* kvm_mmu_cache_min_pages() is the number of pages required
24+
* to install a stage-2 translation. We pre-allocate the entry
25+
* level table at VM creation. Since we have a 3 level page-table,
26+
* we need only two pages to add a new mapping.
27+
*/
28+
#define kvm_mmu_cache_min_pages(kvm) 2
29+
30+
#define stage2_pgd_none(kvm, pgd) pgd_none(pgd)
31+
#define stage2_pgd_clear(kvm, pgd) pgd_clear(pgd)
32+
#define stage2_pgd_present(kvm, pgd) pgd_present(pgd)
33+
#define stage2_pgd_populate(kvm, pgd, pud) pgd_populate(NULL, pgd, pud)
34+
#define stage2_pud_offset(kvm, pgd, address) pud_offset(pgd, address)
35+
#define stage2_pud_free(kvm, pud) pud_free(NULL, pud)
36+
37+
#define stage2_pud_none(kvm, pud) pud_none(pud)
38+
#define stage2_pud_clear(kvm, pud) pud_clear(pud)
39+
#define stage2_pud_present(kvm, pud) pud_present(pud)
40+
#define stage2_pud_populate(kvm, pud, pmd) pud_populate(NULL, pud, pmd)
41+
#define stage2_pmd_offset(kvm, pud, address) pmd_offset(pud, address)
42+
#define stage2_pmd_free(kvm, pmd) pmd_free(NULL, pmd)
43+
44+
#define stage2_pud_huge(kvm, pud) pud_huge(pud)
3745

3846
/* Open coded p*d_addr_end that can deal with 64bit addresses */
39-
static inline phys_addr_t stage2_pgd_addr_end(phys_addr_t addr, phys_addr_t end)
47+
static inline phys_addr_t
48+
stage2_pgd_addr_end(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
4049
{
4150
phys_addr_t boundary = (addr + PGDIR_SIZE) & PGDIR_MASK;
4251

4352
return (boundary - 1 < end - 1) ? boundary : end;
4453
}
4554

46-
#define stage2_pud_addr_end(addr, end) (end)
55+
#define stage2_pud_addr_end(kvm, addr, end) (end)
4756

48-
static inline phys_addr_t stage2_pmd_addr_end(phys_addr_t addr, phys_addr_t end)
57+
static inline phys_addr_t
58+
stage2_pmd_addr_end(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
4959
{
5060
phys_addr_t boundary = (addr + PMD_SIZE) & PMD_MASK;
5161

5262
return (boundary - 1 < end - 1) ? boundary : end;
5363
}
5464

55-
#define stage2_pgd_index(addr) pgd_index(addr)
65+
#define stage2_pgd_index(kvm, addr) pgd_index(addr)
5666

57-
#define stage2_pte_table_empty(ptep) kvm_page_empty(ptep)
58-
#define stage2_pmd_table_empty(pmdp) kvm_page_empty(pmdp)
59-
#define stage2_pud_table_empty(pudp) false
67+
#define stage2_pte_table_empty(kvm, ptep) kvm_page_empty(ptep)
68+
#define stage2_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp)
69+
#define stage2_pud_table_empty(kvm, pudp) false
6070

6171
#endif /* __ARM_S2_PGTABLE_H_ */

arch/arm64/include/asm/cpufeature.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,26 @@ void arm64_set_ssbd_mitigation(bool state);
530530
static inline void arm64_set_ssbd_mitigation(bool state) {}
531531
#endif
532532

533+
static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
534+
{
535+
switch (parange) {
536+
case 0: return 32;
537+
case 1: return 36;
538+
case 2: return 40;
539+
case 3: return 42;
540+
case 4: return 44;
541+
case 5: return 48;
542+
case 6: return 52;
543+
/*
544+
* A future PE could use a value unknown to the kernel.
545+
* However, by the "D10.1.4 Principles of the ID scheme
546+
* for fields in ID registers", ARM DDI 0487C.a, any new
547+
* value is guaranteed to be higher than what we know already.
548+
* As a safe limit, we return the limit supported by the kernel.
549+
*/
550+
default: return CONFIG_ARM64_PA_BITS;
551+
}
552+
}
533553
#endif /* __ASSEMBLY__ */
534554

535555
#endif

0 commit comments

Comments
 (0)