Skip to content

Commit fd0aa1a

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "Miscellaneous bugfixes. The main interesting one is a NULL pointer dereference reported by syzkaller ("KVM: x86: Immediately reset the MMU context when the SMM flag is cleared")" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: selftests: Fix kvm_check_cap() assertion KVM: x86/mmu: Calculate and check "full" mmu_role for nested MMU KVM: X86: Fix x86_emulator slab cache leak KVM: SVM: Call SEV Guest Decommission if ASID binding fails KVM: x86: Immediately reset the MMU context when the SMM flag is cleared KVM: x86: Fix fall-through warnings for Clang KVM: SVM: fix doc warnings KVM: selftests: Fix compiling errors when initializing the static structure kvm: LAPIC: Restore guard to prevent illegal APIC register access
2 parents 39519f6 + d8ac05e commit fd0aa1a

File tree

9 files changed

+73
-30
lines changed

9 files changed

+73
-30
lines changed

arch/x86/kvm/cpuid.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ static int __do_cpuid_func_emulated(struct kvm_cpuid_array *array, u32 func)
655655
if (kvm_cpu_cap_has(X86_FEATURE_RDTSCP))
656656
entry->ecx = F(RDPID);
657657
++array->nent;
658+
break;
658659
default:
659660
break;
660661
}

arch/x86/kvm/lapic.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,9 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
14101410
if (!apic_x2apic_mode(apic))
14111411
valid_reg_mask |= APIC_REG_MASK(APIC_ARBPRI);
14121412

1413+
if (alignment + len > 4)
1414+
return 1;
1415+
14131416
if (offset > 0x3f0 || !(valid_reg_mask & APIC_REG_MASK(offset)))
14141417
return 1;
14151418

arch/x86/kvm/mmu/mmu.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4739,9 +4739,33 @@ static void init_kvm_softmmu(struct kvm_vcpu *vcpu)
47394739
context->inject_page_fault = kvm_inject_page_fault;
47404740
}
47414741

4742+
static union kvm_mmu_role kvm_calc_nested_mmu_role(struct kvm_vcpu *vcpu)
4743+
{
4744+
union kvm_mmu_role role = kvm_calc_shadow_root_page_role_common(vcpu, false);
4745+
4746+
/*
4747+
* Nested MMUs are used only for walking L2's gva->gpa, they never have
4748+
* shadow pages of their own and so "direct" has no meaning. Set it
4749+
* to "true" to try to detect bogus usage of the nested MMU.
4750+
*/
4751+
role.base.direct = true;
4752+
4753+
if (!is_paging(vcpu))
4754+
role.base.level = 0;
4755+
else if (is_long_mode(vcpu))
4756+
role.base.level = is_la57_mode(vcpu) ? PT64_ROOT_5LEVEL :
4757+
PT64_ROOT_4LEVEL;
4758+
else if (is_pae(vcpu))
4759+
role.base.level = PT32E_ROOT_LEVEL;
4760+
else
4761+
role.base.level = PT32_ROOT_LEVEL;
4762+
4763+
return role;
4764+
}
4765+
47424766
static void init_kvm_nested_mmu(struct kvm_vcpu *vcpu)
47434767
{
4744-
union kvm_mmu_role new_role = kvm_calc_mmu_role_common(vcpu, false);
4768+
union kvm_mmu_role new_role = kvm_calc_nested_mmu_role(vcpu);
47454769
struct kvm_mmu *g_context = &vcpu->arch.nested_mmu;
47464770

47474771
if (new_role.as_u64 == g_context->mmu_role.as_u64)

arch/x86/kvm/svm/avic.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
221221
return &avic_physical_id_table[index];
222222
}
223223

224-
/**
224+
/*
225225
* Note:
226226
* AVIC hardware walks the nested page table to check permissions,
227227
* but does not use the SPA address specified in the leaf page
@@ -764,7 +764,7 @@ static int svm_ir_list_add(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi)
764764
return ret;
765765
}
766766

767-
/**
767+
/*
768768
* Note:
769769
* The HW cannot support posting multicast/broadcast
770770
* interrupts to a vCPU. So, we still use legacy interrupt
@@ -1005,7 +1005,7 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu)
10051005
WRITE_ONCE(*(svm->avic_physical_id_cache), entry);
10061006
}
10071007

1008-
/**
1008+
/*
10091009
* This function is called during VCPU halt/unhalt.
10101010
*/
10111011
static void avic_set_running(struct kvm_vcpu *vcpu, bool is_run)

arch/x86/kvm/svm/sev.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,19 @@ static void sev_asid_free(struct kvm_sev_info *sev)
199199
sev->misc_cg = NULL;
200200
}
201201

202-
static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
202+
static void sev_decommission(unsigned int handle)
203203
{
204204
struct sev_data_decommission decommission;
205+
206+
if (!handle)
207+
return;
208+
209+
decommission.handle = handle;
210+
sev_guest_decommission(&decommission, NULL);
211+
}
212+
213+
static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
214+
{
205215
struct sev_data_deactivate deactivate;
206216

207217
if (!handle)
@@ -214,9 +224,7 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
214224
sev_guest_deactivate(&deactivate, NULL);
215225
up_read(&sev_deactivate_lock);
216226

217-
/* decommission handle */
218-
decommission.handle = handle;
219-
sev_guest_decommission(&decommission, NULL);
227+
sev_decommission(handle);
220228
}
221229

222230
static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
@@ -341,8 +349,10 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
341349

342350
/* Bind ASID to this guest */
343351
ret = sev_bind_asid(kvm, start.handle, error);
344-
if (ret)
352+
if (ret) {
353+
sev_decommission(start.handle);
345354
goto e_free_session;
355+
}
346356

347357
/* return handle to userspace */
348358
params.handle = start.handle;

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6247,6 +6247,7 @@ void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
62476247
switch (kvm_get_apic_mode(vcpu)) {
62486248
case LAPIC_MODE_INVALID:
62496249
WARN_ONCE(true, "Invalid local APIC state");
6250+
break;
62506251
case LAPIC_MODE_DISABLED:
62516252
break;
62526253
case LAPIC_MODE_XAPIC:

arch/x86/kvm/x86.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7106,7 +7106,10 @@ static unsigned emulator_get_hflags(struct x86_emulate_ctxt *ctxt)
71067106

71077107
static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_flags)
71087108
{
7109-
emul_to_vcpu(ctxt)->arch.hflags = emul_flags;
7109+
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
7110+
7111+
vcpu->arch.hflags = emul_flags;
7112+
kvm_mmu_reset_context(vcpu);
71107113
}
71117114

71127115
static int emulator_pre_leave_smm(struct x86_emulate_ctxt *ctxt,
@@ -8258,6 +8261,7 @@ void kvm_arch_exit(void)
82588261
kvm_x86_ops.hardware_enable = NULL;
82598262
kvm_mmu_module_exit();
82608263
free_percpu(user_return_msrs);
8264+
kmem_cache_destroy(x86_emulator_cache);
82618265
kmem_cache_destroy(x86_fpu_cache);
82628266
#ifdef CONFIG_KVM_XEN
82638267
static_key_deferred_flush(&kvm_xen_enabled);

tools/testing/selftests/kvm/lib/kvm_util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int kvm_check_cap(long cap)
8282

8383
kvm_fd = open_kvm_dev_path_or_exit();
8484
ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, cap);
85-
TEST_ASSERT(ret != -1, "KVM_CHECK_EXTENSION IOCTL failed,\n"
85+
TEST_ASSERT(ret >= 0, "KVM_CHECK_EXTENSION IOCTL failed,\n"
8686
" rc: %i errno: %i", ret, errno);
8787

8888
close(kvm_fd);

tools/testing/selftests/kvm/lib/test_util.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -166,75 +166,75 @@ size_t get_def_hugetlb_pagesz(void)
166166
return 0;
167167
}
168168

169+
#define ANON_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS)
170+
#define ANON_HUGE_FLAGS (ANON_FLAGS | MAP_HUGETLB)
171+
169172
const struct vm_mem_backing_src_alias *vm_mem_backing_src_alias(uint32_t i)
170173
{
171-
static const int anon_flags = MAP_PRIVATE | MAP_ANONYMOUS;
172-
static const int anon_huge_flags = anon_flags | MAP_HUGETLB;
173-
174174
static const struct vm_mem_backing_src_alias aliases[] = {
175175
[VM_MEM_SRC_ANONYMOUS] = {
176176
.name = "anonymous",
177-
.flag = anon_flags,
177+
.flag = ANON_FLAGS,
178178
},
179179
[VM_MEM_SRC_ANONYMOUS_THP] = {
180180
.name = "anonymous_thp",
181-
.flag = anon_flags,
181+
.flag = ANON_FLAGS,
182182
},
183183
[VM_MEM_SRC_ANONYMOUS_HUGETLB] = {
184184
.name = "anonymous_hugetlb",
185-
.flag = anon_huge_flags,
185+
.flag = ANON_HUGE_FLAGS,
186186
},
187187
[VM_MEM_SRC_ANONYMOUS_HUGETLB_16KB] = {
188188
.name = "anonymous_hugetlb_16kb",
189-
.flag = anon_huge_flags | MAP_HUGE_16KB,
189+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_16KB,
190190
},
191191
[VM_MEM_SRC_ANONYMOUS_HUGETLB_64KB] = {
192192
.name = "anonymous_hugetlb_64kb",
193-
.flag = anon_huge_flags | MAP_HUGE_64KB,
193+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_64KB,
194194
},
195195
[VM_MEM_SRC_ANONYMOUS_HUGETLB_512KB] = {
196196
.name = "anonymous_hugetlb_512kb",
197-
.flag = anon_huge_flags | MAP_HUGE_512KB,
197+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_512KB,
198198
},
199199
[VM_MEM_SRC_ANONYMOUS_HUGETLB_1MB] = {
200200
.name = "anonymous_hugetlb_1mb",
201-
.flag = anon_huge_flags | MAP_HUGE_1MB,
201+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_1MB,
202202
},
203203
[VM_MEM_SRC_ANONYMOUS_HUGETLB_2MB] = {
204204
.name = "anonymous_hugetlb_2mb",
205-
.flag = anon_huge_flags | MAP_HUGE_2MB,
205+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_2MB,
206206
},
207207
[VM_MEM_SRC_ANONYMOUS_HUGETLB_8MB] = {
208208
.name = "anonymous_hugetlb_8mb",
209-
.flag = anon_huge_flags | MAP_HUGE_8MB,
209+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_8MB,
210210
},
211211
[VM_MEM_SRC_ANONYMOUS_HUGETLB_16MB] = {
212212
.name = "anonymous_hugetlb_16mb",
213-
.flag = anon_huge_flags | MAP_HUGE_16MB,
213+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_16MB,
214214
},
215215
[VM_MEM_SRC_ANONYMOUS_HUGETLB_32MB] = {
216216
.name = "anonymous_hugetlb_32mb",
217-
.flag = anon_huge_flags | MAP_HUGE_32MB,
217+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_32MB,
218218
},
219219
[VM_MEM_SRC_ANONYMOUS_HUGETLB_256MB] = {
220220
.name = "anonymous_hugetlb_256mb",
221-
.flag = anon_huge_flags | MAP_HUGE_256MB,
221+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_256MB,
222222
},
223223
[VM_MEM_SRC_ANONYMOUS_HUGETLB_512MB] = {
224224
.name = "anonymous_hugetlb_512mb",
225-
.flag = anon_huge_flags | MAP_HUGE_512MB,
225+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_512MB,
226226
},
227227
[VM_MEM_SRC_ANONYMOUS_HUGETLB_1GB] = {
228228
.name = "anonymous_hugetlb_1gb",
229-
.flag = anon_huge_flags | MAP_HUGE_1GB,
229+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_1GB,
230230
},
231231
[VM_MEM_SRC_ANONYMOUS_HUGETLB_2GB] = {
232232
.name = "anonymous_hugetlb_2gb",
233-
.flag = anon_huge_flags | MAP_HUGE_2GB,
233+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_2GB,
234234
},
235235
[VM_MEM_SRC_ANONYMOUS_HUGETLB_16GB] = {
236236
.name = "anonymous_hugetlb_16gb",
237-
.flag = anon_huge_flags | MAP_HUGE_16GB,
237+
.flag = ANON_HUGE_FLAGS | MAP_HUGE_16GB,
238238
},
239239
[VM_MEM_SRC_SHMEM] = {
240240
.name = "shmem",

0 commit comments

Comments
 (0)