Skip to content

Commit 90bf8d9

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull more kvm fixes from Paolo Bonzini: - Static analysis fix - New SEV-ES protocol for communicating invalid VMGEXIT requests - Ensure APICv is considered inactive if there is no APIC - Fix reserved bits for AMD PerfEvtSeln register * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: SVM: Do not terminate SEV-ES guests on GHCB validation failure KVM: SEV: Fall back to vmalloc for SEV-ES scratch area if necessary KVM: SEV: Return appropriate error codes if SEV-ES scratch setup fails KVM: x86/mmu: Retry page fault if root is invalidated by memslot update KVM: VMX: Set failure code in prepare_vmcs02() KVM: ensure APICv is considered inactive if there is no APIC KVM: x86/pmu: Fix reserved bits for AMD PerfEvtSeln register
2 parents 79a7216 + ad5b353 commit 90bf8d9

File tree

10 files changed

+106
-51
lines changed

10 files changed

+106
-51
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,7 @@ struct kvm_x86_msr_filter {
10361036
#define APICV_INHIBIT_REASON_PIT_REINJ 4
10371037
#define APICV_INHIBIT_REASON_X2APIC 5
10381038
#define APICV_INHIBIT_REASON_BLOCKIRQ 6
1039+
#define APICV_INHIBIT_REASON_ABSENT 7
10391040

10401041
struct kvm_arch {
10411042
unsigned long n_used_mmu_pages;

arch/x86/include/asm/sev-common.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,15 @@
7373

7474
#define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK)
7575

76+
/*
77+
* Error codes related to GHCB input that can be communicated back to the guest
78+
* by setting the lower 32-bits of the GHCB SW_EXITINFO1 field to 2.
79+
*/
80+
#define GHCB_ERR_NOT_REGISTERED 1
81+
#define GHCB_ERR_INVALID_USAGE 2
82+
#define GHCB_ERR_INVALID_SCRATCH_AREA 3
83+
#define GHCB_ERR_MISSING_INPUT 4
84+
#define GHCB_ERR_INVALID_INPUT 5
85+
#define GHCB_ERR_INVALID_EVENT 6
86+
7687
#endif

arch/x86/kvm/mmu/mmu.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,7 +1936,11 @@ static void mmu_audit_disable(void) { }
19361936

19371937
static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
19381938
{
1939-
return sp->role.invalid ||
1939+
if (sp->role.invalid)
1940+
return true;
1941+
1942+
/* TDP MMU pages due not use the MMU generation. */
1943+
return !sp->tdp_mmu_page &&
19401944
unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen);
19411945
}
19421946

@@ -3976,6 +3980,20 @@ static bool kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
39763980
return true;
39773981
}
39783982

3983+
/*
3984+
* Returns true if the page fault is stale and needs to be retried, i.e. if the
3985+
* root was invalidated by a memslot update or a relevant mmu_notifier fired.
3986+
*/
3987+
static bool is_page_fault_stale(struct kvm_vcpu *vcpu,
3988+
struct kvm_page_fault *fault, int mmu_seq)
3989+
{
3990+
if (is_obsolete_sp(vcpu->kvm, to_shadow_page(vcpu->arch.mmu->root_hpa)))
3991+
return true;
3992+
3993+
return fault->slot &&
3994+
mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva);
3995+
}
3996+
39793997
static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
39803998
{
39813999
bool is_tdp_mmu_fault = is_tdp_mmu(vcpu->arch.mmu);
@@ -4013,8 +4031,9 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
40134031
else
40144032
write_lock(&vcpu->kvm->mmu_lock);
40154033

4016-
if (fault->slot && mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva))
4034+
if (is_page_fault_stale(vcpu, fault, mmu_seq))
40174035
goto out_unlock;
4036+
40184037
r = make_mmu_pages_available(vcpu);
40194038
if (r)
40204039
goto out_unlock;

arch/x86/kvm/mmu/paging_tmpl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
911911

912912
r = RET_PF_RETRY;
913913
write_lock(&vcpu->kvm->mmu_lock);
914-
if (fault->slot && mmu_notifier_retry_hva(vcpu->kvm, mmu_seq, fault->hva))
914+
915+
if (is_page_fault_stale(vcpu, fault, mmu_seq))
915916
goto out_unlock;
916917

917918
kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT);

arch/x86/kvm/svm/avic.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,7 @@ int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
900900
bool svm_check_apicv_inhibit_reasons(ulong bit)
901901
{
902902
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
903+
BIT(APICV_INHIBIT_REASON_ABSENT) |
903904
BIT(APICV_INHIBIT_REASON_HYPERV) |
904905
BIT(APICV_INHIBIT_REASON_NESTED) |
905906
BIT(APICV_INHIBIT_REASON_IRQWIN) |

arch/x86/kvm/svm/pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
281281
pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS;
282282

283283
pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1;
284-
pmu->reserved_bits = 0xffffffff00200000ull;
284+
pmu->reserved_bits = 0xfffffff000280000ull;
285285
pmu->version = 1;
286286
/* not applicable to AMD; but clean them to prevent any fall out */
287287
pmu->counter_bitmask[KVM_PMC_FIXED] = 0;

arch/x86/kvm/svm/sev.c

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2260,7 +2260,7 @@ void sev_free_vcpu(struct kvm_vcpu *vcpu)
22602260
__free_page(virt_to_page(svm->sev_es.vmsa));
22612261

22622262
if (svm->sev_es.ghcb_sa_free)
2263-
kfree(svm->sev_es.ghcb_sa);
2263+
kvfree(svm->sev_es.ghcb_sa);
22642264
}
22652265

22662266
static void dump_ghcb(struct vcpu_svm *svm)
@@ -2352,24 +2352,29 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
23522352
memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
23532353
}
23542354

2355-
static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
2355+
static bool sev_es_validate_vmgexit(struct vcpu_svm *svm)
23562356
{
23572357
struct kvm_vcpu *vcpu;
23582358
struct ghcb *ghcb;
2359-
u64 exit_code = 0;
2359+
u64 exit_code;
2360+
u64 reason;
23602361

23612362
ghcb = svm->sev_es.ghcb;
23622363

2363-
/* Only GHCB Usage code 0 is supported */
2364-
if (ghcb->ghcb_usage)
2365-
goto vmgexit_err;
2366-
23672364
/*
2368-
* Retrieve the exit code now even though is may not be marked valid
2365+
* Retrieve the exit code now even though it may not be marked valid
23692366
* as it could help with debugging.
23702367
*/
23712368
exit_code = ghcb_get_sw_exit_code(ghcb);
23722369

2370+
/* Only GHCB Usage code 0 is supported */
2371+
if (ghcb->ghcb_usage) {
2372+
reason = GHCB_ERR_INVALID_USAGE;
2373+
goto vmgexit_err;
2374+
}
2375+
2376+
reason = GHCB_ERR_MISSING_INPUT;
2377+
23732378
if (!ghcb_sw_exit_code_is_valid(ghcb) ||
23742379
!ghcb_sw_exit_info_1_is_valid(ghcb) ||
23752380
!ghcb_sw_exit_info_2_is_valid(ghcb))
@@ -2448,30 +2453,34 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
24482453
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
24492454
break;
24502455
default:
2456+
reason = GHCB_ERR_INVALID_EVENT;
24512457
goto vmgexit_err;
24522458
}
24532459

2454-
return 0;
2460+
return true;
24552461

24562462
vmgexit_err:
24572463
vcpu = &svm->vcpu;
24582464

2459-
if (ghcb->ghcb_usage) {
2465+
if (reason == GHCB_ERR_INVALID_USAGE) {
24602466
vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n",
24612467
ghcb->ghcb_usage);
2468+
} else if (reason == GHCB_ERR_INVALID_EVENT) {
2469+
vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is not valid\n",
2470+
exit_code);
24622471
} else {
2463-
vcpu_unimpl(vcpu, "vmgexit: exit reason %#llx is not valid\n",
2472+
vcpu_unimpl(vcpu, "vmgexit: exit code %#llx input is not valid\n",
24642473
exit_code);
24652474
dump_ghcb(svm);
24662475
}
24672476

2468-
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
2469-
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON;
2470-
vcpu->run->internal.ndata = 2;
2471-
vcpu->run->internal.data[0] = exit_code;
2472-
vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu;
2477+
/* Clear the valid entries fields */
2478+
memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
2479+
2480+
ghcb_set_sw_exit_info_1(ghcb, 2);
2481+
ghcb_set_sw_exit_info_2(ghcb, reason);
24732482

2474-
return -EINVAL;
2483+
return false;
24752484
}
24762485

24772486
void sev_es_unmap_ghcb(struct vcpu_svm *svm)
@@ -2493,7 +2502,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
24932502
svm->sev_es.ghcb_sa_sync = false;
24942503
}
24952504

2496-
kfree(svm->sev_es.ghcb_sa);
2505+
kvfree(svm->sev_es.ghcb_sa);
24972506
svm->sev_es.ghcb_sa = NULL;
24982507
svm->sev_es.ghcb_sa_free = false;
24992508
}
@@ -2541,14 +2550,14 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
25412550
scratch_gpa_beg = ghcb_get_sw_scratch(ghcb);
25422551
if (!scratch_gpa_beg) {
25432552
pr_err("vmgexit: scratch gpa not provided\n");
2544-
return false;
2553+
goto e_scratch;
25452554
}
25462555

25472556
scratch_gpa_end = scratch_gpa_beg + len;
25482557
if (scratch_gpa_end < scratch_gpa_beg) {
25492558
pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n",
25502559
len, scratch_gpa_beg);
2551-
return false;
2560+
goto e_scratch;
25522561
}
25532562

25542563
if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) {
@@ -2566,7 +2575,7 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
25662575
scratch_gpa_end > ghcb_scratch_end) {
25672576
pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n",
25682577
scratch_gpa_beg, scratch_gpa_end);
2569-
return false;
2578+
goto e_scratch;
25702579
}
25712580

25722581
scratch_va = (void *)svm->sev_es.ghcb;
@@ -2579,18 +2588,18 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
25792588
if (len > GHCB_SCRATCH_AREA_LIMIT) {
25802589
pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n",
25812590
len, GHCB_SCRATCH_AREA_LIMIT);
2582-
return false;
2591+
goto e_scratch;
25832592
}
2584-
scratch_va = kzalloc(len, GFP_KERNEL_ACCOUNT);
2593+
scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);
25852594
if (!scratch_va)
2586-
return false;
2595+
goto e_scratch;
25872596

25882597
if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) {
25892598
/* Unable to copy scratch area from guest */
25902599
pr_err("vmgexit: kvm_read_guest for scratch area failed\n");
25912600

2592-
kfree(scratch_va);
2593-
return false;
2601+
kvfree(scratch_va);
2602+
goto e_scratch;
25942603
}
25952604

25962605
/*
@@ -2607,6 +2616,12 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
26072616
svm->sev_es.ghcb_sa_len = len;
26082617

26092618
return true;
2619+
2620+
e_scratch:
2621+
ghcb_set_sw_exit_info_1(ghcb, 2);
2622+
ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_SCRATCH_AREA);
2623+
2624+
return false;
26102625
}
26112626

26122627
static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask,
@@ -2657,7 +2672,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
26572672

26582673
ret = svm_invoke_exit_handler(vcpu, SVM_EXIT_CPUID);
26592674
if (!ret) {
2660-
ret = -EINVAL;
2675+
/* Error, keep GHCB MSR value as-is */
26612676
break;
26622677
}
26632678

@@ -2693,10 +2708,13 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
26932708
GHCB_MSR_TERM_REASON_POS);
26942709
pr_info("SEV-ES guest requested termination: %#llx:%#llx\n",
26952710
reason_set, reason_code);
2696-
fallthrough;
2711+
2712+
ret = -EINVAL;
2713+
break;
26972714
}
26982715
default:
2699-
ret = -EINVAL;
2716+
/* Error, keep GHCB MSR value as-is */
2717+
break;
27002718
}
27012719

27022720
trace_kvm_vmgexit_msr_protocol_exit(svm->vcpu.vcpu_id,
@@ -2720,14 +2738,18 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
27202738

27212739
if (!ghcb_gpa) {
27222740
vcpu_unimpl(vcpu, "vmgexit: GHCB gpa is not set\n");
2723-
return -EINVAL;
2741+
2742+
/* Without a GHCB, just return right back to the guest */
2743+
return 1;
27242744
}
27252745

27262746
if (kvm_vcpu_map(vcpu, ghcb_gpa >> PAGE_SHIFT, &svm->sev_es.ghcb_map)) {
27272747
/* Unable to map GHCB from guest */
27282748
vcpu_unimpl(vcpu, "vmgexit: error mapping GHCB [%#llx] from guest\n",
27292749
ghcb_gpa);
2730-
return -EINVAL;
2750+
2751+
/* Without a GHCB, just return right back to the guest */
2752+
return 1;
27312753
}
27322754

27332755
svm->sev_es.ghcb = svm->sev_es.ghcb_map.hva;
@@ -2737,15 +2759,14 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
27372759

27382760
exit_code = ghcb_get_sw_exit_code(ghcb);
27392761

2740-
ret = sev_es_validate_vmgexit(svm);
2741-
if (ret)
2742-
return ret;
2762+
if (!sev_es_validate_vmgexit(svm))
2763+
return 1;
27432764

27442765
sev_es_sync_from_ghcb(svm);
27452766
ghcb_set_sw_exit_info_1(ghcb, 0);
27462767
ghcb_set_sw_exit_info_2(ghcb, 0);
27472768

2748-
ret = -EINVAL;
2769+
ret = 1;
27492770
switch (exit_code) {
27502771
case SVM_VMGEXIT_MMIO_READ:
27512772
if (!setup_vmgexit_scratch(svm, true, control->exit_info_2))
@@ -2786,20 +2807,17 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
27862807
default:
27872808
pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n",
27882809
control->exit_info_1);
2789-
ghcb_set_sw_exit_info_1(ghcb, 1);
2790-
ghcb_set_sw_exit_info_2(ghcb,
2791-
X86_TRAP_UD |
2792-
SVM_EVTINJ_TYPE_EXEPT |
2793-
SVM_EVTINJ_VALID);
2810+
ghcb_set_sw_exit_info_1(ghcb, 2);
2811+
ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_INPUT);
27942812
}
27952813

2796-
ret = 1;
27972814
break;
27982815
}
27992816
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
28002817
vcpu_unimpl(vcpu,
28012818
"vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n",
28022819
control->exit_info_1, control->exit_info_2);
2820+
ret = -EINVAL;
28032821
break;
28042822
default:
28052823
ret = svm_invoke_exit_handler(vcpu, exit_code);
@@ -2821,7 +2839,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
28212839
return -EINVAL;
28222840

28232841
if (!setup_vmgexit_scratch(svm, in, bytes))
2824-
return -EINVAL;
2842+
return 1;
28252843

28262844
return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->sev_es.ghcb_sa,
28272845
count, in);

arch/x86/kvm/vmx/nested.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2591,8 +2591,10 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
25912591

25922592
if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) &&
25932593
WARN_ON_ONCE(kvm_set_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL,
2594-
vmcs12->guest_ia32_perf_global_ctrl)))
2594+
vmcs12->guest_ia32_perf_global_ctrl))) {
2595+
*entry_failure_code = ENTRY_FAIL_DEFAULT;
25952596
return -EINVAL;
2597+
}
25962598

25972599
kvm_rsp_write(vcpu, vmcs12->guest_rsp);
25982600
kvm_rip_write(vcpu, vmcs12->guest_rip);

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7525,6 +7525,7 @@ static void hardware_unsetup(void)
75257525
static bool vmx_check_apicv_inhibit_reasons(ulong bit)
75267526
{
75277527
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
7528+
BIT(APICV_INHIBIT_REASON_ABSENT) |
75287529
BIT(APICV_INHIBIT_REASON_HYPERV) |
75297530
BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
75307531

0 commit comments

Comments
 (0)