Skip to content

Commit c75597c

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "s390: - Fix S390_USER_OPEREXEC so it can now be enabled regardless of other unrelated capabilities - Fix handling of the _PAGE_UNUSED pte bit that could lead to guest memory corruption in some scenarios - A bunch of misc gmap fixes (locking, behaviour under memory pressure) - Fix CMMA dirty tracking x86: - Tidy up some WARN_ON() and BUG_ON(), replacing them with WARN_ON_ONCE() or KVM_BUG_ON(). All of these have obviously never triggered, or somebody would have been annoyed earlier, but still... - Fix missing interrupt due to stale CR8 intercept - Add a statistic that can come in handy to debug leaks as well as the vulnerability to a class of recently-discovered issues - Do not ask arch/x86/kernel to export default_cpu_present_to_apicid() just for KVM" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (22 commits) x86/apic: KVM: Use cpu_physical_id() to get APIC ID of running vCPU for AVIC KVM: x86/mmu: Expose number of shadow MMU shadow pages as a stat KVM: x86: Unconditionally recompute CR8 intercept on PPR update KVM: VMX: Grab vmcs12 on CR8 interception update iff vCPU is in guest mode KVM: x86: WARN (once) if RTC pending EOI tracking goes off the rails KVM: x86: WARN and fail kvm_set_irq() if a PIC or I/O APIC vector is invalid KVM: x86: Bug the VM, not the kernel, if the ISR count {under,over}flows KVM: x86/mmu: Bug the VM, not the host kernel, if KVM write-protects upper SPTEs KVM: x86: Replace BUG_ON() with WARN_ON_ONCE() on "bad" nested GPA translation KVM: Replace guest-triggerable BUG_ON() in ioeventfd datamatch with get_unaligned() KVM: s390: Return failure in case of failure in kvm_s390_set_cmma_bits() KVM: s390: selftests: Fix cmma selftest KVM: s390: Fix cmma dirty tracking KVM: s390: Fix locking in kvm_s390_set_mem_control() KVM: s390: Fix handle_{sske,pfmf} under memory pressure KVM: s390: Fix code typo in gmap_protect_asce_top_level() KVM: s390: Do not set special large pages dirty KVM: s390: Fix dat_peek_cmma() overflow s390/mm: Fix handling of _PAGE_UNUSED pte bit KVM: s390: Fix typo in UCONTROL documentation ...
2 parents a142da0 + 098e32c commit c75597c

25 files changed

Lines changed: 265 additions & 85 deletions

File tree

Documentation/virt/kvm/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6840,7 +6840,7 @@ s390 specific.
68406840
} s390_ucontrol;
68416841

68426842
s390 specific. A page fault has occurred for a user controlled virtual
6843-
machine (KVM_VM_S390_UNCONTROL) on its host page table that cannot be
6843+
machine (KVM_VM_S390_UCONTROL) on its host page table that cannot be
68446844
resolved by the kernel.
68456845
The program code and the translation exception code that were placed
68466846
in the cpu's lowcore are presented here as defined by the z Architecture

arch/s390/include/asm/pgtable.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,8 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
980980

981981
static inline void set_pte(pte_t *ptep, pte_t pte)
982982
{
983+
if (pte_present(pte))
984+
pte = clear_pte_bit(pte, __pgprot(_PAGE_UNUSED));
983985
WRITE_ONCE(*ptep, pte);
984986
}
985987

@@ -1359,8 +1361,6 @@ pgprot_t pgprot_writecombine(pgprot_t prot);
13591361
static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
13601362
pte_t *ptep, pte_t entry, unsigned int nr)
13611363
{
1362-
if (pte_present(entry))
1363-
entry = clear_pte_bit(entry, __pgprot(_PAGE_UNUSED));
13641364
page_table_check_ptes_set(mm, addr, ptep, entry, nr);
13651365
for (;;) {
13661366
set_pte(ptep, entry);

arch/s390/kvm/dat.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ int dat_peek_cmma(gfn_t start, union asce asce, unsigned int *count, u8 *values)
12091209
int rc;
12101210

12111211
rc = _dat_walk_gfn_range(start, start + *count, asce, &ops, DAT_WALK_DEFAULT, &state);
1212-
*count = state.end - start;
1212+
*count = state.end >= start ? state.end - start : 0;
12131213
/* Return success if at least one value was saved, otherwise an error. */
12141214
return (rc == -EFAULT && *count > 0) ? 0 : rc;
12151215
}
@@ -1253,6 +1253,9 @@ int dat_get_cmma(union asce asce, gfn_t *start, unsigned int *count, u8 *values,
12531253
};
12541254

12551255
_dat_walk_gfn_range(*start, asce_end(asce), asce, &ops, DAT_WALK_IGN_HOLES, &state);
1256+
/* If no dirty pages were found, wrap around and continue searching */
1257+
if (*start && state.start == -1)
1258+
_dat_walk_gfn_range(0, *start, asce, &ops, DAT_WALK_IGN_HOLES, &state);
12561259

12571260
if (state.start == -1) {
12581261
*count = 0;

arch/s390/kvm/gmap.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ static long gmap_clear_young_crste(union crste *crstep, gfn_t gfn, gfn_t end, st
332332
new.h.i = 1;
333333
new.s.fc1.y = 0;
334334
new.s.fc1.prefix_notif = 0;
335-
if (new.s.fc1.d || !new.h.p)
335+
if ((new.s.fc1.d || !new.h.p) && !new.s.fc1.s)
336336
folio_set_dirty(phys_to_folio(crste_origin_large(crste)));
337337
new.s.fc1.d = 0;
338338
new.h.p = 1;
@@ -1098,23 +1098,46 @@ int gmap_protect_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gf
10981098
return 0;
10991099
}
11001100

1101+
static long __set_cmma_clean_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
1102+
{
1103+
union pgste pgste;
1104+
1105+
pgste = pgste_get_lock(ptep);
1106+
pgste.cmma_d = 0;
1107+
pgste_set_unlock(ptep, pgste);
1108+
1109+
if (need_resched())
1110+
return next;
1111+
return 0;
1112+
}
1113+
11011114
static long __set_cmma_dirty_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
11021115
{
1103-
__atomic64_or(PGSTE_CMMA_D_BIT, &pgste_of(ptep)->val);
1116+
union pgste pgste;
1117+
1118+
pgste = pgste_get_lock(ptep);
1119+
if (!pgste.cmma_d)
1120+
atomic64_inc(walk->priv);
1121+
pgste.cmma_d = 1;
1122+
pgste_set_unlock(ptep, pgste);
1123+
11041124
if (need_resched())
11051125
return next;
11061126
return 0;
11071127
}
11081128

1109-
void gmap_set_cmma_all_dirty(struct gmap *gmap)
1129+
void _gmap_set_cmma_all(struct gmap *gmap, bool dirty)
11101130
{
1111-
const struct dat_walk_ops ops = { .pte_entry = __set_cmma_dirty_pte, };
1131+
const struct dat_walk_ops ops = {
1132+
.pte_entry = dirty ? __set_cmma_dirty_pte : __set_cmma_clean_pte,
1133+
};
11121134
gfn_t gfn = 0;
11131135

11141136
do {
11151137
scoped_guard(read_lock, &gmap->kvm->mmu_lock)
11161138
gfn = _dat_walk_gfn_range(gfn, asce_end(gmap->asce), gmap->asce, &ops,
1117-
DAT_WALK_IGN_HOLES, NULL);
1139+
DAT_WALK_IGN_HOLES,
1140+
&gmap->kvm->arch.cmma_dirty_pages);
11181141
cond_resched();
11191142
} while (gfn);
11201143
}
@@ -1287,7 +1310,7 @@ static int gmap_protect_asce_top_level(struct kvm_s390_mmu_cache *mc, struct gma
12871310
/* Pairs with the smp_wmb() in kvm_mmu_invalidate_end(). */
12881311
smp_rmb();
12891312

1290-
rc = kvm_s390_get_guest_pages(sg->kvm, context.f, asce.rsto, asce.dt + 1, false);
1313+
rc = kvm_s390_get_guest_pages(sg->kvm, context.f, asce.rsto, asce.tl + 1, false);
12911314
if (rc > 0)
12921315
rc = -EFAULT;
12931316
if (!rc)

arch/s390/kvm/gmap.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ int gmap_insert_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gfn
104104
gfn_t r_gfn, int level);
105105
int gmap_protect_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gfn, gfn_t r_gfn,
106106
kvm_pfn_t pfn, int level, bool wr);
107-
void gmap_set_cmma_all_dirty(struct gmap *gmap);
107+
void _gmap_set_cmma_all(struct gmap *gmap, bool dirty);
108108
void _gmap_handle_vsie_unshadow_event(struct gmap *parent, gfn_t gfn);
109109
struct gmap *gmap_create_shadow(struct kvm_s390_mmu_cache *mc, struct gmap *gmap,
110110
union asce asce, int edat_level);
@@ -198,6 +198,16 @@ static inline bool pte_needs_unshadow(union pte oldpte, union pte newpte, union
198198
return !newpte.h.p || !newpte.s.pr;
199199
}
200200

201+
static inline void gmap_set_cmma_all_dirty(struct gmap *gmap)
202+
{
203+
_gmap_set_cmma_all(gmap, true);
204+
}
205+
206+
static inline void gmap_set_cmma_all_clean(struct gmap *gmap)
207+
{
208+
_gmap_set_cmma_all(gmap, false);
209+
}
210+
201211
static inline union pgste _gmap_ptep_xchg(struct gmap *gmap, union pte *ptep, union pte newpte,
202212
union pgste pgste, gfn_t gfn, bool needs_lock)
203213
{

arch/s390/kvm/kvm-s390.c

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,9 +1022,11 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
10221022
if (!kvm->arch.use_cmma)
10231023
break;
10241024

1025+
guard(mutex)(&kvm->lock);
10251026
VM_EVENT(kvm, 3, "%s", "RESET: CMMA states");
10261027
do {
1027-
start_gfn = dat_reset_cmma(kvm->arch.gmap->asce, start_gfn);
1028+
scoped_guard(read_lock, &kvm->mmu_lock)
1029+
start_gfn = dat_reset_cmma(kvm->arch.gmap->asce, start_gfn);
10281030
cond_resched();
10291031
} while (start_gfn);
10301032
ret = 0;
@@ -1217,13 +1219,13 @@ static void kvm_s390_sync_request_broadcast(struct kvm *kvm, int req)
12171219

12181220
/*
12191221
* Must be called with kvm->srcu held to avoid races on memslots, and with
1220-
* kvm->slots_lock to avoid races with ourselves and kvm_s390_vm_stop_migration.
1222+
* kvm->slots_lock to avoid races with ourselves, kvm_s390_vm_stop_migration(),
1223+
* and kvm_s390_get_cmma_bits().
12211224
*/
12221225
static int kvm_s390_vm_start_migration(struct kvm *kvm)
12231226
{
12241227
struct kvm_memory_slot *ms;
12251228
struct kvm_memslots *slots;
1226-
unsigned long ram_pages = 0;
12271229
int bkt;
12281230

12291231
/* migration mode already enabled */
@@ -1240,28 +1242,54 @@ static int kvm_s390_vm_start_migration(struct kvm *kvm)
12401242
kvm_for_each_memslot(ms, bkt, slots) {
12411243
if (!ms->dirty_bitmap)
12421244
return -EINVAL;
1243-
ram_pages += ms->npages;
12441245
}
1245-
/* mark all the pages as dirty */
1246-
gmap_set_cmma_all_dirty(kvm->arch.gmap);
1247-
atomic64_set(&kvm->arch.cmma_dirty_pages, ram_pages);
1248-
kvm->arch.migration_mode = 1;
1246+
/*
1247+
* Set the flag and let KVM handle ESSA manually, potentially setting
1248+
* the cmma_d bit in some PGSTEs and increasing cmma_dirty_pages.
1249+
* At this point cmma_dirty_pages is still 0, and all existing PGSTEs
1250+
* have their cmma_d bit set to 0.
1251+
* Any newly allocated page table has its entries marked as cmma-clean,
1252+
* which is fine because the CMMA values are not dirty.
1253+
*/
1254+
WRITE_ONCE(kvm->arch.migration_mode, 1);
12491255
kvm_s390_sync_request_broadcast(kvm, KVM_REQ_START_MIGRATION);
1256+
/*
1257+
* Mark all PGSTEs as cmma-dirty, increasing cmma_dirty_pages as needed,
1258+
* but without double-counting pages that have become dirty on their own
1259+
* in the meantime.
1260+
* At this point some pages might have become dirty on their own already
1261+
* and cmma_dirty_pages might therefore be non-zero.
1262+
*/
1263+
gmap_set_cmma_all_dirty(kvm->arch.gmap);
12501264
return 0;
12511265
}
12521266

12531267
/*
1254-
* Must be called with kvm->slots_lock to avoid races with ourselves and
1255-
* kvm_s390_vm_start_migration.
1268+
* Must be called with kvm->slots_lock to avoid races with ourselves,
1269+
* kvm_s390_vm_start_migration() and kvm_s390_get_cmma_bits().
12561270
*/
12571271
static int kvm_s390_vm_stop_migration(struct kvm *kvm)
12581272
{
12591273
/* migration mode already disabled */
12601274
if (!kvm->arch.migration_mode)
12611275
return 0;
1262-
kvm->arch.migration_mode = 0;
1276+
/*
1277+
* Unset the flag and propagate to all vCPUs. From now on the cmma_d
1278+
* bit will not be touched on any PGSTE.
1279+
* At this point cmma_dirty_pages is possibly non-zero, and thus some
1280+
* PGSTEs might have cmma_d set.
1281+
*/
1282+
WRITE_ONCE(kvm->arch.migration_mode, 0);
12631283
if (kvm->arch.use_cmma)
12641284
kvm_s390_sync_request_broadcast(kvm, KVM_REQ_STOP_MIGRATION);
1285+
/* Clear cmma_d on all existing PGSTEs and set cmma_dirty_pages to 0. */
1286+
gmap_set_cmma_all_clean(kvm->arch.gmap);
1287+
atomic64_set(&kvm->arch.cmma_dirty_pages, 0);
1288+
/*
1289+
* At this point the system has the expected state: migration_mode is 0,
1290+
* cmma_dirty_pages is 0, and all existing PGSTEs have their cmma_d bit
1291+
* set to 0.
1292+
*/
12651293
return 0;
12661294
}
12671295

@@ -2317,8 +2345,8 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm,
23172345
static int kvm_s390_set_cmma_bits(struct kvm *kvm,
23182346
const struct kvm_s390_cmma_log *args)
23192347
{
2320-
struct kvm_s390_mmu_cache *mc;
2321-
u8 *bits = NULL;
2348+
struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
2349+
u8 *bits __free(kvfree) = NULL;
23222350
int r = 0;
23232351

23242352
if (!kvm->arch.use_cmma)
@@ -2338,28 +2366,24 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm,
23382366
return -ENOMEM;
23392367
bits = vmalloc(array_size(sizeof(*bits), args->count));
23402368
if (!bits)
2341-
goto out;
2369+
return -ENOMEM;
23422370

23432371
r = copy_from_user(bits, (void __user *)args->values, args->count);
2344-
if (r) {
2345-
r = -EFAULT;
2346-
goto out;
2347-
}
2372+
if (r)
2373+
return -EFAULT;
23482374

23492375
do {
23502376
r = kvm_s390_mmu_cache_topup(mc);
23512377
if (r)
2352-
break;
2378+
return r;
23532379
scoped_guard(read_lock, &kvm->mmu_lock) {
23542380
r = dat_set_cmma_bits(mc, kvm->arch.gmap->asce, args->start_gfn,
23552381
args->count, args->mask, bits);
23562382
}
23572383
} while (r == -ENOMEM);
23582384

23592385
set_bit(GMAP_FLAG_USES_CMM, &kvm->arch.gmap->flags);
2360-
out:
2361-
kvm_s390_free_mmu_cache(mc);
2362-
vfree(bits);
2386+
23632387
return r;
23642388
}
23652389

@@ -3584,7 +3608,8 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
35843608
vcpu->arch.gmap = vcpu->kvm->arch.gmap;
35853609
sca_add_vcpu(vcpu);
35863610
}
3587-
if (test_kvm_facility(vcpu->kvm, 74) || vcpu->kvm->arch.user_instr0)
3611+
if (test_kvm_facility(vcpu->kvm, 74) || vcpu->kvm->arch.user_instr0 ||
3612+
vcpu->kvm->arch.user_operexec)
35883613
vcpu->arch.sie_block->ictl |= ICTL_OPEREXC;
35893614
}
35903615

arch/s390/kvm/priv.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,9 @@ static int handle_sske(struct kvm_vcpu *vcpu)
366366
if (rc > 1)
367367
return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
368368
if (rc == -ENOMEM) {
369-
kvm_s390_mmu_cache_topup(vcpu->arch.mc);
369+
rc = kvm_s390_mmu_cache_topup(vcpu->arch.mc);
370+
if (rc)
371+
return rc;
370372
continue;
371373
}
372374
if (rc < 0)
@@ -1122,7 +1124,9 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
11221124
if (rc > 1)
11231125
return kvm_s390_inject_program_int(vcpu, rc);
11241126
if (rc == -ENOMEM) {
1125-
kvm_s390_mmu_cache_topup(vcpu->arch.mc);
1127+
rc = kvm_s390_mmu_cache_topup(vcpu->arch.mc);
1128+
if (rc)
1129+
return rc;
11261130
continue;
11271131
}
11281132
if (rc < 0)
@@ -1232,7 +1236,7 @@ static int handle_essa(struct kvm_vcpu *vcpu)
12321236
: ESSA_SET_STABLE_IF_RESIDENT))
12331237
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
12341238

1235-
if (!vcpu->kvm->arch.migration_mode) {
1239+
if (!READ_ONCE(vcpu->kvm->arch.migration_mode)) {
12361240
/*
12371241
* CMMA is enabled in the KVM settings, but is disabled in
12381242
* the SIE block and in the mm_context, and we are not doing

arch/s390/mm/gmap_helpers.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ void gmap_helper_try_set_pte_unused(struct mm_struct *mm, unsigned long vmaddr)
181181
if (IS_ERR_OR_NULL(ptep))
182182
return;
183183

184-
__atomic64_or(_PAGE_UNUSED, (long *)ptep);
184+
if (pte_present(*ptep))
185+
__atomic64_or(_PAGE_UNUSED, (long *)ptep);
185186
pte_unmap_unlock(ptep, ptl);
186187
}
187188
EXPORT_SYMBOL_GPL(gmap_helper_try_set_pte_unused);

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,6 @@ enum kvm_mmu_type {
14341434
};
14351435

14361436
struct kvm_arch {
1437-
unsigned long n_used_mmu_pages;
14381437
unsigned long n_requested_mmu_pages;
14391438
unsigned long n_max_mmu_pages;
14401439
unsigned int indirect_shadow_pages;
@@ -1700,6 +1699,7 @@ struct kvm_vm_stat {
17001699
u64 mmu_recycled;
17011700
u64 mmu_cache_miss;
17021701
u64 mmu_unsync;
1702+
u64 mmu_shadow_pages;
17031703
union {
17041704
struct {
17051705
atomic64_t pages_4k;
@@ -2525,16 +2525,6 @@ static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
25252525
kvm_x86_call(vcpu_unblocking)(vcpu);
25262526
}
25272527

2528-
static inline int kvm_cpu_get_apicid(int mps_cpu)
2529-
{
2530-
#ifdef CONFIG_X86_LOCAL_APIC
2531-
return default_cpu_present_to_apicid(mps_cpu);
2532-
#else
2533-
WARN_ON_ONCE(1);
2534-
return BAD_APICID;
2535-
#endif
2536-
}
2537-
25382528
int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages);
25392529

25402530
#define KVM_CLOCK_VALID_FLAGS \

arch/x86/kernel/apic/apic_common.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ u32 default_cpu_present_to_apicid(int mps_cpu)
2626
else
2727
return BAD_APICID;
2828
}
29-
EXPORT_SYMBOL_FOR_KVM(default_cpu_present_to_apicid);
3029

3130
/*
3231
* Set up the logical destination ID when the APIC operates in logical

0 commit comments

Comments
 (0)