Skip to content

Commit 73d7cf0

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: "Many patches, pretty much all of them small, that accumulated while I was on vacation. ARM: - Remove the last leftovers of the ill-fated FPSIMD host state mapping at EL2 stage-1 - Fix unexpected advertisement to the guest of unimplemented S2 base granule sizes - Gracefully fail initialising pKVM if the interrupt controller isn't GICv3 - Also gracefully fail initialising pKVM if the carveout allocation fails - Fix the computing of the minimum MMIO range required for the host on stage-2 fault - Fix the generation of the GICv3 Maintenance Interrupt in nested mode x86: - Reject SEV{-ES} intra-host migration if one or more vCPUs are actively being created, so as not to create a non-SEV{-ES} vCPU in an SEV{-ES} VM - Use a pre-allocated, per-vCPU buffer for handling de-sparsification of vCPU masks in Hyper-V hypercalls; fixes a "stack frame too large" issue - Allow out-of-range/invalid Xen event channel ports when configuring IRQ routing, to avoid dictating a specific ioctl() ordering to userspace - Conditionally reschedule when setting memory attributes to avoid soft lockups when userspace converts huge swaths of memory to/from private - Add back MWAIT as a required feature for the MONITOR/MWAIT selftest - Add a missing field in struct sev_data_snp_launch_start that resulted in the guest-visible workarounds field being filled at the wrong offset - Skip non-canonical address when processing Hyper-V PV TLB flushes to avoid VM-Fail on INVVPID - Advertise supported TDX TDVMCALLs to userspace - Pass SetupEventNotifyInterrupt arguments to userspace - Fix TSC frequency underflow" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86: avoid underflow when scaling TSC frequency KVM: arm64: Remove kvm_arch_vcpu_run_map_fp() KVM: arm64: Fix handling of FEAT_GTG for unimplemented granule sizes KVM: arm64: Don't free hyp pages with pKVM on GICv2 KVM: arm64: Fix error path in init_hyp_mode() KVM: arm64: Adjust range correctly during host stage-2 faults KVM: arm64: nv: Fix MI line level calculation in vgic_v3_nested_update_mi() KVM: x86/hyper-v: Skip non-canonical addresses during PV TLB flush KVM: SVM: Add missing member in SNP_LAUNCH_START command structure Documentation: KVM: Fix unexpected unindent warnings KVM: selftests: Add back the missing check of MONITOR/MWAIT availability KVM: Allow CPU to reschedule while setting per-page memory attributes KVM: x86/xen: Allow 'out of range' event channel ports in IRQ routing table. KVM: x86/hyper-v: Use preallocated per-vCPU buffer for de-sparsified vCPU masks KVM: SVM: Initialize vmsa_pa in VMCB to INVALID_PAGE if VMSA page is NULL KVM: SVM: Reject SEV{-ES} intra host migration if vCPU creation is in-flight KVM: TDX: Report supported optional TDVMCALLs in TDX capabilities KVM: TDX: Exit to userspace for SetupEventNotifyInterrupt
2 parents 8c2e52e + 4578a74 commit 73d7cf0

File tree

20 files changed

+166
-71
lines changed

20 files changed

+166
-71
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7196,6 +7196,10 @@ The valid value for 'flags' is:
71967196
u64 leaf;
71977197
u64 r11, r12, r13, r14;
71987198
} get_tdvmcall_info;
7199+
struct {
7200+
u64 ret;
7201+
u64 vector;
7202+
} setup_event_notify;
71997203
};
72007204
} tdx;
72017205

@@ -7210,21 +7214,24 @@ number from register R11. The remaining field of the union provide the
72107214
inputs and outputs of the TDVMCALL. Currently the following values of
72117215
``nr`` are defined:
72127216

7213-
* ``TDVMCALL_GET_QUOTE``: the guest has requested to generate a TD-Quote
7214-
signed by a service hosting TD-Quoting Enclave operating on the host.
7215-
Parameters and return value are in the ``get_quote`` field of the union.
7216-
The ``gpa`` field and ``size`` specify the guest physical address
7217-
(without the shared bit set) and the size of a shared-memory buffer, in
7218-
which the TDX guest passes a TD Report. The ``ret`` field represents
7219-
the return value of the GetQuote request. When the request has been
7220-
queued successfully, the TDX guest can poll the status field in the
7221-
shared-memory area to check whether the Quote generation is completed or
7222-
not. When completed, the generated Quote is returned via the same buffer.
7223-
7224-
* ``TDVMCALL_GET_TD_VM_CALL_INFO``: the guest has requested the support
7225-
status of TDVMCALLs. The output values for the given leaf should be
7226-
placed in fields from ``r11`` to ``r14`` of the ``get_tdvmcall_info``
7227-
field of the union.
7217+
* ``TDVMCALL_GET_QUOTE``: the guest has requested to generate a TD-Quote
7218+
signed by a service hosting TD-Quoting Enclave operating on the host.
7219+
Parameters and return value are in the ``get_quote`` field of the union.
7220+
The ``gpa`` field and ``size`` specify the guest physical address
7221+
(without the shared bit set) and the size of a shared-memory buffer, in
7222+
which the TDX guest passes a TD Report. The ``ret`` field represents
7223+
the return value of the GetQuote request. When the request has been
7224+
queued successfully, the TDX guest can poll the status field in the
7225+
shared-memory area to check whether the Quote generation is completed or
7226+
not. When completed, the generated Quote is returned via the same buffer.
7227+
7228+
* ``TDVMCALL_GET_TD_VM_CALL_INFO``: the guest has requested the support
7229+
status of TDVMCALLs. The output values for the given leaf should be
7230+
placed in fields from ``r11`` to ``r14`` of the ``get_tdvmcall_info``
7231+
field of the union.
7232+
7233+
* ``TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT``: the guest has requested to
7234+
set up a notification interrupt for vector ``vector``.
72287235

72297236
KVM may add support for more values in the future that may cause a userspace
72307237
exit, even without calls to ``KVM_ENABLE_CAP`` or similar. In this case,

Documentation/virt/kvm/x86/intel-tdx.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,20 @@ to be configured to the TDX guest.
7979
struct kvm_tdx_capabilities {
8080
__u64 supported_attrs;
8181
__u64 supported_xfam;
82-
__u64 reserved[254];
82+
83+
/* TDG.VP.VMCALL hypercalls executed in kernel and forwarded to
84+
* userspace, respectively
85+
*/
86+
__u64 kernel_tdvmcallinfo_1_r11;
87+
__u64 user_tdvmcallinfo_1_r11;
88+
89+
/* TDG.VP.VMCALL instruction executions subfunctions executed in kernel
90+
* and forwarded to userspace, respectively
91+
*/
92+
__u64 kernel_tdvmcallinfo_1_r12;
93+
__u64 user_tdvmcallinfo_1_r12;
94+
95+
__u64 reserved[250];
8396

8497
/* Configurable CPUID bits for userspace */
8598
struct kvm_cpuid2 cpuid;

arch/arm64/include/asm/kvm_host.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1480,7 +1480,6 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm,
14801480
struct reg_mask_range *range);
14811481

14821482
/* Guest/host FPSIMD coordination helpers */
1483-
int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
14841483
void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
14851484
void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu);
14861485
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);

arch/arm64/kvm/arm.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -825,10 +825,6 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
825825
if (!kvm_arm_vcpu_is_finalized(vcpu))
826826
return -EPERM;
827827

828-
ret = kvm_arch_vcpu_run_map_fp(vcpu);
829-
if (ret)
830-
return ret;
831-
832828
if (likely(vcpu_has_run_once(vcpu)))
833829
return 0;
834830

@@ -2129,7 +2125,7 @@ static void cpu_hyp_init(void *discard)
21292125

21302126
static void cpu_hyp_uninit(void *discard)
21312127
{
2132-
if (__this_cpu_read(kvm_hyp_initialized)) {
2128+
if (!is_protected_kvm_enabled() && __this_cpu_read(kvm_hyp_initialized)) {
21332129
cpu_hyp_reset();
21342130
__this_cpu_write(kvm_hyp_initialized, 0);
21352131
}
@@ -2345,15 +2341,23 @@ static void __init teardown_hyp_mode(void)
23452341

23462342
free_hyp_pgds();
23472343
for_each_possible_cpu(cpu) {
2344+
if (per_cpu(kvm_hyp_initialized, cpu))
2345+
continue;
2346+
23482347
free_pages(per_cpu(kvm_arm_hyp_stack_base, cpu), NVHE_STACK_SHIFT - PAGE_SHIFT);
2349-
free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());
2348+
2349+
if (!kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu])
2350+
continue;
23502351

23512352
if (free_sve) {
23522353
struct cpu_sve_state *sve_state;
23532354

23542355
sve_state = per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state;
23552356
free_pages((unsigned long) sve_state, pkvm_host_sve_state_order());
23562357
}
2358+
2359+
free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());
2360+
23572361
}
23582362
}
23592363

arch/arm64/kvm/fpsimd.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,6 @@
1414
#include <asm/kvm_mmu.h>
1515
#include <asm/sysreg.h>
1616

17-
/*
18-
* Called on entry to KVM_RUN unless this vcpu previously ran at least
19-
* once and the most recent prior KVM_RUN for this vcpu was called from
20-
* the same task as current (highly likely).
21-
*
22-
* This is guaranteed to execute before kvm_arch_vcpu_load_fp(vcpu),
23-
* such that on entering hyp the relevant parts of current are already
24-
* mapped.
25-
*/
26-
int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
27-
{
28-
struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
29-
int ret;
30-
31-
/* pKVM has its own tracking of the host fpsimd state. */
32-
if (is_protected_kvm_enabled())
33-
return 0;
34-
35-
/* Make sure the host task fpsimd state is visible to hyp: */
36-
ret = kvm_share_hyp(fpsimd, fpsimd + 1);
37-
if (ret)
38-
return ret;
39-
40-
return 0;
41-
}
42-
4317
/*
4418
* Prepare vcpu for saving the host's FPSIMD state and loading the guest's.
4519
* The actual loading is done by the FPSIMD access trap taken to hyp.

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
479479
{
480480
struct kvm_mem_range cur;
481481
kvm_pte_t pte;
482+
u64 granule;
482483
s8 level;
483484
int ret;
484485

@@ -496,18 +497,21 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
496497
return -EPERM;
497498
}
498499

499-
do {
500-
u64 granule = kvm_granule_size(level);
500+
for (; level <= KVM_PGTABLE_LAST_LEVEL; level++) {
501+
if (!kvm_level_supports_block_mapping(level))
502+
continue;
503+
granule = kvm_granule_size(level);
501504
cur.start = ALIGN_DOWN(addr, granule);
502505
cur.end = cur.start + granule;
503-
level++;
504-
} while ((level <= KVM_PGTABLE_LAST_LEVEL) &&
505-
!(kvm_level_supports_block_mapping(level) &&
506-
range_included(&cur, range)));
506+
if (!range_included(&cur, range))
507+
continue;
508+
*range = cur;
509+
return 0;
510+
}
507511

508-
*range = cur;
512+
WARN_ON(1);
509513

510-
return 0;
514+
return -EINVAL;
511515
}
512516

513517
int host_stage2_idmap_locked(phys_addr_t addr, u64 size,

arch/arm64/kvm/nested.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,21 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
14021402
}
14031403
}
14041404

1405+
#define has_tgran_2(__r, __sz) \
1406+
({ \
1407+
u64 _s1, _s2, _mmfr0 = __r; \
1408+
\
1409+
_s2 = SYS_FIELD_GET(ID_AA64MMFR0_EL1, \
1410+
TGRAN##__sz##_2, _mmfr0); \
1411+
\
1412+
_s1 = SYS_FIELD_GET(ID_AA64MMFR0_EL1, \
1413+
TGRAN##__sz, _mmfr0); \
1414+
\
1415+
((_s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_NI && \
1416+
_s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz) || \
1417+
(_s2 == ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz && \
1418+
_s1 != ID_AA64MMFR0_EL1_TGRAN##__sz##_NI)); \
1419+
})
14051420
/*
14061421
* Our emulated CPU doesn't support all the possible features. For the
14071422
* sake of simplicity (and probably mental sanity), wipe out a number
@@ -1411,6 +1426,8 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
14111426
*/
14121427
u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val)
14131428
{
1429+
u64 orig_val = val;
1430+
14141431
switch (reg) {
14151432
case SYS_ID_AA64ISAR0_EL1:
14161433
/* Support everything but TME */
@@ -1480,13 +1497,16 @@ u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val)
14801497
*/
14811498
switch (PAGE_SIZE) {
14821499
case SZ_4K:
1483-
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN4_2, IMP);
1500+
if (has_tgran_2(orig_val, 4))
1501+
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN4_2, IMP);
14841502
fallthrough;
14851503
case SZ_16K:
1486-
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN16_2, IMP);
1504+
if (has_tgran_2(orig_val, 16))
1505+
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN16_2, IMP);
14871506
fallthrough;
14881507
case SZ_64K:
1489-
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN64_2, IMP);
1508+
if (has_tgran_2(orig_val, 64))
1509+
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN64_2, IMP);
14901510
break;
14911511
}
14921512

arch/arm64/kvm/vgic/vgic-v3-nested.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,7 @@ void vgic_v3_nested_update_mi(struct kvm_vcpu *vcpu)
401401
{
402402
bool level;
403403

404-
level = __vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En;
405-
if (level)
406-
level &= vgic_v3_get_misr(vcpu);
404+
level = (__vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EL2_En) && vgic_v3_get_misr(vcpu);
407405
kvm_vgic_inject_irq(vcpu->kvm, vcpu,
408406
vcpu->kvm->arch.vgic.mi_intid, level, vcpu);
409407
}

arch/x86/include/asm/kvm_host.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,13 @@ struct kvm_vcpu_hv {
700700

701701
struct kvm_vcpu_hv_tlb_flush_fifo tlb_flush_fifo[HV_NR_TLB_FLUSH_FIFOS];
702702

703-
/* Preallocated buffer for handling hypercalls passing sparse vCPU set */
703+
/*
704+
* Preallocated buffers for handling hypercalls that pass sparse vCPU
705+
* sets (for high vCPU counts, they're too large to comfortably fit on
706+
* the stack).
707+
*/
704708
u64 sparse_banks[HV_MAX_SPARSE_VCPU_BANKS];
709+
DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS);
705710

706711
struct hv_vp_assist_page vp_assist_page;
707712

arch/x86/include/asm/shared/tdx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
#define TDVMCALL_MAP_GPA 0x10001
7373
#define TDVMCALL_GET_QUOTE 0x10002
7474
#define TDVMCALL_REPORT_FATAL_ERROR 0x10003
75+
#define TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT 0x10004ULL
7576

7677
/*
7778
* TDG.VP.VMCALL Status Codes (returned in R10)

0 commit comments

Comments
 (0)