Skip to content

Commit 725d410

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm updates from Paolo Bonzini: "The bulk of the changes here is a largish change to guest_memfd, delaying the clearing and encryption of guest-private pages until they are actually added to guest page tables. This started as "let's make it impossible to misuse the API" for SEV-SNP; but then it ballooned a bit. The new logic is generally simpler and more ready for hugepage support in guest_memfd. Summary: - fix latent bug in how usage of large pages is determined for confidential VMs - fix "underline too short" in docs - eliminate log spam from limited APIC timer periods - disallow pre-faulting of memory before SEV-SNP VMs are initialized - delay clearing and encrypting private memory until it is added to guest page tables - this change also enables another small cleanup: the checks in SNP_LAUNCH_UPDATE that limit it to non-populated, private pages can now be moved in the common kvm_gmem_populate() function - fix compilation error that the RISC-V merge introduced in selftests" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86/mmu: fix determination of max NPT mapping level for private pages KVM: riscv: selftests: Fix compile error KVM: guest_memfd: abstract how prepared folios are recorded KVM: guest_memfd: let kvm_gmem_populate() operate only on private gfns KVM: extend kvm_range_has_memory_attributes() to check subset of attributes KVM: cleanup and add shortcuts to kvm_range_has_memory_attributes() KVM: guest_memfd: move check for already-populated page to common code KVM: remove kvm_arch_gmem_prepare_needed() KVM: guest_memfd: make kvm_gmem_prepare_folio() operate on a single struct kvm KVM: guest_memfd: delay kvm_gmem_prepare_folio() until the memory is passed to the guest KVM: guest_memfd: return locked folio from __kvm_gmem_get_pfn KVM: rename CONFIG_HAVE_KVM_GMEM_* to CONFIG_HAVE_KVM_ARCH_GMEM_* KVM: guest_memfd: do not go through struct page KVM: guest_memfd: delay folio_mark_uptodate() until after successful preparation KVM: guest_memfd: return folio from __kvm_gmem_get_pfn() KVM: x86: disallow pre-fault for SNP VMs before initialization KVM: Documentation: Fix title underline too short warning KVM: x86: Eliminate log spam from limited APIC timer periods
2 parents 948752d + 1773014 commit 725d410

File tree

13 files changed

+202
-147
lines changed

13 files changed

+202
-147
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6368,7 +6368,7 @@ a single guest_memfd file, but the bound ranges must not overlap).
63686368
See KVM_SET_USER_MEMORY_REGION2 for additional details.
63696369

63706370
4.143 KVM_PRE_FAULT_MEMORY
6371-
------------------------
6371+
---------------------------
63726372

63736373
:Capability: KVM_CAP_PRE_FAULT_MEMORY
63746374
:Architectures: none
@@ -6405,6 +6405,12 @@ for the current vCPU state. KVM maps memory as if the vCPU generated a
64056405
stage-2 read page fault, e.g. faults in memory as needed, but doesn't break
64066406
CoW. However, KVM does not mark any newly created stage-2 PTE as Accessed.
64076407

6408+
In the case of confidential VM types where there is an initial set up of
6409+
private guest memory before the guest is 'finalized'/measured, this ioctl
6410+
should only be issued after completing all the necessary setup to put the
6411+
guest into a 'finalized' state so that the above semantics can be reliably
6412+
ensured.
6413+
64086414
In some cases, multiple vCPUs might share the page tables. In this
64096415
case, the ioctl can be called in parallel.
64106416

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,7 @@ struct kvm_arch {
13051305
u8 vm_type;
13061306
bool has_private_mem;
13071307
bool has_protected_state;
1308+
bool pre_fault_allowed;
13081309
struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
13091310
struct list_head active_mmu_pages;
13101311
struct list_head zapped_obsolete_pages;

arch/x86/kvm/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ config KVM_AMD_SEV
141141
depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m)
142142
select ARCH_HAS_CC_PLATFORM
143143
select KVM_GENERIC_PRIVATE_MEM
144-
select HAVE_KVM_GMEM_PREPARE
145-
select HAVE_KVM_GMEM_INVALIDATE
144+
select HAVE_KVM_ARCH_GMEM_PREPARE
145+
select HAVE_KVM_ARCH_GMEM_INVALIDATE
146146
help
147147
Provides support for launching Encrypted VMs (SEV) and Encrypted VMs
148148
with Encrypted State (SEV-ES) on AMD processors.

arch/x86/kvm/lapic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,7 @@ static void limit_periodic_timer_frequency(struct kvm_lapic *apic)
17431743
s64 min_period = min_timer_period_us * 1000LL;
17441744

17451745
if (apic->lapic_timer.period < min_period) {
1746-
pr_info_ratelimited(
1746+
pr_info_once(
17471747
"vcpu %i: requested %lld ns "
17481748
"lapic timer period limited to %lld ns\n",
17491749
apic->vcpu->vcpu_id,

arch/x86/kvm/mmu/mmu.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,7 +4335,7 @@ static u8 kvm_max_private_mapping_level(struct kvm *kvm, kvm_pfn_t pfn,
43354335
if (req_max_level)
43364336
max_level = min(max_level, req_max_level);
43374337

4338-
return req_max_level;
4338+
return max_level;
43394339
}
43404340

43414341
static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
@@ -4743,6 +4743,9 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu,
47434743
u64 end;
47444744
int r;
47454745

4746+
if (!vcpu->kvm->arch.pre_fault_allowed)
4747+
return -EOPNOTSUPP;
4748+
47464749
/*
47474750
* reload is efficient when called repeatedly, so we can do it on
47484751
* every iteration.
@@ -7510,7 +7513,7 @@ static bool hugepage_has_attrs(struct kvm *kvm, struct kvm_memory_slot *slot,
75107513
const unsigned long end = start + KVM_PAGES_PER_HPAGE(level);
75117514

75127515
if (level == PG_LEVEL_2M)
7513-
return kvm_range_has_memory_attributes(kvm, start, end, attrs);
7516+
return kvm_range_has_memory_attributes(kvm, start, end, ~0, attrs);
75147517

75157518
for (gfn = start; gfn < end; gfn += KVM_PAGES_PER_HPAGE(level - 1)) {
75167519
if (hugepage_test_mixed(slot, gfn, level - 1) ||

arch/x86/kvm/svm/sev.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,18 +2279,11 @@ static int sev_gmem_post_populate(struct kvm *kvm, gfn_t gfn_start, kvm_pfn_t pf
22792279
bool assigned;
22802280
int level;
22812281

2282-
if (!kvm_mem_is_private(kvm, gfn)) {
2283-
pr_debug("%s: Failed to ensure GFN 0x%llx has private memory attribute set\n",
2284-
__func__, gfn);
2285-
ret = -EINVAL;
2286-
goto err;
2287-
}
2288-
22892282
ret = snp_lookup_rmpentry((u64)pfn + i, &assigned, &level);
22902283
if (ret || assigned) {
22912284
pr_debug("%s: Failed to ensure GFN 0x%llx RMP entry is initial shared state, ret: %d assigned: %d\n",
22922285
__func__, gfn, ret, assigned);
2293-
ret = -EINVAL;
2286+
ret = ret ? -EINVAL : -EEXIST;
22942287
goto err;
22952288
}
22962289

@@ -2549,6 +2542,14 @@ static int snp_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp)
25492542
data->gctx_paddr = __psp_pa(sev->snp_context);
25502543
ret = sev_issue_cmd(kvm, SEV_CMD_SNP_LAUNCH_FINISH, data, &argp->error);
25512544

2545+
/*
2546+
* Now that there will be no more SNP_LAUNCH_UPDATE ioctls, private pages
2547+
* can be given to the guest simply by marking the RMP entry as private.
2548+
* This can happen on first access and also with KVM_PRE_FAULT_MEMORY.
2549+
*/
2550+
if (!ret)
2551+
kvm->arch.pre_fault_allowed = true;
2552+
25522553
kfree(id_auth);
25532554

25542555
e_free_id_block:

arch/x86/kvm/svm/svm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4949,6 +4949,7 @@ static int svm_vm_init(struct kvm *kvm)
49494949
to_kvm_sev_info(kvm)->need_init = true;
49504950

49514951
kvm->arch.has_private_mem = (type == KVM_X86_SNP_VM);
4952+
kvm->arch.pre_fault_allowed = !kvm->arch.has_private_mem;
49524953
}
49534954

49544955
if (!pause_filter_count || !pause_filter_thresh)

arch/x86/kvm/x86.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12646,6 +12646,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
1264612646
kvm->arch.vm_type = type;
1264712647
kvm->arch.has_private_mem =
1264812648
(type == KVM_X86_SW_PROTECTED_VM);
12649+
/* Decided by the vendor code for other VM types. */
12650+
kvm->arch.pre_fault_allowed =
12651+
type == KVM_X86_DEFAULT_VM || type == KVM_X86_SW_PROTECTED_VM;
1264912652

1265012653
ret = kvm_page_track_init(kvm);
1265112654
if (ret)
@@ -13641,19 +13644,14 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
1364113644
}
1364213645
EXPORT_SYMBOL_GPL(kvm_arch_no_poll);
1364313646

13644-
#ifdef CONFIG_HAVE_KVM_GMEM_PREPARE
13645-
bool kvm_arch_gmem_prepare_needed(struct kvm *kvm)
13646-
{
13647-
return kvm->arch.vm_type == KVM_X86_SNP_VM;
13648-
}
13649-
13647+
#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_PREPARE
1365013648
int kvm_arch_gmem_prepare(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, int max_order)
1365113649
{
1365213650
return kvm_x86_call(gmem_prepare)(kvm, pfn, gfn, max_order);
1365313651
}
1365413652
#endif
1365513653

13656-
#ifdef CONFIG_HAVE_KVM_GMEM_INVALIDATE
13654+
#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
1365713655
void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end)
1365813656
{
1365913657
kvm_x86_call(gmem_invalidate)(start, end);

include/linux/kvm_host.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,7 +2414,7 @@ static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn_t gfn
24142414
}
24152415

24162416
bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
2417-
unsigned long attrs);
2417+
unsigned long mask, unsigned long attrs);
24182418
bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm,
24192419
struct kvm_gfn_range *range);
24202420
bool kvm_arch_post_set_memory_attributes(struct kvm *kvm,
@@ -2445,11 +2445,11 @@ static inline int kvm_gmem_get_pfn(struct kvm *kvm,
24452445
}
24462446
#endif /* CONFIG_KVM_PRIVATE_MEM */
24472447

2448-
#ifdef CONFIG_HAVE_KVM_GMEM_PREPARE
2448+
#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_PREPARE
24492449
int kvm_arch_gmem_prepare(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, int max_order);
2450-
bool kvm_arch_gmem_prepare_needed(struct kvm *kvm);
24512450
#endif
24522451

2452+
#ifdef CONFIG_KVM_GENERIC_PRIVATE_MEM
24532453
/**
24542454
* kvm_gmem_populate() - Populate/prepare a GPA range with guest data
24552455
*
@@ -2476,8 +2476,9 @@ typedef int (*kvm_gmem_populate_cb)(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
24762476

24772477
long kvm_gmem_populate(struct kvm *kvm, gfn_t gfn, void __user *src, long npages,
24782478
kvm_gmem_populate_cb post_populate, void *opaque);
2479+
#endif
24792480

2480-
#ifdef CONFIG_HAVE_KVM_GMEM_INVALIDATE
2481+
#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
24812482
void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end);
24822483
#endif
24832484

tools/testing/selftests/kvm/riscv/get-reg-list.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -961,10 +961,10 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zbkb, ZBKB);
961961
KVM_ISA_EXT_SIMPLE_CONFIG(zbkc, ZBKC);
962962
KVM_ISA_EXT_SIMPLE_CONFIG(zbkx, ZBKX);
963963
KVM_ISA_EXT_SIMPLE_CONFIG(zbs, ZBS);
964-
KVM_ISA_EXT_SIMPLE_CONFIG(zca, ZCA),
965-
KVM_ISA_EXT_SIMPLE_CONFIG(zcb, ZCB),
966-
KVM_ISA_EXT_SIMPLE_CONFIG(zcd, ZCD),
967-
KVM_ISA_EXT_SIMPLE_CONFIG(zcf, ZCF),
964+
KVM_ISA_EXT_SIMPLE_CONFIG(zca, ZCA);
965+
KVM_ISA_EXT_SIMPLE_CONFIG(zcb, ZCB);
966+
KVM_ISA_EXT_SIMPLE_CONFIG(zcd, ZCD);
967+
KVM_ISA_EXT_SIMPLE_CONFIG(zcf, ZCF);
968968
KVM_ISA_EXT_SIMPLE_CONFIG(zcmop, ZCMOP);
969969
KVM_ISA_EXT_SIMPLE_CONFIG(zfa, ZFA);
970970
KVM_ISA_EXT_SIMPLE_CONFIG(zfh, ZFH);

virt/kvm/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ config KVM_GENERIC_PRIVATE_MEM
113113
select KVM_PRIVATE_MEM
114114
bool
115115

116-
config HAVE_KVM_GMEM_PREPARE
116+
config HAVE_KVM_ARCH_GMEM_PREPARE
117117
bool
118118
depends on KVM_PRIVATE_MEM
119119

120-
config HAVE_KVM_GMEM_INVALIDATE
120+
config HAVE_KVM_ARCH_GMEM_INVALIDATE
121121
bool
122122
depends on KVM_PRIVATE_MEM

0 commit comments

Comments
 (0)