x86 bug fixes.
-----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAl58ewEUHHBib256aW5p QHJlZGhhdC5jb20ACgkQv/vSX3jHroMpagf/Ya2j9EGWMv+0BSvV9POYjbMmxfOe HdNld2zlaNreAvgHQvdW76AufIa+VnJqJEgI2wjN7exmC+HjqtF/uC9l5B3ZK5BR WKK/t9ZynXhBSmrddLI477nufsv8c34lELgLObKMECGrzsGdx8T4tEg7q9GjlZBY umDVc6kx0GEblzAIzX9Z8l8deFXeykTghMM+mSnHNDLd3a2L6hHoT4atDj5VcqQ/ PxpOV+uZhOliOgTaUmuvlQQUJ/CjJO2lsMoItGzUtKb6gTKKc0U/5kuGxXe7phB+ Ttz9Svs2oLBrKcr59R5UfI7ovGqPCaXgQ4cRPwBgIQ4lS/LR4s5ltODywA== =wIQr -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm Pull KVM fixes from Paolo Bonzini: "x86 bug fixes" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: X86: Narrow down the IPI fastpath to single target IPI KVM: LAPIC: Also cancel preemption timer when disarm LAPIC timer KVM: VMX: don't allow memory operands for inline asm that modifies SP KVM: LAPIC: Mark hrtimer for period or oneshot mode to expire in hard interrupt context KVM: SVM: Issue WBINVD after deactivating an SEV guest KVM: SVM: document KVM_MEM_ENCRYPT_OP, let userspace detect if SEV is available KVM: x86: remove bogus user-triggerable WARN_ON
This commit is contained in:
commit
a53071bd34
|
@ -53,6 +53,29 @@ key management interface to perform common hypervisor activities such as
|
|||
encrypting bootstrap code, snapshot, migrating and debugging the guest. For more
|
||||
information, see the SEV Key Management spec [api-spec]_
|
||||
|
||||
The main ioctl to access SEV is KVM_MEM_ENCRYPT_OP. If the argument
|
||||
to KVM_MEM_ENCRYPT_OP is NULL, the ioctl returns 0 if SEV is enabled
|
||||
and ``ENOTTY` if it is disabled (on some older versions of Linux,
|
||||
the ioctl runs normally even with a NULL argument, and therefore will
|
||||
likely return ``EFAULT``). If non-NULL, the argument to KVM_MEM_ENCRYPT_OP
|
||||
must be a struct kvm_sev_cmd::
|
||||
|
||||
struct kvm_sev_cmd {
|
||||
__u32 id;
|
||||
__u64 data;
|
||||
__u32 error;
|
||||
__u32 sev_fd;
|
||||
};
|
||||
|
||||
|
||||
The ``id`` field contains the subcommand, and the ``data`` field points to
|
||||
another struct containing arguments specific to command. The ``sev_fd``
|
||||
should point to a file descriptor that is opened on the ``/dev/sev``
|
||||
device, if needed (see individual commands).
|
||||
|
||||
On output, ``error`` is zero on success, or an error code. Error codes
|
||||
are defined in ``<linux/psp-dev.h>`.
|
||||
|
||||
KVM implements the following commands to support common lifecycle events of SEV
|
||||
guests, such as launching, running, snapshotting, migrating and decommissioning.
|
||||
|
||||
|
@ -90,6 +113,8 @@ Returns: 0 on success, -negative on error
|
|||
|
||||
On success, the 'handle' field contains a new handle and on error, a negative value.
|
||||
|
||||
KVM_SEV_LAUNCH_START requires the ``sev_fd`` field to be valid.
|
||||
|
||||
For more details, see SEV spec Section 6.2.
|
||||
|
||||
3. KVM_SEV_LAUNCH_UPDATE_DATA
|
||||
|
|
|
@ -1445,6 +1445,8 @@ static void limit_periodic_timer_frequency(struct kvm_lapic *apic)
|
|||
}
|
||||
}
|
||||
|
||||
static void cancel_hv_timer(struct kvm_lapic *apic);
|
||||
|
||||
static void apic_update_lvtt(struct kvm_lapic *apic)
|
||||
{
|
||||
u32 timer_mode = kvm_lapic_get_reg(apic, APIC_LVTT) &
|
||||
|
@ -1454,6 +1456,10 @@ static void apic_update_lvtt(struct kvm_lapic *apic)
|
|||
if (apic_lvtt_tscdeadline(apic) != (timer_mode ==
|
||||
APIC_LVT_TIMER_TSCDEADLINE)) {
|
||||
hrtimer_cancel(&apic->lapic_timer.timer);
|
||||
preempt_disable();
|
||||
if (apic->lapic_timer.hv_timer_in_use)
|
||||
cancel_hv_timer(apic);
|
||||
preempt_enable();
|
||||
kvm_lapic_set_reg(apic, APIC_TMICT, 0);
|
||||
apic->lapic_timer.period = 0;
|
||||
apic->lapic_timer.tscdeadline = 0;
|
||||
|
@ -1715,7 +1721,7 @@ static void start_sw_period(struct kvm_lapic *apic)
|
|||
|
||||
hrtimer_start(&apic->lapic_timer.timer,
|
||||
apic->lapic_timer.target_expiration,
|
||||
HRTIMER_MODE_ABS);
|
||||
HRTIMER_MODE_ABS_HARD);
|
||||
}
|
||||
|
||||
bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu)
|
||||
|
|
|
@ -1933,14 +1933,6 @@ static void sev_clflush_pages(struct page *pages[], unsigned long npages)
|
|||
static void __unregister_enc_region_locked(struct kvm *kvm,
|
||||
struct enc_region *region)
|
||||
{
|
||||
/*
|
||||
* The guest may change the memory encryption attribute from C=0 -> C=1
|
||||
* or vice versa for this memory range. Lets make sure caches are
|
||||
* flushed to ensure that guest data gets written into memory with
|
||||
* correct C-bit.
|
||||
*/
|
||||
sev_clflush_pages(region->pages, region->npages);
|
||||
|
||||
sev_unpin_memory(kvm, region->pages, region->npages);
|
||||
list_del(®ion->list);
|
||||
kfree(region);
|
||||
|
@ -1970,6 +1962,13 @@ static void sev_vm_destroy(struct kvm *kvm)
|
|||
|
||||
mutex_lock(&kvm->lock);
|
||||
|
||||
/*
|
||||
* Ensure that all guest tagged cache entries are flushed before
|
||||
* releasing the pages back to the system for use. CLFLUSH will
|
||||
* not do this, so issue a WBINVD.
|
||||
*/
|
||||
wbinvd_on_all_cpus();
|
||||
|
||||
/*
|
||||
* if userspace was terminated before unregistering the memory regions
|
||||
* then lets unpin all the registered memory.
|
||||
|
@ -7158,6 +7157,9 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
|
|||
if (!svm_sev_enabled())
|
||||
return -ENOTTY;
|
||||
|
||||
if (!argp)
|
||||
return 0;
|
||||
|
||||
if (copy_from_user(&sev_cmd, argp, sizeof(struct kvm_sev_cmd)))
|
||||
return -EFAULT;
|
||||
|
||||
|
@ -7285,6 +7287,13 @@ static int svm_unregister_enc_region(struct kvm *kvm,
|
|||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that all guest tagged cache entries are flushed before
|
||||
* releasing the pages back to the system for use. CLFLUSH will
|
||||
* not do this, so issue a WBINVD.
|
||||
*/
|
||||
wbinvd_on_all_cpus();
|
||||
|
||||
__unregister_enc_region_locked(kvm, region);
|
||||
|
||||
mutex_unlock(&kvm->lock);
|
||||
|
|
|
@ -6287,7 +6287,7 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu)
|
|||
#endif
|
||||
ASM_CALL_CONSTRAINT
|
||||
:
|
||||
THUNK_TARGET(entry),
|
||||
[thunk_target]"r"(entry),
|
||||
[ss]"i"(__KERNEL_DS),
|
||||
[cs]"i"(__KERNEL_CS)
|
||||
);
|
||||
|
|
|
@ -1554,7 +1554,10 @@ EXPORT_SYMBOL_GPL(kvm_emulate_wrmsr);
|
|||
*/
|
||||
static int handle_fastpath_set_x2apic_icr_irqoff(struct kvm_vcpu *vcpu, u64 data)
|
||||
{
|
||||
if (lapic_in_kernel(vcpu) && apic_x2apic_mode(vcpu->arch.apic) &&
|
||||
if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(vcpu->arch.apic))
|
||||
return 1;
|
||||
|
||||
if (((data & APIC_SHORT_MASK) == APIC_DEST_NOSHORT) &&
|
||||
((data & APIC_DEST_MASK) == APIC_DEST_PHYSICAL) &&
|
||||
((data & APIC_MODE_MASK) == APIC_DM_FIXED)) {
|
||||
|
||||
|
@ -2444,7 +2447,6 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
|
|||
vcpu->hv_clock.tsc_timestamp = tsc_timestamp;
|
||||
vcpu->hv_clock.system_time = kernel_ns + v->kvm->arch.kvmclock_offset;
|
||||
vcpu->last_guest_tsc = tsc_timestamp;
|
||||
WARN_ON((s64)vcpu->hv_clock.system_time < 0);
|
||||
|
||||
/* If the host uses TSC clocksource, then it is stable */
|
||||
pvclock_flags = 0;
|
||||
|
|
Loading…
Reference in a new issue