Commit d45111e5 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull x86 kvm fixes from Paolo Bonzini:
 "Many small fixes that accumulated while I was on vacation...

   - Fixup missed comments from the REMOVED_SPTE => FROZEN_SPTE rename

   - Ensure a root is successfully loaded when pre-faulting SPTEs

   - Grab kvm->srcu when handling KVM_SET_VCPU_EVENTS to guard against
     accessing memslots if toggling SMM happens to force a VM-Exit

   - Emulate MSR_{FS,GS}_BASE on SVM even though interception is always
     disabled, so that KVM does the right thing if KVM's emulator
     encounters {RD,WR}MSR

   - Explicitly clear BUS_LOCK_DETECT from KVM's caps on AMD, as KVM
     doesn't yet virtualize BUS_LOCK_DETECT on AMD

   - Cleanup the help message for CONFIG_KVM_AMD_SEV, and call out that
     KVM now supports SEV-SNP too

   - Specialize return value of
     KVM_CHECK_EXTENSION(KVM_CAP_READONLY_MEM), based on VM type

   - Remove unnecessary dependency on CONFIG_HIGH_RES_TIMERS

   - Note an RCU quiescent state on guest exit. This avoids a call to
     rcu_core() if there was a grace period request while guest was
     running"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: Remove HIGH_RES_TIMERS dependency
  kvm: Note an RCU quiescent state on guest exit
  KVM: x86: Only advertise KVM_CAP_READONLY_MEM when supported by VM
  KVM: SEV: Update KVM_AMD_SEV Kconfig entry and mention SEV-SNP
  KVM: SVM: Don't advertise Bus Lock Detect to guest if SVM support is missing
  KVM: SVM: fix emulation of msr reads/writes of MSR_FS_BASE and MSR_GS_BASE
  KVM: x86: Acquire kvm->srcu when handling KVM_SET_VCPU_EVENTS
  KVM: x86/mmu: Check that root is valid/loaded when pre-faulting SPTEs
  KVM: x86/mmu: Fixup comments missed by the REMOVED_SPTE=>FROZEN_SPTE rename
parents 788220ee 59cbd4ee
...@@ -19,7 +19,6 @@ if VIRTUALIZATION ...@@ -19,7 +19,6 @@ if VIRTUALIZATION
config KVM config KVM
tristate "Kernel-based Virtual Machine (KVM) support" tristate "Kernel-based Virtual Machine (KVM) support"
depends on HIGH_RES_TIMERS
depends on X86_LOCAL_APIC depends on X86_LOCAL_APIC
select KVM_COMMON select KVM_COMMON
select KVM_GENERIC_MMU_NOTIFIER select KVM_GENERIC_MMU_NOTIFIER
...@@ -144,8 +143,10 @@ config KVM_AMD_SEV ...@@ -144,8 +143,10 @@ config KVM_AMD_SEV
select HAVE_KVM_ARCH_GMEM_PREPARE select HAVE_KVM_ARCH_GMEM_PREPARE
select HAVE_KVM_ARCH_GMEM_INVALIDATE select HAVE_KVM_ARCH_GMEM_INVALIDATE
help help
Provides support for launching Encrypted VMs (SEV) and Encrypted VMs Provides support for launching encrypted VMs which use Secure
with Encrypted State (SEV-ES) on AMD processors. Encrypted Virtualization (SEV), Secure Encrypted Virtualization with
Encrypted State (SEV-ES), and Secure Encrypted Virtualization with
Secure Nested Paging (SEV-SNP) technologies on AMD processors.
config KVM_SMM config KVM_SMM
bool "System Management Mode emulation" bool "System Management Mode emulation"
......
...@@ -4750,7 +4750,9 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, ...@@ -4750,7 +4750,9 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu,
* reload is efficient when called repeatedly, so we can do it on * reload is efficient when called repeatedly, so we can do it on
* every iteration. * every iteration.
*/ */
kvm_mmu_reload(vcpu); r = kvm_mmu_reload(vcpu);
if (r)
return r;
if (kvm_arch_has_private_mem(vcpu->kvm) && if (kvm_arch_has_private_mem(vcpu->kvm) &&
kvm_mem_is_private(vcpu->kvm, gpa_to_gfn(range->gpa))) kvm_mem_is_private(vcpu->kvm, gpa_to_gfn(range->gpa)))
......
...@@ -391,9 +391,9 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask) ...@@ -391,9 +391,9 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask)
mmio_value = 0; mmio_value = 0;
/* /*
* The masked MMIO value must obviously match itself and a removed SPTE * The masked MMIO value must obviously match itself and a frozen SPTE
* must not get a false positive. Removed SPTEs and MMIO SPTEs should * must not get a false positive. Frozen SPTEs and MMIO SPTEs should
* never collide as MMIO must set some RWX bits, and removed SPTEs must * never collide as MMIO must set some RWX bits, and frozen SPTEs must
* not set any RWX bits. * not set any RWX bits.
*/ */
if (WARN_ON((mmio_value & mmio_mask) != mmio_value) || if (WARN_ON((mmio_value & mmio_mask) != mmio_value) ||
......
...@@ -214,7 +214,7 @@ extern u64 __read_mostly shadow_nonpresent_or_rsvd_mask; ...@@ -214,7 +214,7 @@ extern u64 __read_mostly shadow_nonpresent_or_rsvd_mask;
*/ */
#define FROZEN_SPTE (SHADOW_NONPRESENT_VALUE | 0x5a0ULL) #define FROZEN_SPTE (SHADOW_NONPRESENT_VALUE | 0x5a0ULL)
/* Removed SPTEs must not be misconstrued as shadow present PTEs. */ /* Frozen SPTEs must not be misconstrued as shadow present PTEs. */
static_assert(!(FROZEN_SPTE & SPTE_MMU_PRESENT_MASK)); static_assert(!(FROZEN_SPTE & SPTE_MMU_PRESENT_MASK));
static inline bool is_frozen_spte(u64 spte) static inline bool is_frozen_spte(u64 spte)
......
...@@ -359,10 +359,10 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared) ...@@ -359,10 +359,10 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
/* /*
* Set the SPTE to a nonpresent value that other * Set the SPTE to a nonpresent value that other
* threads will not overwrite. If the SPTE was * threads will not overwrite. If the SPTE was
* already marked as removed then another thread * already marked as frozen then another thread
* handling a page fault could overwrite it, so * handling a page fault could overwrite it, so
* set the SPTE until it is set from some other * set the SPTE until it is set from some other
* value to the removed SPTE value. * value to the frozen SPTE value.
*/ */
for (;;) { for (;;) {
old_spte = kvm_tdp_mmu_write_spte_atomic(sptep, FROZEN_SPTE); old_spte = kvm_tdp_mmu_write_spte_atomic(sptep, FROZEN_SPTE);
...@@ -536,8 +536,8 @@ static inline int __must_check __tdp_mmu_set_spte_atomic(struct tdp_iter *iter, ...@@ -536,8 +536,8 @@ static inline int __must_check __tdp_mmu_set_spte_atomic(struct tdp_iter *iter,
u64 *sptep = rcu_dereference(iter->sptep); u64 *sptep = rcu_dereference(iter->sptep);
/* /*
* The caller is responsible for ensuring the old SPTE is not a REMOVED * The caller is responsible for ensuring the old SPTE is not a FROZEN
* SPTE. KVM should never attempt to zap or manipulate a REMOVED SPTE, * SPTE. KVM should never attempt to zap or manipulate a FROZEN SPTE,
* and pre-checking before inserting a new SPTE is advantageous as it * and pre-checking before inserting a new SPTE is advantageous as it
* avoids unnecessary work. * avoids unnecessary work.
*/ */
......
...@@ -2876,6 +2876,12 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) ...@@ -2876,6 +2876,12 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_CSTAR: case MSR_CSTAR:
msr_info->data = svm->vmcb01.ptr->save.cstar; msr_info->data = svm->vmcb01.ptr->save.cstar;
break; break;
case MSR_GS_BASE:
msr_info->data = svm->vmcb01.ptr->save.gs.base;
break;
case MSR_FS_BASE:
msr_info->data = svm->vmcb01.ptr->save.fs.base;
break;
case MSR_KERNEL_GS_BASE: case MSR_KERNEL_GS_BASE:
msr_info->data = svm->vmcb01.ptr->save.kernel_gs_base; msr_info->data = svm->vmcb01.ptr->save.kernel_gs_base;
break; break;
...@@ -3101,6 +3107,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) ...@@ -3101,6 +3107,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
case MSR_CSTAR: case MSR_CSTAR:
svm->vmcb01.ptr->save.cstar = data; svm->vmcb01.ptr->save.cstar = data;
break; break;
case MSR_GS_BASE:
svm->vmcb01.ptr->save.gs.base = data;
break;
case MSR_FS_BASE:
svm->vmcb01.ptr->save.fs.base = data;
break;
case MSR_KERNEL_GS_BASE: case MSR_KERNEL_GS_BASE:
svm->vmcb01.ptr->save.kernel_gs_base = data; svm->vmcb01.ptr->save.kernel_gs_base = data;
break; break;
...@@ -5224,6 +5236,9 @@ static __init void svm_set_cpu_caps(void) ...@@ -5224,6 +5236,9 @@ static __init void svm_set_cpu_caps(void)
/* CPUID 0x8000001F (SME/SEV features) */ /* CPUID 0x8000001F (SME/SEV features) */
sev_set_cpu_caps(); sev_set_cpu_caps();
/* Don't advertise Bus Lock Detect to guest if SVM support is absent */
kvm_cpu_cap_clear(X86_FEATURE_BUS_LOCK_DETECT);
} }
static __init int svm_hardware_setup(void) static __init int svm_hardware_setup(void)
......
...@@ -4656,7 +4656,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) ...@@ -4656,7 +4656,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_ASYNC_PF_INT: case KVM_CAP_ASYNC_PF_INT:
case KVM_CAP_GET_TSC_KHZ: case KVM_CAP_GET_TSC_KHZ:
case KVM_CAP_KVMCLOCK_CTRL: case KVM_CAP_KVMCLOCK_CTRL:
case KVM_CAP_READONLY_MEM:
case KVM_CAP_IOAPIC_POLARITY_IGNORED: case KVM_CAP_IOAPIC_POLARITY_IGNORED:
case KVM_CAP_TSC_DEADLINE_TIMER: case KVM_CAP_TSC_DEADLINE_TIMER:
case KVM_CAP_DISABLE_QUIRKS: case KVM_CAP_DISABLE_QUIRKS:
...@@ -4815,6 +4814,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) ...@@ -4815,6 +4814,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_VM_TYPES: case KVM_CAP_VM_TYPES:
r = kvm_caps.supported_vm_types; r = kvm_caps.supported_vm_types;
break; break;
case KVM_CAP_READONLY_MEM:
r = kvm ? kvm_arch_has_readonly_mem(kvm) : 1;
default: default:
break; break;
} }
...@@ -6040,7 +6041,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, ...@@ -6040,7 +6041,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
if (copy_from_user(&events, argp, sizeof(struct kvm_vcpu_events))) if (copy_from_user(&events, argp, sizeof(struct kvm_vcpu_events)))
break; break;
kvm_vcpu_srcu_read_lock(vcpu);
r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events); r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events);
kvm_vcpu_srcu_read_unlock(vcpu);
break; break;
} }
case KVM_GET_DEBUGREGS: { case KVM_GET_DEBUGREGS: {
......
...@@ -80,10 +80,12 @@ static __always_inline bool context_tracking_guest_enter(void) ...@@ -80,10 +80,12 @@ static __always_inline bool context_tracking_guest_enter(void)
return context_tracking_enabled_this_cpu(); return context_tracking_enabled_this_cpu();
} }
static __always_inline void context_tracking_guest_exit(void) static __always_inline bool context_tracking_guest_exit(void)
{ {
if (context_tracking_enabled()) if (context_tracking_enabled())
__ct_user_exit(CONTEXT_GUEST); __ct_user_exit(CONTEXT_GUEST);
return context_tracking_enabled_this_cpu();
} }
#define CT_WARN_ON(cond) WARN_ON(context_tracking_enabled() && (cond)) #define CT_WARN_ON(cond) WARN_ON(context_tracking_enabled() && (cond))
...@@ -98,7 +100,7 @@ static inline void exception_exit(enum ctx_state prev_ctx) { } ...@@ -98,7 +100,7 @@ static inline void exception_exit(enum ctx_state prev_ctx) { }
static inline int ct_state(void) { return -1; } static inline int ct_state(void) { return -1; }
static inline int __ct_state(void) { return -1; } static inline int __ct_state(void) { return -1; }
static __always_inline bool context_tracking_guest_enter(void) { return false; } static __always_inline bool context_tracking_guest_enter(void) { return false; }
static __always_inline void context_tracking_guest_exit(void) { } static __always_inline bool context_tracking_guest_exit(void) { return false; }
#define CT_WARN_ON(cond) do { } while (0) #define CT_WARN_ON(cond) do { } while (0)
#endif /* !CONFIG_CONTEXT_TRACKING_USER */ #endif /* !CONFIG_CONTEXT_TRACKING_USER */
......
...@@ -485,7 +485,15 @@ static __always_inline void guest_state_enter_irqoff(void) ...@@ -485,7 +485,15 @@ static __always_inline void guest_state_enter_irqoff(void)
*/ */
static __always_inline void guest_context_exit_irqoff(void) static __always_inline void guest_context_exit_irqoff(void)
{ {
context_tracking_guest_exit(); /*
* Guest mode is treated as a quiescent state, see
* guest_context_enter_irqoff() for more details.
*/
if (!context_tracking_guest_exit()) {
instrumentation_begin();
rcu_virt_note_context_switch();
instrumentation_end();
}
} }
/* /*
......
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