Skip to content

Commit 2d38c80

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "ARM: - selftest fix - force PTE mapping on device pages provided via VFIO - fix detection of cacheable mapping at S2 - fallback to PMD/PTE mappings for composite huge pages - fix accounting of Stage-2 PGD allocation - fix AArch32 handling of some of the debug registers - simplify host HYP entry - fix stray pointer conversion on nVHE TLB invalidation - fix initialization of the nVHE code - simplify handling of capabilities exposed to HYP - nuke VCPUs caught using a forbidden AArch32 EL0 x86: - new nested virtualization selftest - miscellaneous fixes - make W=1 fixes - reserve new CPUID bit in the KVM leaves" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: vmx: remove unused variable KVM: selftests: Don't require THP to run tests KVM: VMX: eVMCS: make evmcs_sanitize_exec_ctrls() work again KVM: selftests: test behavior of unmapped L2 APIC-access address KVM: x86: Fix NULL dereference at kvm_msr_ignored_check() KVM: x86: replace static const variables with macros KVM: arm64: Handle Asymmetric AArch32 systems arm64: cpufeature: upgrade hyp caps to final arm64: cpufeature: reorder cpus_have_{const, final}_cap() KVM: arm64: Factor out is_{vhe,nvhe}_hyp_code() KVM: arm64: Force PTE mapping on fault resulting in a device mapping KVM: arm64: Use fallback mapping sizes for contiguous huge page sizes KVM: arm64: Fix masks in stage2_pte_cacheable() KVM: arm64: Fix AArch32 handling of DBGD{CCINT,SCRext} and DBGVCR KVM: arm64: Allocate stage-2 pgd pages with GFP_KERNEL_ACCOUNT KVM: arm64: Drop useless PAN setting on host EL1 to EL2 transition KVM: arm64: Remove leftover kern_hyp_va() in nVHE TLB invalidation KVM: arm64: Don't corrupt tpidr_el2 on failed HVC call x86/kvm: Reserve KVM_FEATURE_MSI_EXT_DEST_ID
2 parents c2dc4c0 + 9478dec commit 2d38c80

26 files changed

Lines changed: 306 additions & 76 deletions

File tree

Documentation/virt/kvm/cpuid.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ KVM_FEATURE_ASYNC_PF_INT 14 guest checks this feature bit
9292
async pf acknowledgment msr
9393
0x4b564d07.
9494

95+
KVM_FEATURE_MSI_EXT_DEST_ID 15 guest checks this feature bit
96+
before using extended destination
97+
ID bits in MSI address bits 11-5.
98+
9599
KVM_FEATURE_CLOCKSOURCE_STABLE_BIT 24 host will warn if no guest-side
96100
per-cpu warps are expected in
97101
kvmclock

arch/arm64/include/asm/cpufeature.h

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,23 @@ cpucap_multi_entry_cap_matches(const struct arm64_cpu_capabilities *entry,
375375
return false;
376376
}
377377

378+
static __always_inline bool is_vhe_hyp_code(void)
379+
{
380+
/* Only defined for code run in VHE hyp context */
381+
return __is_defined(__KVM_VHE_HYPERVISOR__);
382+
}
383+
384+
static __always_inline bool is_nvhe_hyp_code(void)
385+
{
386+
/* Only defined for code run in NVHE hyp context */
387+
return __is_defined(__KVM_NVHE_HYPERVISOR__);
388+
}
389+
390+
static __always_inline bool is_hyp_code(void)
391+
{
392+
return is_vhe_hyp_code() || is_nvhe_hyp_code();
393+
}
394+
378395
extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
379396
extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
380397
extern struct static_key_false arm64_const_caps_ready;
@@ -428,35 +445,40 @@ static __always_inline bool __cpus_have_const_cap(int num)
428445
}
429446

430447
/*
431-
* Test for a capability, possibly with a runtime check.
448+
* Test for a capability without a runtime check.
432449
*
433-
* Before capabilities are finalized, this behaves as cpus_have_cap().
450+
* Before capabilities are finalized, this will BUG().
434451
* After capabilities are finalized, this is patched to avoid a runtime check.
435452
*
436453
* @num must be a compile-time constant.
437454
*/
438-
static __always_inline bool cpus_have_const_cap(int num)
455+
static __always_inline bool cpus_have_final_cap(int num)
439456
{
440457
if (system_capabilities_finalized())
441458
return __cpus_have_const_cap(num);
442459
else
443-
return cpus_have_cap(num);
460+
BUG();
444461
}
445462

446463
/*
447-
* Test for a capability without a runtime check.
464+
* Test for a capability, possibly with a runtime check for non-hyp code.
448465
*
449-
* Before capabilities are finalized, this will BUG().
466+
* For hyp code, this behaves the same as cpus_have_final_cap().
467+
*
468+
* For non-hyp code:
469+
* Before capabilities are finalized, this behaves as cpus_have_cap().
450470
* After capabilities are finalized, this is patched to avoid a runtime check.
451471
*
452472
* @num must be a compile-time constant.
453473
*/
454-
static __always_inline bool cpus_have_final_cap(int num)
474+
static __always_inline bool cpus_have_const_cap(int num)
455475
{
456-
if (system_capabilities_finalized())
476+
if (is_hyp_code())
477+
return cpus_have_final_cap(num);
478+
else if (system_capabilities_finalized())
457479
return __cpus_have_const_cap(num);
458480
else
459-
BUG();
481+
return cpus_have_cap(num);
460482
}
461483

462484
static inline void cpus_set_cap(unsigned int num)

arch/arm64/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ enum vcpu_sysreg {
239239
#define cp14_DBGWCR0 (DBGWCR0_EL1 * 2)
240240
#define cp14_DBGWVR0 (DBGWVR0_EL1 * 2)
241241
#define cp14_DBGDCCINT (MDCCINT_EL1 * 2)
242+
#define cp14_DBGVCR (DBGVCR32_EL2 * 2)
242243

243244
#define NR_COPRO_REGS (NR_SYS_REGS * 2)
244245

arch/arm64/include/asm/virt.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,12 @@ static inline bool is_kernel_in_hyp_mode(void)
8686
static __always_inline bool has_vhe(void)
8787
{
8888
/*
89-
* The following macros are defined for code specic to VHE/nVHE.
90-
* If has_vhe() is inlined into those compilation units, it can
91-
* be determined statically. Otherwise fall back to caps.
89+
* Code only run in VHE/NVHE hyp context can assume VHE is present or
90+
* absent. Otherwise fall back to caps.
9291
*/
93-
if (__is_defined(__KVM_VHE_HYPERVISOR__))
92+
if (is_vhe_hyp_code())
9493
return true;
95-
else if (__is_defined(__KVM_NVHE_HYPERVISOR__))
94+
else if (is_nvhe_hyp_code())
9695
return false;
9796
else
9897
return cpus_have_final_cap(ARM64_HAS_VIRT_HOST_EXTN);

arch/arm64/kernel/image-vars.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ KVM_NVHE_ALIAS(__icache_flags);
8787
/* Kernel symbols needed for cpus_have_final/const_caps checks. */
8888
KVM_NVHE_ALIAS(arm64_const_caps_ready);
8989
KVM_NVHE_ALIAS(cpu_hwcap_keys);
90-
KVM_NVHE_ALIAS(cpu_hwcaps);
9190

9291
/* Static keys which are set if a vGIC trap should be handled in hyp. */
9392
KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);

arch/arm64/kvm/arm.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,25 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
808808

809809
preempt_enable();
810810

811+
/*
812+
* The ARMv8 architecture doesn't give the hypervisor
813+
* a mechanism to prevent a guest from dropping to AArch32 EL0
814+
* if implemented by the CPU. If we spot the guest in such
815+
* state and that we decided it wasn't supposed to do so (like
816+
* with the asymmetric AArch32 case), return to userspace with
817+
* a fatal error.
818+
*/
819+
if (!system_supports_32bit_el0() && vcpu_mode_is_32bit(vcpu)) {
820+
/*
821+
* As we have caught the guest red-handed, decide that
822+
* it isn't fit for purpose anymore by making the vcpu
823+
* invalid. The VMM can try and fix it by issuing a
824+
* KVM_ARM_VCPU_INIT if it really wants to.
825+
*/
826+
vcpu->arch.target = -1;
827+
ret = ARM_EXCEPTION_IL;
828+
}
829+
811830
ret = handle_exit(vcpu, ret);
812831
}
813832

arch/arm64/kvm/hyp/nvhe/host.S

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ SYM_FUNC_START(__host_exit)
1717

1818
get_host_ctxt x0, x1
1919

20-
ALTERNATIVE(nop, SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
21-
2220
/* Store the host regs x2 and x3 */
2321
stp x2, x3, [x0, #CPU_XREG_OFFSET(2)]
2422

arch/arm64/kvm/hyp/nvhe/hyp-init.S

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,25 @@ __do_hyp_init:
5757
cmp x0, #HVC_STUB_HCALL_NR
5858
b.lo __kvm_handle_stub_hvc
5959

60-
/* Set tpidr_el2 for use by HYP to free a register */
61-
msr tpidr_el2, x2
62-
63-
mov x2, #KVM_HOST_SMCCC_FUNC(__kvm_hyp_init)
64-
cmp x0, x2
65-
b.eq 1f
60+
// We only actively check bits [24:31], and everything
61+
// else has to be zero, which we check at build time.
62+
#if (KVM_HOST_SMCCC_FUNC(__kvm_hyp_init) & 0xFFFFFFFF00FFFFFF)
63+
#error Unexpected __KVM_HOST_SMCCC_FUNC___kvm_hyp_init value
64+
#endif
65+
66+
ror x0, x0, #24
67+
eor x0, x0, #((KVM_HOST_SMCCC_FUNC(__kvm_hyp_init) >> 24) & 0xF)
68+
ror x0, x0, #4
69+
eor x0, x0, #((KVM_HOST_SMCCC_FUNC(__kvm_hyp_init) >> 28) & 0xF)
70+
cbz x0, 1f
6671
mov x0, #SMCCC_RET_NOT_SUPPORTED
6772
eret
6873

69-
1: phys_to_ttbr x0, x1
74+
1:
75+
/* Set tpidr_el2 for use by HYP to free a register */
76+
msr tpidr_el2, x2
77+
78+
phys_to_ttbr x0, x1
7079
alternative_if ARM64_HAS_CNP
7180
orr x0, x0, #TTBR_CNP_BIT
7281
alternative_else_nop_endif

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu)
128128
struct tlb_inv_context cxt;
129129

130130
/* Switch to requested VMID */
131-
mmu = kern_hyp_va(mmu);
132131
__tlb_switch_to_guest(mmu, &cxt);
133132

134133
__tlbi(vmalle1);

arch/arm64/kvm/hyp/pgtable.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ static void stage2_flush_dcache(void *addr, u64 size)
635635

636636
static bool stage2_pte_cacheable(kvm_pte_t pte)
637637
{
638-
u64 memattr = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR, pte);
638+
u64 memattr = pte & KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR;
639639
return memattr == PAGE_S2_MEMATTR(NORMAL);
640640
}
641641

@@ -846,7 +846,7 @@ int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm *kvm)
846846
u32 start_level = VTCR_EL2_TGRAN_SL0_BASE - sl0;
847847

848848
pgd_sz = kvm_pgd_pages(ia_bits, start_level) * PAGE_SIZE;
849-
pgt->pgd = alloc_pages_exact(pgd_sz, GFP_KERNEL | __GFP_ZERO);
849+
pgt->pgd = alloc_pages_exact(pgd_sz, GFP_KERNEL_ACCOUNT | __GFP_ZERO);
850850
if (!pgt->pgd)
851851
return -ENOMEM;
852852

0 commit comments

Comments
 (0)