Commit 7c7ec322 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull more kvm fixes from Paolo Bonzini:
 "Five small fixes.

  The nested migration bug will be fixed with a better API in 5.10 or
  5.11, for now this is a fix that works with existing userspace but
  keeps the current ugly API"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: SVM: Add a dedicated INVD intercept routine
  KVM: x86: Reset MMU context if guest toggles CR4.SMAP or CR4.PKE
  KVM: x86: fix MSR_IA32_TSC read for nested migration
  selftests: kvm: Fix assert failure in single-step test
  KVM: x86: VMX: Make smaller physical guest address space support user-configurable
parents b463b6f6 4bb05f30
...@@ -2183,6 +2183,12 @@ static int iret_interception(struct vcpu_svm *svm) ...@@ -2183,6 +2183,12 @@ static int iret_interception(struct vcpu_svm *svm)
return 1; return 1;
} }
static int invd_interception(struct vcpu_svm *svm)
{
/* Treat an INVD instruction as a NOP and just skip it. */
return kvm_skip_emulated_instruction(&svm->vcpu);
}
static int invlpg_interception(struct vcpu_svm *svm) static int invlpg_interception(struct vcpu_svm *svm)
{ {
if (!static_cpu_has(X86_FEATURE_DECODEASSISTS)) if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
...@@ -2774,7 +2780,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { ...@@ -2774,7 +2780,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_RDPMC] = rdpmc_interception, [SVM_EXIT_RDPMC] = rdpmc_interception,
[SVM_EXIT_CPUID] = cpuid_interception, [SVM_EXIT_CPUID] = cpuid_interception,
[SVM_EXIT_IRET] = iret_interception, [SVM_EXIT_IRET] = iret_interception,
[SVM_EXIT_INVD] = emulate_on_interception, [SVM_EXIT_INVD] = invd_interception,
[SVM_EXIT_PAUSE] = pause_interception, [SVM_EXIT_PAUSE] = pause_interception,
[SVM_EXIT_HLT] = halt_interception, [SVM_EXIT_HLT] = halt_interception,
[SVM_EXIT_INVLPG] = invlpg_interception, [SVM_EXIT_INVLPG] = invlpg_interception,
......
...@@ -129,6 +129,9 @@ static bool __read_mostly enable_preemption_timer = 1; ...@@ -129,6 +129,9 @@ static bool __read_mostly enable_preemption_timer = 1;
module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO); module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO);
#endif #endif
extern bool __read_mostly allow_smaller_maxphyaddr;
module_param(allow_smaller_maxphyaddr, bool, S_IRUGO);
#define KVM_VM_CR0_ALWAYS_OFF (X86_CR0_NW | X86_CR0_CD) #define KVM_VM_CR0_ALWAYS_OFF (X86_CR0_NW | X86_CR0_CD)
#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR0_NE #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR0_NE
#define KVM_VM_CR0_ALWAYS_ON \ #define KVM_VM_CR0_ALWAYS_ON \
...@@ -4803,6 +4806,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) ...@@ -4803,6 +4806,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
* EPT will cause page fault only if we need to * EPT will cause page fault only if we need to
* detect illegal GPAs. * detect illegal GPAs.
*/ */
WARN_ON_ONCE(!allow_smaller_maxphyaddr);
kvm_fixup_and_inject_pf_error(vcpu, cr2, error_code); kvm_fixup_and_inject_pf_error(vcpu, cr2, error_code);
return 1; return 1;
} else } else
...@@ -5331,7 +5335,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu) ...@@ -5331,7 +5335,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
* would also use advanced VM-exit information for EPT violations to * would also use advanced VM-exit information for EPT violations to
* reconstruct the page fault error code. * reconstruct the page fault error code.
*/ */
if (unlikely(kvm_mmu_is_illegal_gpa(vcpu, gpa))) if (unlikely(allow_smaller_maxphyaddr && kvm_mmu_is_illegal_gpa(vcpu, gpa)))
return kvm_emulate_instruction(vcpu, 0); return kvm_emulate_instruction(vcpu, 0);
return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0); return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
...@@ -8305,11 +8309,12 @@ static int __init vmx_init(void) ...@@ -8305,11 +8309,12 @@ static int __init vmx_init(void)
vmx_check_vmcs12_offsets(); vmx_check_vmcs12_offsets();
/* /*
* Intel processors don't have problems with * Shadow paging doesn't have a (further) performance penalty
* GUEST_MAXPHYADDR < HOST_MAXPHYADDR so enable * from GUEST_MAXPHYADDR < HOST_MAXPHYADDR so enable it
* it for VMX by default * by default
*/ */
allow_smaller_maxphyaddr = true; if (!enable_ept)
allow_smaller_maxphyaddr = true;
return 0; return 0;
} }
......
...@@ -552,7 +552,10 @@ static inline bool vmx_has_waitpkg(struct vcpu_vmx *vmx) ...@@ -552,7 +552,10 @@ static inline bool vmx_has_waitpkg(struct vcpu_vmx *vmx)
static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu) static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu)
{ {
return !enable_ept || cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits; if (!enable_ept)
return true;
return allow_smaller_maxphyaddr && cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits;
} }
void dump_vmcs(void); void dump_vmcs(void);
......
...@@ -188,7 +188,7 @@ static struct kvm_shared_msrs __percpu *shared_msrs; ...@@ -188,7 +188,7 @@ static struct kvm_shared_msrs __percpu *shared_msrs;
u64 __read_mostly host_efer; u64 __read_mostly host_efer;
EXPORT_SYMBOL_GPL(host_efer); EXPORT_SYMBOL_GPL(host_efer);
bool __read_mostly allow_smaller_maxphyaddr; bool __read_mostly allow_smaller_maxphyaddr = 0;
EXPORT_SYMBOL_GPL(allow_smaller_maxphyaddr); EXPORT_SYMBOL_GPL(allow_smaller_maxphyaddr);
static u64 __read_mostly host_xss; static u64 __read_mostly host_xss;
...@@ -976,6 +976,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) ...@@ -976,6 +976,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
unsigned long old_cr4 = kvm_read_cr4(vcpu); unsigned long old_cr4 = kvm_read_cr4(vcpu);
unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE | unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE |
X86_CR4_SMEP; X86_CR4_SMEP;
unsigned long mmu_role_bits = pdptr_bits | X86_CR4_SMAP | X86_CR4_PKE;
if (kvm_valid_cr4(vcpu, cr4)) if (kvm_valid_cr4(vcpu, cr4))
return 1; return 1;
...@@ -1003,7 +1004,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) ...@@ -1003,7 +1004,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
if (kvm_x86_ops.set_cr4(vcpu, cr4)) if (kvm_x86_ops.set_cr4(vcpu, cr4))
return 1; return 1;
if (((cr4 ^ old_cr4) & pdptr_bits) || if (((cr4 ^ old_cr4) & mmu_role_bits) ||
(!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
kvm_mmu_reset_context(vcpu); kvm_mmu_reset_context(vcpu);
...@@ -3221,9 +3222,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) ...@@ -3221,9 +3222,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_IA32_POWER_CTL: case MSR_IA32_POWER_CTL:
msr_info->data = vcpu->arch.msr_ia32_power_ctl; msr_info->data = vcpu->arch.msr_ia32_power_ctl;
break; break;
case MSR_IA32_TSC: case MSR_IA32_TSC: {
msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset; /*
* Intel SDM states that MSR_IA32_TSC read adds the TSC offset
* even when not intercepted. AMD manual doesn't explicitly
* state this but appears to behave the same.
*
* On userspace reads and writes, however, we unconditionally
* operate L1's TSC value to ensure backwards-compatible
* behavior for migration.
*/
u64 tsc_offset = msr_info->host_initiated ? vcpu->arch.l1_tsc_offset :
vcpu->arch.tsc_offset;
msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + tsc_offset;
break; break;
}
case MSR_MTRRcap: case MSR_MTRRcap:
case 0x200 ... 0x2ff: case 0x200 ... 0x2ff:
return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data); return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data);
......
...@@ -73,7 +73,7 @@ int main(void) ...@@ -73,7 +73,7 @@ int main(void)
int i; int i;
/* Instruction lengths starting at ss_start */ /* Instruction lengths starting at ss_start */
int ss_size[4] = { int ss_size[4] = {
3, /* xor */ 2, /* xor */
2, /* cpuid */ 2, /* cpuid */
5, /* mov */ 5, /* mov */
2, /* rdmsr */ 2, /* rdmsr */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment