Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0d8690a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull KVM fixes from Paolo Bonzini:
 "This includes a fix for two oopses, one on PPC and on x86.

  The rest is fixes for bugs with newer Intel processors"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  kvm/fpu: Enable eager restore kvm FPU for MPX
  Revert "KVM: x86: drop fpu_activate hook"
  kvm: fix crash in kvm_vcpu_reload_apic_access_page
  KVM: MMU: fix SMAP virtualization
  KVM: MMU: fix CR4.SMEP=1, CR0.WP=0 with shadow pages
  KVM: MMU: fix smap permission check
  KVM: PPC: Book3S HV: Fix list traversal in error case
parents 2f8126e3 c447e76b
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -169,6 +169,10 @@ Shadow pages contain the following information:
    Contains the value of cr4.smep && !cr0.wp for which the page is valid
    (pages for which this is true are different from other pages; see the
    treatment of cr0.wp=0 below).
  role.smap_andnot_wp:
    Contains the value of cr4.smap && !cr0.wp for which the page is valid
    (pages for which this is true are different from other pages; see the
    treatment of cr0.wp=0 below).
  gfn:
    Either the guest page table containing the translations shadowed by this
    page, or the base page frame for linear translations.  See role.direct.
@@ -344,10 +348,16 @@ on fault type:

(user write faults generate a #PF)

In the first case there is an additional complication if CR4.SMEP is
enabled: since we've turned the page into a kernel page, the kernel may now
execute it.  We handle this by also setting spte.nx.  If we get a user
fetch or read fault, we'll change spte.u=1 and spte.nx=gpte.nx back.
In the first case there are two additional complications:
- if CR4.SMEP is enabled: since we've turned the page into a kernel page,
  the kernel may now execute it.  We handle this by also setting spte.nx.
  If we get a user fetch or read fault, we'll change spte.u=1 and
  spte.nx=gpte.nx back.
- if CR4.SMAP is disabled: since the page has been changed to a kernel
  page, it can not be reused when CR4.SMAP is enabled. We set
  CR4.SMAP && !CR0.WP into shadow page's role to avoid this case. Note,
  here we do not care the case that CR4.SMAP is enabled since KVM will
  directly inject #PF to guest due to failed permission check.

To prevent an spte that was converted into a kernel page with cr0.wp=0
from being written by the kernel after cr0.wp has changed to 1, we make
+3 −2
Original line number Diff line number Diff line
@@ -1952,7 +1952,7 @@ static void post_guest_process(struct kvmppc_vcore *vc)
 */
static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
{
	struct kvm_vcpu *vcpu;
	struct kvm_vcpu *vcpu, *vnext;
	int i;
	int srcu_idx;

@@ -1982,7 +1982,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
	 */
	if ((threads_per_core > 1) &&
	    ((vc->num_threads > threads_per_subcore) || !on_primary_thread())) {
		list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {
		list_for_each_entry_safe(vcpu, vnext, &vc->runnable_threads,
					 arch.run_list) {
			vcpu->arch.ret = -EBUSY;
			kvmppc_remove_runnable(vc, vcpu);
			wake_up(&vcpu->arch.cpu_run);
+3 −0
Original line number Diff line number Diff line
@@ -207,6 +207,7 @@ union kvm_mmu_page_role {
		unsigned nxe:1;
		unsigned cr0_wp:1;
		unsigned smep_andnot_wp:1;
		unsigned smap_andnot_wp:1;
	};
};

@@ -400,6 +401,7 @@ struct kvm_vcpu_arch {
	struct kvm_mmu_memory_cache mmu_page_header_cache;

	struct fpu guest_fpu;
	bool eager_fpu;
	u64 xcr0;
	u64 guest_supported_xcr0;
	u32 guest_xstate_size;
@@ -743,6 +745,7 @@ struct kvm_x86_ops {
	void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg);
	unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
	void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
	void (*fpu_activate)(struct kvm_vcpu *vcpu);
	void (*fpu_deactivate)(struct kvm_vcpu *vcpu);

	void (*tlb_flush)(struct kvm_vcpu *vcpu);
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include <asm/i387.h> /* For use_eager_fpu.  Ugh! */
#include <asm/fpu-internal.h> /* For use_eager_fpu.  Ugh! */
#include <asm/user.h>
#include <asm/xsave.h>
#include "cpuid.h"
@@ -95,6 +97,8 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
	if (best && (best->eax & (F(XSAVES) | F(XSAVEC))))
		best->ebx = xstate_required_size(vcpu->arch.xcr0, true);

	vcpu->arch.eager_fpu = guest_cpuid_has_mpx(vcpu);

	/*
	 * The existing code assumes virtual address is 48-bit in the canonical
	 * address checks; exit if it is ever changed.
+8 −0
Original line number Diff line number Diff line
@@ -117,4 +117,12 @@ static inline bool guest_cpuid_has_rtm(struct kvm_vcpu *vcpu)
	best = kvm_find_cpuid_entry(vcpu, 7, 0);
	return best && (best->ebx & bit(X86_FEATURE_RTM));
}

static inline bool guest_cpuid_has_mpx(struct kvm_vcpu *vcpu)
{
	struct kvm_cpuid_entry2 *best;

	best = kvm_find_cpuid_entry(vcpu, 7, 0);
	return best && (best->ebx & bit(X86_FEATURE_MPX));
}
#endif
Loading