forked from Minki/linux
This merge introduces three patches that are later reverted,
- Switching of MSR_TSC_AUX in SVM was thought to cause a host misbehavior, but it was later cleared of those doubts and the patch moved code to a hot path, so we reverted it. That patch also needed a fix for 32 bit builds and both were reverted in one go. - Al Viro noticed that a fix for a leak in an error path was not valid with the given API and provided a better fix, so the original patch was reverted. Then there are two VMX fixes that move code around because VMCS was not accessed between vcpu_load() and vcpu_put(), a simple ARM VHE fix, and two one-liners for PML and MTRR. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABCAAGBQJXljRwAAoJEED/6hsPKofoIZMIAIMm2h5HKplmpT007dVCt1zw dG8gO9hxOxstXfGVkNEZvdxyUb0ilFMO5AYySS1ctENpswVAZlKWlyc+aNGsHXOS KFylAUNHlibua1xgB64Sitgub8M9Ct5mDfvvqWL79aCgHTLcDxnb/0NprTqB2P3O TfsLaiKMDOeZs4nTcs62vNqpPJzoFc6DK2x1RltFGF9RpR7bOD7gnp7KypDWJx7S 1LleWPHboxHQ40qf8dxAb7HwEARfXndlP6ZoCkf2stoWTwuexHJfesUnsNgEuXnX 6YJ9mO7np/bHfSDpGMJbb9pPI5g7UDwOzmgvYQvzhak3LRmvjsZePpWchlb0yCs= =3VD4 -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm Pull KVM leftovers from Radim Krčmář: "This is a combination of two pull requests for 4.7-rc8 that were not merged due to looking hairy. I have changed the tag message to focus on circumstances of contained reverts as they were likely the reason behind rejection. This merge introduces three patches that are later reverted, - Switching of MSR_TSC_AUX in SVM was thought to cause a host misbehavior, but it was later cleared of those doubts and the patch moved code to a hot path, so we reverted it. That patch also needed a fix for 32 bit builds and both were reverted in one go. - Al Viro noticed that a fix for a leak in an error path was not valid with the given API and provided a better fix, so the original patch was reverted. Then there are two VMX fixes that move code around because VMCS was not accessed between vcpu_load() and vcpu_put(), a simple ARM VHE fix, and two one-liners for PML and MTRR" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: arm64: KVM: VHE: Context switch MDSCR_EL1 KVM: VMX: handle PML full VMEXIT that occurs during event delivery Revert "KVM: SVM: fix trashing of MSR_TSC_AUX" KVM: SVM: do not set MSR_TSC_AUX on 32-bit builds KVM: don't use anon_inode_getfd() before possible failures Revert "KVM: release anon file in failure path of vm creation" KVM: release anon file in failure path of vm creation KVM: nVMX: Fix memory corruption when using VMCS shadowing kvm: vmx: ensure VMCS is current while enabling PML KVM: SVM: fix trashing of MSR_TSC_AUX KVM: MTRR: fix kvm_mtrr_check_gfn_range_consistency page fault
This commit is contained in:
commit
85802a49a8
@ -27,8 +27,8 @@ static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { }
|
||||
/*
|
||||
* Non-VHE: Both host and guest must save everything.
|
||||
*
|
||||
* VHE: Host must save tpidr*_el[01], actlr_el1, sp0, pc, pstate, and
|
||||
* guest must save everything.
|
||||
* VHE: Host must save tpidr*_el[01], actlr_el1, mdscr_el1, sp0, pc,
|
||||
* pstate, and guest must save everything.
|
||||
*/
|
||||
|
||||
static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
|
||||
@ -37,6 +37,7 @@ static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
|
||||
ctxt->sys_regs[TPIDR_EL0] = read_sysreg(tpidr_el0);
|
||||
ctxt->sys_regs[TPIDRRO_EL0] = read_sysreg(tpidrro_el0);
|
||||
ctxt->sys_regs[TPIDR_EL1] = read_sysreg(tpidr_el1);
|
||||
ctxt->sys_regs[MDSCR_EL1] = read_sysreg(mdscr_el1);
|
||||
ctxt->gp_regs.regs.sp = read_sysreg(sp_el0);
|
||||
ctxt->gp_regs.regs.pc = read_sysreg_el2(elr);
|
||||
ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr);
|
||||
@ -61,7 +62,6 @@ static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
|
||||
ctxt->sys_regs[AMAIR_EL1] = read_sysreg_el1(amair);
|
||||
ctxt->sys_regs[CNTKCTL_EL1] = read_sysreg_el1(cntkctl);
|
||||
ctxt->sys_regs[PAR_EL1] = read_sysreg(par_el1);
|
||||
ctxt->sys_regs[MDSCR_EL1] = read_sysreg(mdscr_el1);
|
||||
|
||||
ctxt->gp_regs.sp_el1 = read_sysreg(sp_el1);
|
||||
ctxt->gp_regs.elr_el1 = read_sysreg_el1(elr);
|
||||
@ -90,6 +90,7 @@ static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctx
|
||||
write_sysreg(ctxt->sys_regs[TPIDR_EL0], tpidr_el0);
|
||||
write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0);
|
||||
write_sysreg(ctxt->sys_regs[TPIDR_EL1], tpidr_el1);
|
||||
write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1);
|
||||
write_sysreg(ctxt->gp_regs.regs.sp, sp_el0);
|
||||
write_sysreg_el2(ctxt->gp_regs.regs.pc, elr);
|
||||
write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr);
|
||||
@ -114,7 +115,6 @@ static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
|
||||
write_sysreg_el1(ctxt->sys_regs[AMAIR_EL1], amair);
|
||||
write_sysreg_el1(ctxt->sys_regs[CNTKCTL_EL1], cntkctl);
|
||||
write_sysreg(ctxt->sys_regs[PAR_EL1], par_el1);
|
||||
write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1);
|
||||
|
||||
write_sysreg(ctxt->gp_regs.sp_el1, sp_el1);
|
||||
write_sysreg_el1(ctxt->gp_regs.elr_el1, elr);
|
||||
|
@ -539,6 +539,7 @@ static void mtrr_lookup_var_start(struct mtrr_iter *iter)
|
||||
|
||||
iter->fixed = false;
|
||||
iter->start_max = iter->start;
|
||||
iter->range = NULL;
|
||||
iter->range = list_prepare_entry(iter->range, &mtrr_state->head, node);
|
||||
|
||||
__mtrr_lookup_var_next(iter);
|
||||
|
@ -4979,6 +4979,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
|
||||
if (vmx_xsaves_supported())
|
||||
vmcs_write64(XSS_EXIT_BITMAP, VMX_XSS_EXIT_BITMAP);
|
||||
|
||||
if (enable_pml) {
|
||||
ASSERT(vmx->pml_pg);
|
||||
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
|
||||
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7937,22 +7943,6 @@ static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
|
||||
*info2 = vmcs_read32(VM_EXIT_INTR_INFO);
|
||||
}
|
||||
|
||||
static int vmx_create_pml_buffer(struct vcpu_vmx *vmx)
|
||||
{
|
||||
struct page *pml_pg;
|
||||
|
||||
pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (!pml_pg)
|
||||
return -ENOMEM;
|
||||
|
||||
vmx->pml_pg = pml_pg;
|
||||
|
||||
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
|
||||
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx)
|
||||
{
|
||||
if (vmx->pml_pg) {
|
||||
@ -8224,6 +8214,7 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
|
||||
if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
|
||||
(exit_reason != EXIT_REASON_EXCEPTION_NMI &&
|
||||
exit_reason != EXIT_REASON_EPT_VIOLATION &&
|
||||
exit_reason != EXIT_REASON_PML_FULL &&
|
||||
exit_reason != EXIT_REASON_TASK_SWITCH)) {
|
||||
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
|
||||
@ -8854,6 +8845,22 @@ static void vmx_load_vmcs01(struct kvm_vcpu *vcpu)
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that the current vmcs of the logical processor is the
|
||||
* vmcs01 of the vcpu before calling free_nested().
|
||||
*/
|
||||
static void vmx_free_vcpu_nested(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
int r;
|
||||
|
||||
r = vcpu_load(vcpu);
|
||||
BUG_ON(r);
|
||||
vmx_load_vmcs01(vcpu);
|
||||
free_nested(vmx);
|
||||
vcpu_put(vcpu);
|
||||
}
|
||||
|
||||
static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
@ -8862,8 +8869,7 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
|
||||
vmx_destroy_pml_buffer(vmx);
|
||||
free_vpid(vmx->vpid);
|
||||
leave_guest_mode(vcpu);
|
||||
vmx_load_vmcs01(vcpu);
|
||||
free_nested(vmx);
|
||||
vmx_free_vcpu_nested(vcpu);
|
||||
free_loaded_vmcs(vmx->loaded_vmcs);
|
||||
kfree(vmx->guest_msrs);
|
||||
kvm_vcpu_uninit(vcpu);
|
||||
@ -8885,14 +8891,26 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
|
||||
if (err)
|
||||
goto free_vcpu;
|
||||
|
||||
err = -ENOMEM;
|
||||
|
||||
/*
|
||||
* If PML is turned on, failure on enabling PML just results in failure
|
||||
* of creating the vcpu, therefore we can simplify PML logic (by
|
||||
* avoiding dealing with cases, such as enabling PML partially on vcpus
|
||||
* for the guest, etc.
|
||||
*/
|
||||
if (enable_pml) {
|
||||
vmx->pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (!vmx->pml_pg)
|
||||
goto uninit_vcpu;
|
||||
}
|
||||
|
||||
vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) * sizeof(vmx->guest_msrs[0])
|
||||
> PAGE_SIZE);
|
||||
|
||||
err = -ENOMEM;
|
||||
if (!vmx->guest_msrs) {
|
||||
goto uninit_vcpu;
|
||||
}
|
||||
if (!vmx->guest_msrs)
|
||||
goto free_pml;
|
||||
|
||||
vmx->loaded_vmcs = &vmx->vmcs01;
|
||||
vmx->loaded_vmcs->vmcs = alloc_vmcs();
|
||||
@ -8936,18 +8954,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
|
||||
vmx->nested.current_vmptr = -1ull;
|
||||
vmx->nested.current_vmcs12 = NULL;
|
||||
|
||||
/*
|
||||
* If PML is turned on, failure on enabling PML just results in failure
|
||||
* of creating the vcpu, therefore we can simplify PML logic (by
|
||||
* avoiding dealing with cases, such as enabling PML partially on vcpus
|
||||
* for the guest, etc.
|
||||
*/
|
||||
if (enable_pml) {
|
||||
err = vmx_create_pml_buffer(vmx);
|
||||
if (err)
|
||||
goto free_vmcs;
|
||||
}
|
||||
|
||||
return &vmx->vcpu;
|
||||
|
||||
free_vmcs:
|
||||
@ -8955,6 +8961,8 @@ free_vmcs:
|
||||
free_loaded_vmcs(vmx->loaded_vmcs);
|
||||
free_msrs:
|
||||
kfree(vmx->guest_msrs);
|
||||
free_pml:
|
||||
vmx_destroy_pml_buffer(vmx);
|
||||
uninit_vcpu:
|
||||
kvm_vcpu_uninit(&vmx->vcpu);
|
||||
free_vcpu:
|
||||
|
@ -148,6 +148,7 @@ int vcpu_load(struct kvm_vcpu *vcpu)
|
||||
put_cpu();
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vcpu_load);
|
||||
|
||||
void vcpu_put(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
@ -157,6 +158,7 @@ void vcpu_put(struct kvm_vcpu *vcpu)
|
||||
preempt_enable();
|
||||
mutex_unlock(&vcpu->mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vcpu_put);
|
||||
|
||||
static void ack_flush(void *_completed)
|
||||
{
|
||||
@ -3048,6 +3050,7 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
|
||||
{
|
||||
int r;
|
||||
struct kvm *kvm;
|
||||
struct file *file;
|
||||
|
||||
kvm = kvm_create_vm(type);
|
||||
if (IS_ERR(kvm))
|
||||
@ -3059,17 +3062,25 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
r = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR | O_CLOEXEC);
|
||||
r = get_unused_fd_flags(O_CLOEXEC);
|
||||
if (r < 0) {
|
||||
kvm_put_kvm(kvm);
|
||||
return r;
|
||||
}
|
||||
file = anon_inode_getfile("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
|
||||
if (IS_ERR(file)) {
|
||||
put_unused_fd(r);
|
||||
kvm_put_kvm(kvm);
|
||||
return PTR_ERR(file);
|
||||
}
|
||||
|
||||
if (kvm_create_vm_debugfs(kvm, r) < 0) {
|
||||
kvm_put_kvm(kvm);
|
||||
put_unused_fd(r);
|
||||
fput(file);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fd_install(r, file);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user