mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 18:13:04 +00:00
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.
|
* Non-VHE: Both host and guest must save everything.
|
||||||
*
|
*
|
||||||
* VHE: Host must save tpidr*_el[01], actlr_el1, sp0, pc, pstate, and
|
* VHE: Host must save tpidr*_el[01], actlr_el1, mdscr_el1, sp0, pc,
|
||||||
* guest must save everything.
|
* pstate, and guest must save everything.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
|
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[TPIDR_EL0] = read_sysreg(tpidr_el0);
|
||||||
ctxt->sys_regs[TPIDRRO_EL0] = read_sysreg(tpidrro_el0);
|
ctxt->sys_regs[TPIDRRO_EL0] = read_sysreg(tpidrro_el0);
|
||||||
ctxt->sys_regs[TPIDR_EL1] = read_sysreg(tpidr_el1);
|
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.sp = read_sysreg(sp_el0);
|
||||||
ctxt->gp_regs.regs.pc = read_sysreg_el2(elr);
|
ctxt->gp_regs.regs.pc = read_sysreg_el2(elr);
|
||||||
ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr);
|
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[AMAIR_EL1] = read_sysreg_el1(amair);
|
||||||
ctxt->sys_regs[CNTKCTL_EL1] = read_sysreg_el1(cntkctl);
|
ctxt->sys_regs[CNTKCTL_EL1] = read_sysreg_el1(cntkctl);
|
||||||
ctxt->sys_regs[PAR_EL1] = read_sysreg(par_el1);
|
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.sp_el1 = read_sysreg(sp_el1);
|
||||||
ctxt->gp_regs.elr_el1 = read_sysreg_el1(elr);
|
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[TPIDR_EL0], tpidr_el0);
|
||||||
write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0);
|
write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0);
|
||||||
write_sysreg(ctxt->sys_regs[TPIDR_EL1], tpidr_el1);
|
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(ctxt->gp_regs.regs.sp, sp_el0);
|
||||||
write_sysreg_el2(ctxt->gp_regs.regs.pc, elr);
|
write_sysreg_el2(ctxt->gp_regs.regs.pc, elr);
|
||||||
write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr);
|
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[AMAIR_EL1], amair);
|
||||||
write_sysreg_el1(ctxt->sys_regs[CNTKCTL_EL1], cntkctl);
|
write_sysreg_el1(ctxt->sys_regs[CNTKCTL_EL1], cntkctl);
|
||||||
write_sysreg(ctxt->sys_regs[PAR_EL1], par_el1);
|
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(ctxt->gp_regs.sp_el1, sp_el1);
|
||||||
write_sysreg_el1(ctxt->gp_regs.elr_el1, elr);
|
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->fixed = false;
|
||||||
iter->start_max = iter->start;
|
iter->start_max = iter->start;
|
||||||
|
iter->range = NULL;
|
||||||
iter->range = list_prepare_entry(iter->range, &mtrr_state->head, node);
|
iter->range = list_prepare_entry(iter->range, &mtrr_state->head, node);
|
||||||
|
|
||||||
__mtrr_lookup_var_next(iter);
|
__mtrr_lookup_var_next(iter);
|
||||||
|
@ -4979,6 +4979,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
|
|||||||
if (vmx_xsaves_supported())
|
if (vmx_xsaves_supported())
|
||||||
vmcs_write64(XSS_EXIT_BITMAP, VMX_XSS_EXIT_BITMAP);
|
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;
|
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);
|
*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)
|
static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx)
|
||||||
{
|
{
|
||||||
if (vmx->pml_pg) {
|
if (vmx->pml_pg) {
|
||||||
@ -8224,6 +8214,7 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
|
|||||||
if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
|
if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
|
||||||
(exit_reason != EXIT_REASON_EXCEPTION_NMI &&
|
(exit_reason != EXIT_REASON_EXCEPTION_NMI &&
|
||||||
exit_reason != EXIT_REASON_EPT_VIOLATION &&
|
exit_reason != EXIT_REASON_EPT_VIOLATION &&
|
||||||
|
exit_reason != EXIT_REASON_PML_FULL &&
|
||||||
exit_reason != EXIT_REASON_TASK_SWITCH)) {
|
exit_reason != EXIT_REASON_TASK_SWITCH)) {
|
||||||
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||||
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
|
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
|
||||||
@ -8854,6 +8845,22 @@ static void vmx_load_vmcs01(struct kvm_vcpu *vcpu)
|
|||||||
put_cpu();
|
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)
|
static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct vcpu_vmx *vmx = to_vmx(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);
|
vmx_destroy_pml_buffer(vmx);
|
||||||
free_vpid(vmx->vpid);
|
free_vpid(vmx->vpid);
|
||||||
leave_guest_mode(vcpu);
|
leave_guest_mode(vcpu);
|
||||||
vmx_load_vmcs01(vcpu);
|
vmx_free_vcpu_nested(vcpu);
|
||||||
free_nested(vmx);
|
|
||||||
free_loaded_vmcs(vmx->loaded_vmcs);
|
free_loaded_vmcs(vmx->loaded_vmcs);
|
||||||
kfree(vmx->guest_msrs);
|
kfree(vmx->guest_msrs);
|
||||||
kvm_vcpu_uninit(vcpu);
|
kvm_vcpu_uninit(vcpu);
|
||||||
@ -8885,14 +8891,26 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
|
|||||||
if (err)
|
if (err)
|
||||||
goto free_vcpu;
|
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);
|
vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||||
BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) * sizeof(vmx->guest_msrs[0])
|
BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) * sizeof(vmx->guest_msrs[0])
|
||||||
> PAGE_SIZE);
|
> PAGE_SIZE);
|
||||||
|
|
||||||
err = -ENOMEM;
|
if (!vmx->guest_msrs)
|
||||||
if (!vmx->guest_msrs) {
|
goto free_pml;
|
||||||
goto uninit_vcpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
vmx->loaded_vmcs = &vmx->vmcs01;
|
vmx->loaded_vmcs = &vmx->vmcs01;
|
||||||
vmx->loaded_vmcs->vmcs = alloc_vmcs();
|
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_vmptr = -1ull;
|
||||||
vmx->nested.current_vmcs12 = NULL;
|
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;
|
return &vmx->vcpu;
|
||||||
|
|
||||||
free_vmcs:
|
free_vmcs:
|
||||||
@ -8955,6 +8961,8 @@ free_vmcs:
|
|||||||
free_loaded_vmcs(vmx->loaded_vmcs);
|
free_loaded_vmcs(vmx->loaded_vmcs);
|
||||||
free_msrs:
|
free_msrs:
|
||||||
kfree(vmx->guest_msrs);
|
kfree(vmx->guest_msrs);
|
||||||
|
free_pml:
|
||||||
|
vmx_destroy_pml_buffer(vmx);
|
||||||
uninit_vcpu:
|
uninit_vcpu:
|
||||||
kvm_vcpu_uninit(&vmx->vcpu);
|
kvm_vcpu_uninit(&vmx->vcpu);
|
||||||
free_vcpu:
|
free_vcpu:
|
||||||
|
@ -148,6 +148,7 @@ int vcpu_load(struct kvm_vcpu *vcpu)
|
|||||||
put_cpu();
|
put_cpu();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(vcpu_load);
|
||||||
|
|
||||||
void vcpu_put(struct kvm_vcpu *vcpu)
|
void vcpu_put(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
@ -157,6 +158,7 @@ void vcpu_put(struct kvm_vcpu *vcpu)
|
|||||||
preempt_enable();
|
preempt_enable();
|
||||||
mutex_unlock(&vcpu->mutex);
|
mutex_unlock(&vcpu->mutex);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(vcpu_put);
|
||||||
|
|
||||||
static void ack_flush(void *_completed)
|
static void ack_flush(void *_completed)
|
||||||
{
|
{
|
||||||
@ -3048,6 +3050,7 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct kvm *kvm;
|
struct kvm *kvm;
|
||||||
|
struct file *file;
|
||||||
|
|
||||||
kvm = kvm_create_vm(type);
|
kvm = kvm_create_vm(type);
|
||||||
if (IS_ERR(kvm))
|
if (IS_ERR(kvm))
|
||||||
@ -3059,17 +3062,25 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
#endif
|
#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) {
|
if (r < 0) {
|
||||||
kvm_put_kvm(kvm);
|
kvm_put_kvm(kvm);
|
||||||
return r;
|
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) {
|
if (kvm_create_vm_debugfs(kvm, r) < 0) {
|
||||||
kvm_put_kvm(kvm);
|
put_unused_fd(r);
|
||||||
|
fput(file);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd_install(r, file);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user