Commit 3f0d6ecd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'core-entry-2020-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull generic kernel entry/exit code from Thomas Gleixner:
 "Generic implementation of common syscall, interrupt and exception
  entry/exit functionality based on the recent X86 effort to ensure
  correctness of entry/exit vs RCU and instrumentation.

  As this functionality and the required entry/exit sequences are not
  architecture specific, sharing them allows other architectures to
  benefit instead of copying the same code over and over again.

  This branch was kept standalone to allow others to work on it. The
  conversion of x86 comes in a seperate pull request which obviously is
  based on this branch"

* tag 'core-entry-2020-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  entry: Correct __secure_computing() stub
  entry: Correct 'noinstr' attributes
  entry: Provide infrastructure for work before transitioning to guest mode
  entry: Provide generic interrupt entry/exit code
  entry: Provide generic syscall exit function
  entry: Provide generic syscall entry functionality
  seccomp: Provide stub for __secure_computing()
parents 442489c2 3135f5b7
...@@ -27,6 +27,9 @@ config HAVE_IMA_KEXEC ...@@ -27,6 +27,9 @@ config HAVE_IMA_KEXEC
config HOTPLUG_SMT config HOTPLUG_SMT
bool bool
config GENERIC_ENTRY
bool
config OPROFILE config OPROFILE
tristate "OProfile system profiling" tristate "OProfile system profiling"
depends on PROFILING depends on PROFILING
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_ENTRYKVM_H
#define __LINUX_ENTRYKVM_H
#include <linux/entry-common.h>
/* Transfer to guest mode work */
#ifdef CONFIG_KVM_XFER_TO_GUEST_WORK
#ifndef ARCH_XFER_TO_GUEST_MODE_WORK
# define ARCH_XFER_TO_GUEST_MODE_WORK (0)
#endif
#define XFER_TO_GUEST_MODE_WORK \
(_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
_TIF_NOTIFY_RESUME | ARCH_XFER_TO_GUEST_MODE_WORK)
struct kvm_vcpu;
/**
* arch_xfer_to_guest_mode_handle_work - Architecture specific xfer to guest
* mode work handling function.
* @vcpu: Pointer to current's VCPU data
* @ti_work: Cached TIF flags gathered in xfer_to_guest_mode_handle_work()
*
* Invoked from xfer_to_guest_mode_handle_work(). Defaults to NOOP. Can be
* replaced by architecture specific code.
*/
static inline int arch_xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu,
unsigned long ti_work);
#ifndef arch_xfer_to_guest_mode_work
static inline int arch_xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu,
unsigned long ti_work)
{
return 0;
}
#endif
/**
* xfer_to_guest_mode_handle_work - Check and handle pending work which needs
* to be handled before going to guest mode
* @vcpu: Pointer to current's VCPU data
*
* Returns: 0 or an error code
*/
int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu);
/**
* __xfer_to_guest_mode_work_pending - Check if work is pending
*
* Returns: True if work pending, False otherwise.
*
* Bare variant of xfer_to_guest_mode_work_pending(). Can be called from
* interrupt enabled code for racy quick checks with care.
*/
static inline bool __xfer_to_guest_mode_work_pending(void)
{
unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
return !!(ti_work & XFER_TO_GUEST_MODE_WORK);
}
/**
* xfer_to_guest_mode_work_pending - Check if work is pending which needs to be
* handled before returning to guest mode
*
* Returns: True if work pending, False otherwise.
*
* Has to be invoked with interrupts disabled before the transition to
* guest mode.
*/
static inline bool xfer_to_guest_mode_work_pending(void)
{
lockdep_assert_irqs_disabled();
return __xfer_to_guest_mode_work_pending();
}
#endif /* CONFIG_KVM_XFER_TO_GUEST_WORK */
#endif
...@@ -1439,4 +1439,12 @@ int kvm_vm_create_worker_thread(struct kvm *kvm, kvm_vm_thread_fn_t thread_fn, ...@@ -1439,4 +1439,12 @@ int kvm_vm_create_worker_thread(struct kvm *kvm, kvm_vm_thread_fn_t thread_fn,
uintptr_t data, const char *name, uintptr_t data, const char *name,
struct task_struct **thread_ptr); struct task_struct **thread_ptr);
#ifdef CONFIG_KVM_XFER_TO_GUEST_WORK
static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu)
{
vcpu->run->exit_reason = KVM_EXIT_INTR;
vcpu->stat.signal_exits++;
}
#endif /* CONFIG_KVM_XFER_TO_GUEST_WORK */
#endif #endif
...@@ -64,9 +64,11 @@ static inline int seccomp_mode(struct seccomp *s) ...@@ -64,9 +64,11 @@ static inline int seccomp_mode(struct seccomp *s)
struct seccomp { }; struct seccomp { };
struct seccomp_filter { }; struct seccomp_filter { };
struct seccomp_data;
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
static inline int secure_computing(void) { return 0; } static inline int secure_computing(void) { return 0; }
static inline int __secure_computing(const struct seccomp_data *sd) { return 0; }
#else #else
static inline void secure_computing_strict(int this_syscall) { return; } static inline void secure_computing_strict(int this_syscall) { return; }
#endif #endif
......
...@@ -49,6 +49,7 @@ obj-y += irq/ ...@@ -49,6 +49,7 @@ obj-y += irq/
obj-y += rcu/ obj-y += rcu/
obj-y += livepatch/ obj-y += livepatch/
obj-y += dma/ obj-y += dma/
obj-y += entry/
obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
obj-$(CONFIG_FREEZER) += freezer.o obj-$(CONFIG_FREEZER) += freezer.o
......
# SPDX-License-Identifier: GPL-2.0
# Prevent the noinstr section from being pestered by sanitizer and other goodies
# as long as these things cannot be disabled per function.
KASAN_SANITIZE := n
UBSAN_SANITIZE := n
KCOV_INSTRUMENT := n
CFLAGS_REMOVE_common.o = -fstack-protector -fstack-protector-strong
CFLAGS_common.o += -fno-stack-protector
obj-$(CONFIG_GENERIC_ENTRY) += common.o
obj-$(CONFIG_KVM_XFER_TO_GUEST_WORK) += kvm.o
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
#include <linux/entry-kvm.h>
#include <linux/kvm_host.h>
static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
{
do {
int ret;
if (ti_work & _TIF_SIGPENDING) {
kvm_handle_signal_exit(vcpu);
return -EINTR;
}
if (ti_work & _TIF_NEED_RESCHED)
schedule();
if (ti_work & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(NULL);
}
ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
if (ret)
return ret;
ti_work = READ_ONCE(current_thread_info()->flags);
} while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched());
return 0;
}
int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
{
unsigned long ti_work;
/*
* This is invoked from the outer guest loop with interrupts and
* preemption enabled.
*
* KVM invokes xfer_to_guest_mode_work_pending() with interrupts
* disabled in the inner loop before going into guest mode. No need
* to disable interrupts here.
*/
ti_work = READ_ONCE(current_thread_info()->flags);
if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
return 0;
return xfer_to_guest_mode_work(vcpu, ti_work);
}
EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work);
...@@ -60,3 +60,6 @@ config HAVE_KVM_VCPU_RUN_PID_CHANGE ...@@ -60,3 +60,6 @@ config HAVE_KVM_VCPU_RUN_PID_CHANGE
config HAVE_KVM_NO_POLL config HAVE_KVM_NO_POLL
bool bool
config KVM_XFER_TO_GUEST_WORK
bool
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