Skip to content

Commit 269f4a4

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "ARM: - Avoid pKVM finalization if KVM initialization fails - Add missing BTI instructions in the hypervisor, fixing an early boot failure on BTI systems - Handle MMU notifiers correctly for non hugepage-aligned memslots - Work around a bug in the architecture where hypervisor timer controls have UNKNOWN behavior under nested virt - Disable preemption in kvm_arch_hardware_enable(), fixing a kernel BUG in cpu hotplug resulting from per-CPU accessor sanity checking - Make WFI emulation on GICv4 systems robust w.r.t. preemption, consistently requesting a doorbell interrupt on vcpu_put() - Uphold RES0 sysreg behavior when emulating older PMU versions - Avoid macro expansion when initializing PMU register names, ensuring the tracepoints pretty-print the sysreg s390: - Two fixes for asynchronous destroy x86 fixes will come early next week" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: s390: pv: fix index value of replaced ASCE KVM: s390: pv: simplify shutdown and fix race KVM: arm64: Fix the name of sys_reg_desc related to PMU KVM: arm64: Correctly handle RES0 bits PMEVTYPER<n>_EL0.evtCount KVM: arm64: vgic-v4: Make the doorbell request robust w.r.t preemption KVM: arm64: Add missing BTI instructions KVM: arm64: Correctly handle page aging notifiers for unaligned memslot KVM: arm64: Disable preemption in kvm_arch_hardware_enable() KVM: arm64: Handle kvm_arm_init failure correctly in finalize_pkvm KVM: arm64: timers: Use CNTHCTL_EL2 when setting non-CNTKCTL_EL1 bits
2 parents 15b593b + 0c18970 commit 269f4a4

File tree

17 files changed

+140
-72
lines changed

17 files changed

+140
-72
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,8 @@ struct kvm_vcpu_arch {
727727
#define DBG_SS_ACTIVE_PENDING __vcpu_single_flag(sflags, BIT(5))
728728
/* PMUSERENR for the guest EL0 is on physical CPU */
729729
#define PMUSERENR_ON_CPU __vcpu_single_flag(sflags, BIT(6))
730+
/* WFI instruction trapped */
731+
#define IN_WFI __vcpu_single_flag(sflags, BIT(7))
730732

731733

732734
/* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */

arch/arm64/include/asm/kvm_pgtable.h

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -608,22 +608,26 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
608608
kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr);
609609

610610
/**
611-
* kvm_pgtable_stage2_mkold() - Clear the access flag in a page-table entry.
611+
* kvm_pgtable_stage2_test_clear_young() - Test and optionally clear the access
612+
* flag in a page-table entry.
612613
* @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
613614
* @addr: Intermediate physical address to identify the page-table entry.
615+
* @size: Size of the address range to visit.
616+
* @mkold: True if the access flag should be cleared.
614617
*
615618
* The offset of @addr within a page is ignored.
616619
*
617-
* If there is a valid, leaf page-table entry used to translate @addr, then
618-
* clear the access flag in that entry.
620+
* Tests and conditionally clears the access flag for every valid, leaf
621+
* page-table entry used to translate the range [@addr, @addr + @size).
619622
*
620623
* Note that it is the caller's responsibility to invalidate the TLB after
621624
* calling this function to ensure that the updated permissions are visible
622625
* to the CPUs.
623626
*
624-
* Return: The old page-table entry prior to clearing the flag, 0 on failure.
627+
* Return: True if any of the visited PTEs had the access flag set.
625628
*/
626-
kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr);
629+
bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
630+
u64 size, bool mkold);
627631

628632
/**
629633
* kvm_pgtable_stage2_relax_perms() - Relax the permissions enforced by a
@@ -645,18 +649,6 @@ kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr);
645649
int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
646650
enum kvm_pgtable_prot prot);
647651

648-
/**
649-
* kvm_pgtable_stage2_is_young() - Test whether a page-table entry has the
650-
* access flag set.
651-
* @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
652-
* @addr: Intermediate physical address to identify the page-table entry.
653-
*
654-
* The offset of @addr within a page is ignored.
655-
*
656-
* Return: True if the page-table entry has the access flag set, false otherwise.
657-
*/
658-
bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr);
659-
660652
/**
661653
* kvm_pgtable_stage2_flush_range() - Clean and invalidate data cache to Point
662654
* of Coherency for guest stage-2 address

arch/arm64/include/asm/virt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ extern u32 __boot_cpu_mode[2];
7878

7979
void __hyp_set_vectors(phys_addr_t phys_vector_base);
8080
void __hyp_reset_vectors(void);
81+
bool is_kvm_arm_initialised(void);
8182

8283
DECLARE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);
8384

arch/arm64/kvm/arch_timer.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -827,8 +827,8 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
827827
assign_clear_set_bit(tpt, CNTHCTL_EL1PCEN << 10, set, clr);
828828
assign_clear_set_bit(tpc, CNTHCTL_EL1PCTEN << 10, set, clr);
829829

830-
/* This only happens on VHE, so use the CNTKCTL_EL1 accessor */
831-
sysreg_clear_set(cntkctl_el1, clr, set);
830+
/* This only happens on VHE, so use the CNTHCTL_EL2 accessor. */
831+
sysreg_clear_set(cnthctl_el2, clr, set);
832832
}
833833

834834
void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
@@ -1563,7 +1563,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
15631563
void kvm_timer_init_vhe(void)
15641564
{
15651565
if (cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF))
1566-
sysreg_clear_set(cntkctl_el1, 0, CNTHCTL_ECV);
1566+
sysreg_clear_set(cnthctl_el2, 0, CNTHCTL_ECV);
15671567
}
15681568

15691569
int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)

arch/arm64/kvm/arm.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,16 @@ DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
5353

5454
DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
5555

56-
static bool vgic_present;
56+
static bool vgic_present, kvm_arm_initialised;
5757

5858
static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled);
5959
DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
6060

61+
bool is_kvm_arm_initialised(void)
62+
{
63+
return kvm_arm_initialised;
64+
}
65+
6166
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
6267
{
6368
return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
@@ -713,13 +718,15 @@ void kvm_vcpu_wfi(struct kvm_vcpu *vcpu)
713718
*/
714719
preempt_disable();
715720
kvm_vgic_vmcr_sync(vcpu);
716-
vgic_v4_put(vcpu, true);
721+
vcpu_set_flag(vcpu, IN_WFI);
722+
vgic_v4_put(vcpu);
717723
preempt_enable();
718724

719725
kvm_vcpu_halt(vcpu);
720726
vcpu_clear_flag(vcpu, IN_WFIT);
721727

722728
preempt_disable();
729+
vcpu_clear_flag(vcpu, IN_WFI);
723730
vgic_v4_load(vcpu);
724731
preempt_enable();
725732
}
@@ -787,7 +794,7 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
787794
if (kvm_check_request(KVM_REQ_RELOAD_GICv4, vcpu)) {
788795
/* The distributor enable bits were changed */
789796
preempt_disable();
790-
vgic_v4_put(vcpu, false);
797+
vgic_v4_put(vcpu);
791798
vgic_v4_load(vcpu);
792799
preempt_enable();
793800
}
@@ -1867,15 +1874,26 @@ static void _kvm_arch_hardware_enable(void *discard)
18671874

18681875
int kvm_arch_hardware_enable(void)
18691876
{
1870-
int was_enabled = __this_cpu_read(kvm_arm_hardware_enabled);
1877+
int was_enabled;
1878+
1879+
/*
1880+
* Most calls to this function are made with migration
1881+
* disabled, but not with preemption disabled. The former is
1882+
* enough to ensure correctness, but most of the helpers
1883+
* expect the later and will throw a tantrum otherwise.
1884+
*/
1885+
preempt_disable();
18711886

1887+
was_enabled = __this_cpu_read(kvm_arm_hardware_enabled);
18721888
_kvm_arch_hardware_enable(NULL);
18731889

18741890
if (!was_enabled) {
18751891
kvm_vgic_cpu_up();
18761892
kvm_timer_cpu_up();
18771893
}
18781894

1895+
preempt_enable();
1896+
18791897
return 0;
18801898
}
18811899

@@ -2482,6 +2500,8 @@ static __init int kvm_arm_init(void)
24822500
if (err)
24832501
goto out_subs;
24842502

2503+
kvm_arm_initialised = true;
2504+
24852505
return 0;
24862506

24872507
out_subs:

arch/arm64/kvm/hyp/hyp-entry.S

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ SYM_CODE_END(\label)
154154
esb
155155
stp x0, x1, [sp, #-16]!
156156
662:
157+
/*
158+
* spectre vectors __bp_harden_hyp_vecs generate br instructions at runtime
159+
* that jump at offset 8 at __kvm_hyp_vector.
160+
* As hyp .text is guarded section, it needs bti j.
161+
*/
162+
bti j
157163
b \target
158164

159165
check_preamble_length 661b, 662b
@@ -165,6 +171,8 @@ check_preamble_length 661b, 662b
165171
nop
166172
stp x0, x1, [sp, #-16]!
167173
662:
174+
/* Check valid_vect */
175+
bti j
168176
b \target
169177

170178
check_preamble_length 661b, 662b

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,13 @@ SYM_CODE_START(__kvm_hyp_host_forward_smc)
297297

298298
ret
299299
SYM_CODE_END(__kvm_hyp_host_forward_smc)
300+
301+
/*
302+
* kvm_host_psci_cpu_entry is called through br instruction, which requires
303+
* bti j instruction as compilers (gcc and llvm) doesn't insert bti j for external
304+
* functions, but bti c instead.
305+
*/
306+
SYM_CODE_START(kvm_host_psci_cpu_entry)
307+
bti j
308+
b __kvm_host_psci_cpu_entry
309+
SYM_CODE_END(kvm_host_psci_cpu_entry)

arch/arm64/kvm/hyp/nvhe/psci-relay.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static int psci_system_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt)
200200
__hyp_pa(init_params), 0);
201201
}
202202

203-
asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on)
203+
asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on)
204204
{
205205
struct psci_boot_args *boot_args;
206206
struct kvm_cpu_context *host_ctxt;

arch/arm64/kvm/hyp/pgtable.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,25 +1195,54 @@ kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr)
11951195
return pte;
11961196
}
11971197

1198-
kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr)
1198+
struct stage2_age_data {
1199+
bool mkold;
1200+
bool young;
1201+
};
1202+
1203+
static int stage2_age_walker(const struct kvm_pgtable_visit_ctx *ctx,
1204+
enum kvm_pgtable_walk_flags visit)
11991205
{
1200-
kvm_pte_t pte = 0;
1201-
stage2_update_leaf_attrs(pgt, addr, 1, 0, KVM_PTE_LEAF_ATTR_LO_S2_AF,
1202-
&pte, NULL, 0);
1206+
kvm_pte_t new = ctx->old & ~KVM_PTE_LEAF_ATTR_LO_S2_AF;
1207+
struct stage2_age_data *data = ctx->arg;
1208+
1209+
if (!kvm_pte_valid(ctx->old) || new == ctx->old)
1210+
return 0;
1211+
1212+
data->young = true;
1213+
1214+
/*
1215+
* stage2_age_walker() is always called while holding the MMU lock for
1216+
* write, so this will always succeed. Nonetheless, this deliberately
1217+
* follows the race detection pattern of the other stage-2 walkers in
1218+
* case the locking mechanics of the MMU notifiers is ever changed.
1219+
*/
1220+
if (data->mkold && !stage2_try_set_pte(ctx, new))
1221+
return -EAGAIN;
1222+
12031223
/*
12041224
* "But where's the TLBI?!", you scream.
12051225
* "Over in the core code", I sigh.
12061226
*
12071227
* See the '->clear_flush_young()' callback on the KVM mmu notifier.
12081228
*/
1209-
return pte;
1229+
return 0;
12101230
}
12111231

1212-
bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr)
1232+
bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
1233+
u64 size, bool mkold)
12131234
{
1214-
kvm_pte_t pte = 0;
1215-
stage2_update_leaf_attrs(pgt, addr, 1, 0, 0, &pte, NULL, 0);
1216-
return pte & KVM_PTE_LEAF_ATTR_LO_S2_AF;
1235+
struct stage2_age_data data = {
1236+
.mkold = mkold,
1237+
};
1238+
struct kvm_pgtable_walker walker = {
1239+
.cb = stage2_age_walker,
1240+
.arg = &data,
1241+
.flags = KVM_PGTABLE_WALK_LEAF,
1242+
};
1243+
1244+
WARN_ON(kvm_pgtable_walk(pgt, addr, size, &walker));
1245+
return data.young;
12171246
}
12181247

12191248
int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,

arch/arm64/kvm/mmu.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,27 +1756,25 @@ bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
17561756
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
17571757
{
17581758
u64 size = (range->end - range->start) << PAGE_SHIFT;
1759-
kvm_pte_t kpte;
1760-
pte_t pte;
17611759

17621760
if (!kvm->arch.mmu.pgt)
17631761
return false;
17641762

1765-
WARN_ON(size != PAGE_SIZE && size != PMD_SIZE && size != PUD_SIZE);
1766-
1767-
kpte = kvm_pgtable_stage2_mkold(kvm->arch.mmu.pgt,
1768-
range->start << PAGE_SHIFT);
1769-
pte = __pte(kpte);
1770-
return pte_valid(pte) && pte_young(pte);
1763+
return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
1764+
range->start << PAGE_SHIFT,
1765+
size, true);
17711766
}
17721767

17731768
bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
17741769
{
1770+
u64 size = (range->end - range->start) << PAGE_SHIFT;
1771+
17751772
if (!kvm->arch.mmu.pgt)
17761773
return false;
17771774

1778-
return kvm_pgtable_stage2_is_young(kvm->arch.mmu.pgt,
1779-
range->start << PAGE_SHIFT);
1775+
return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
1776+
range->start << PAGE_SHIFT,
1777+
size, false);
17801778
}
17811779

17821780
phys_addr_t kvm_mmu_get_httbr(void)

0 commit comments

Comments
 (0)