Skip to content

Commit 628e04d

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: "Bugfixes and strengthening the validity checks on inputs from new userspace APIs. Now I know why I shouldn't prepare pull requests on the weekend, it's hard to concentrate if your son is shouting about his latest Minecraft builds in your ear. Fortunately all the patches were ready and I just had to check the test results..." * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: SVM: Fix disable pause loop exit/pause filtering capability on SVM KVM: LAPIC: Prevent setting the tscdeadline timer if the lapic is hw disabled KVM: arm64: Don't inherit exec permission across page-table levels KVM: arm64: Prevent vcpu_has_ptrauth from generating OOL functions KVM: nVMX: check for invalid hdr.vmx.flags KVM: nVMX: check for required but missing VMCS12 in KVM_SET_NESTED_STATE selftests: kvm: do not set guest mode flag
2 parents ac3a0c8 + 830f01b commit 628e04d

File tree

7 files changed

+72
-24
lines changed

7 files changed

+72
-24
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,14 @@ struct kvm_vcpu_arch {
380380
#define vcpu_has_sve(vcpu) (system_supports_sve() && \
381381
((vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_SVE))
382382

383-
#define vcpu_has_ptrauth(vcpu) ((system_supports_address_auth() || \
384-
system_supports_generic_auth()) && \
385-
((vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_PTRAUTH))
383+
#ifdef CONFIG_ARM64_PTR_AUTH
384+
#define vcpu_has_ptrauth(vcpu) \
385+
((cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH) || \
386+
cpus_have_final_cap(ARM64_HAS_GENERIC_AUTH)) && \
387+
(vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_PTRAUTH)
388+
#else
389+
#define vcpu_has_ptrauth(vcpu) false
390+
#endif
386391

387392
#define vcpu_gp_regs(v) (&(v)->arch.ctxt.gp_regs)
388393

arch/arm64/kvm/mmu.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,7 +1326,7 @@ static bool stage2_get_leaf_entry(struct kvm *kvm, phys_addr_t addr,
13261326
return true;
13271327
}
13281328

1329-
static bool stage2_is_exec(struct kvm *kvm, phys_addr_t addr)
1329+
static bool stage2_is_exec(struct kvm *kvm, phys_addr_t addr, unsigned long sz)
13301330
{
13311331
pud_t *pudp;
13321332
pmd_t *pmdp;
@@ -1338,11 +1338,11 @@ static bool stage2_is_exec(struct kvm *kvm, phys_addr_t addr)
13381338
return false;
13391339

13401340
if (pudp)
1341-
return kvm_s2pud_exec(pudp);
1341+
return sz <= PUD_SIZE && kvm_s2pud_exec(pudp);
13421342
else if (pmdp)
1343-
return kvm_s2pmd_exec(pmdp);
1343+
return sz <= PMD_SIZE && kvm_s2pmd_exec(pmdp);
13441344
else
1345-
return kvm_s2pte_exec(ptep);
1345+
return sz == PAGE_SIZE && kvm_s2pte_exec(ptep);
13461346
}
13471347

13481348
static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
@@ -1958,7 +1958,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
19581958
* execute permissions, and we preserve whatever we have.
19591959
*/
19601960
needs_exec = exec_fault ||
1961-
(fault_status == FSC_PERM && stage2_is_exec(kvm, fault_ipa));
1961+
(fault_status == FSC_PERM &&
1962+
stage2_is_exec(kvm, fault_ipa, vma_pagesize));
19621963

19631964
if (vma_pagesize == PUD_SIZE) {
19641965
pud_t new_pud = kvm_pfn_pud(pfn, mem_type);

arch/x86/kvm/lapic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2195,7 +2195,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data)
21952195
{
21962196
struct kvm_lapic *apic = vcpu->arch.apic;
21972197

2198-
if (!lapic_in_kernel(vcpu) || apic_lvtt_oneshot(apic) ||
2198+
if (!kvm_apic_present(vcpu) || apic_lvtt_oneshot(apic) ||
21992199
apic_lvtt_period(apic))
22002200
return;
22012201

arch/x86/kvm/svm/svm.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ static void init_vmcb(struct vcpu_svm *svm)
10901090
svm->nested.vmcb = 0;
10911091
svm->vcpu.arch.hflags = 0;
10921092

1093-
if (pause_filter_count) {
1093+
if (!kvm_pause_in_guest(svm->vcpu.kvm)) {
10941094
control->pause_filter_count = pause_filter_count;
10951095
if (pause_filter_thresh)
10961096
control->pause_filter_thresh = pause_filter_thresh;
@@ -2693,7 +2693,7 @@ static int pause_interception(struct vcpu_svm *svm)
26932693
struct kvm_vcpu *vcpu = &svm->vcpu;
26942694
bool in_kernel = (svm_get_cpl(vcpu) == 0);
26952695

2696-
if (pause_filter_thresh)
2696+
if (!kvm_pause_in_guest(vcpu->kvm))
26972697
grow_ple_window(vcpu);
26982698

26992699
kvm_vcpu_on_spin(vcpu, in_kernel);
@@ -3780,7 +3780,7 @@ static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu)
37803780

37813781
static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu)
37823782
{
3783-
if (pause_filter_thresh)
3783+
if (!kvm_pause_in_guest(vcpu->kvm))
37843784
shrink_ple_window(vcpu);
37853785
}
37863786

@@ -3958,6 +3958,9 @@ static void svm_vm_destroy(struct kvm *kvm)
39583958

39593959
static int svm_vm_init(struct kvm *kvm)
39603960
{
3961+
if (!pause_filter_count || !pause_filter_thresh)
3962+
kvm->arch.pause_in_guest = true;
3963+
39613964
if (avic) {
39623965
int ret = avic_vm_init(kvm);
39633966
if (ret)

arch/x86/kvm/vmx/nested.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6079,6 +6079,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
60796079
~(KVM_STATE_NESTED_SMM_GUEST_MODE | KVM_STATE_NESTED_SMM_VMXON))
60806080
return -EINVAL;
60816081

6082+
if (kvm_state->hdr.vmx.flags & ~KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE)
6083+
return -EINVAL;
6084+
60826085
/*
60836086
* SMM temporarily disables VMX, so we cannot be in guest mode,
60846087
* nor can VMLAUNCH/VMRESUME be pending. Outside SMM, SMM flags
@@ -6108,9 +6111,16 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
61086111
if (ret)
61096112
return ret;
61106113

6111-
/* Empty 'VMXON' state is permitted */
6112-
if (kvm_state->size < sizeof(*kvm_state) + sizeof(*vmcs12))
6113-
return 0;
6114+
/* Empty 'VMXON' state is permitted if no VMCS loaded */
6115+
if (kvm_state->size < sizeof(*kvm_state) + sizeof(*vmcs12)) {
6116+
/* See vmx_has_valid_vmcs12. */
6117+
if ((kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE) ||
6118+
(kvm_state->flags & KVM_STATE_NESTED_EVMCS) ||
6119+
(kvm_state->hdr.vmx.vmcs12_pa != -1ull))
6120+
return -EINVAL;
6121+
else
6122+
return 0;
6123+
}
61146124

61156125
if (kvm_state->hdr.vmx.vmcs12_pa != -1ull) {
61166126
if (kvm_state->hdr.vmx.vmcs12_pa == kvm_state->hdr.vmx.vmxon_pa ||

arch/x86/kvm/vmx/nested.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ static inline struct vmcs12 *get_shadow_vmcs12(struct kvm_vcpu *vcpu)
4747
return to_vmx(vcpu)->nested.cached_shadow_vmcs12;
4848
}
4949

50+
/*
51+
* Note: the same condition is checked against the state provided by userspace
52+
* in vmx_set_nested_state; if it is satisfied, the nested state must include
53+
* the VMCS12.
54+
*/
5055
static inline int vmx_has_valid_vmcs12(struct kvm_vcpu *vcpu)
5156
{
5257
struct vcpu_vmx *vmx = to_vmx(vcpu);

tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,8 @@ void set_default_state(struct kvm_nested_state *state)
7676
void set_default_vmx_state(struct kvm_nested_state *state, int size)
7777
{
7878
memset(state, 0, size);
79-
state->flags = KVM_STATE_NESTED_GUEST_MODE |
80-
KVM_STATE_NESTED_RUN_PENDING;
8179
if (have_evmcs)
82-
state->flags |= KVM_STATE_NESTED_EVMCS;
80+
state->flags = KVM_STATE_NESTED_EVMCS;
8381
state->format = 0;
8482
state->size = size;
8583
state->hdr.vmx.vmxon_pa = 0x1000;
@@ -148,6 +146,11 @@ void test_vmx_nested_state(struct kvm_vm *vm)
148146
state->hdr.vmx.smm.flags = 1;
149147
test_nested_state_expect_einval(vm, state);
150148

149+
/* Invalid flags are rejected. */
150+
set_default_vmx_state(state, state_sz);
151+
state->hdr.vmx.flags = ~0;
152+
test_nested_state_expect_einval(vm, state);
153+
151154
/* It is invalid to have vmxon_pa == -1ull and vmcs_pa != -1ull. */
152155
set_default_vmx_state(state, state_sz);
153156
state->hdr.vmx.vmxon_pa = -1ull;
@@ -185,20 +188,41 @@ void test_vmx_nested_state(struct kvm_vm *vm)
185188
state->hdr.vmx.smm.flags = KVM_STATE_NESTED_SMM_GUEST_MODE;
186189
test_nested_state_expect_einval(vm, state);
187190

188-
/* Size must be large enough to fit kvm_nested_state and vmcs12. */
191+
/*
192+
* Size must be large enough to fit kvm_nested_state and vmcs12
193+
* if VMCS12 physical address is set
194+
*/
189195
set_default_vmx_state(state, state_sz);
190196
state->size = sizeof(*state);
197+
state->flags = 0;
198+
test_nested_state_expect_einval(vm, state);
199+
200+
set_default_vmx_state(state, state_sz);
201+
state->size = sizeof(*state);
202+
state->flags = 0;
203+
state->hdr.vmx.vmcs12_pa = -1;
191204
test_nested_state(vm, state);
192205

193-
/* vmxon_pa cannot be the same address as vmcs_pa. */
206+
/*
207+
* KVM_SET_NESTED_STATE succeeds with invalid VMCS
208+
* contents but L2 not running.
209+
*/
194210
set_default_vmx_state(state, state_sz);
195-
state->hdr.vmx.vmxon_pa = 0;
196-
state->hdr.vmx.vmcs12_pa = 0;
211+
state->flags = 0;
212+
test_nested_state(vm, state);
213+
214+
/* Invalid flags are rejected, even if no VMCS loaded. */
215+
set_default_vmx_state(state, state_sz);
216+
state->size = sizeof(*state);
217+
state->flags = 0;
218+
state->hdr.vmx.vmcs12_pa = -1;
219+
state->hdr.vmx.flags = ~0;
197220
test_nested_state_expect_einval(vm, state);
198221

199-
/* The revision id for vmcs12 must be VMCS12_REVISION. */
222+
/* vmxon_pa cannot be the same address as vmcs_pa. */
200223
set_default_vmx_state(state, state_sz);
201-
set_revision_id_for_vmcs12(state, 0);
224+
state->hdr.vmx.vmxon_pa = 0;
225+
state->hdr.vmx.vmcs12_pa = 0;
202226
test_nested_state_expect_einval(vm, state);
203227

204228
/*

0 commit comments

Comments
 (0)