mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
Mostly cleanups, except:
- dynamic addition of vfio passthrough devices - implementation of HAVE_SYSCALL_TRACEPOINTS -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEpeA8sTs3M8SN2hR410qiO8sPaAAFAmiIm+YACgkQ10qiO8sP aADNGw/8D+3rMvTcJyFPwZi3UAxyV/PQNFGe2UhPZf9SZlXKrzoku/+FaUtw66YG frmQb3tHbprJRdT1rb1bULtwRNpXifNf+LPcb4cjoci1z1qywZ5z5v8hfxYrjufr pw1f8Eev++EPDyQ6OdLMlZa5Sry0Cuf9xTC61ThCv95iUGVbGliPgMuA3LRf10Pd 99yZfzWv/K9MU53m+xtBNaO41Mn7B/ir6fam7Jrs2MpbeyJgB3bwETZs7ZI6P1sp +g+FtjQUdn5tFWBJ3Jpne0AH3dTU8cSN+QZ/1b1BzTVyyVDOvcXvDO5/XUAP51/Y TMeI3a1Y8LLzDHBluwHd3dwbmMMZjlvvvIXrexfuhA2bJWya9Jd1HSEh3l4CNIIB jnxNAHcswY6kClpCf3HTbdMZS5VqFZ1IUH1zcli62EtvpbCxVt82lgKuPBYs/p83 5vv59tr4n4ge6jm0P7WoyL75rsrY5y+XOtmbU1c3x5QzN6vCtGvVIqWdeZZMG2ge rXFUSdyRqmw4B3RvNGQ4jLhp6RZXUWDvamv/PfzU2vV1mz/wVo3nfGaX8olp5Fyq 7CxZegnO40wH1nj5JBP5zhh+AytSz0cbqPmZNfDYLA3lWnrJCANcmHRTkBxbN2+U PsBimJ5Y6xWZdaaxQjlrHkVHy8Iv8meDvwlJB55N3uY2lrGcndM= =WP21 -----END PGP SIGNATURE----- Merge tag 'uml-for-linux-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux Pull uml updates from Johannes Berg: "Mostly cleanups, except: - dynamic addition of vfio passthrough devices - implementation of HAVE_SYSCALL_TRACEPOINTS" * tag 'uml-for-linux-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux: um: Replace __ASSEMBLY__ with __ASSEMBLER__ in the usermode headers um: Stop tracking stub's PID via userspace_pid[] um: Remove the pid parameter of handle_trap() um: Use err consistently in userspace() um: vfio: Support adding devices via mconsole um: rtc: Avoid shadowing err in uml_rtc_start() um: Avoid redefining ARCH_HAS_CACHE_LINE_SIZE um: Make mm_list and mm_list_lock static um: Make unscheduled_userspace_iterations static um: Re-evaluate thread flags repeatedly um: simplify syscall header files um/ptrace: Implement HAVE_SYSCALL_TRACEPOINTS um/x86: Add system call table to header file um: virt-pci: Switch to msi_create_parent_irq_domain() um: virtio_pcidev: Rename UM_PCI_STAT_WAITING
This commit is contained in:
commit
beb6c8326e
@ -6,6 +6,7 @@ config UML
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
|
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
|
||||||
|
select ARCH_HAS_CACHE_LINE_SIZE
|
||||||
select ARCH_HAS_CPU_FINALIZE_INIT
|
select ARCH_HAS_CPU_FINALIZE_INIT
|
||||||
select ARCH_HAS_FORTIFY_SOURCE
|
select ARCH_HAS_FORTIFY_SOURCE
|
||||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||||
@ -35,6 +36,7 @@ config UML
|
|||||||
select HAVE_RUST
|
select HAVE_RUST
|
||||||
select ARCH_HAS_UBSAN
|
select ARCH_HAS_UBSAN
|
||||||
select HAVE_ARCH_TRACEHOOK
|
select HAVE_ARCH_TRACEHOOK
|
||||||
|
select HAVE_SYSCALL_TRACEPOINTS
|
||||||
select THREAD_INFO_IN_TASK
|
select THREAD_INFO_IN_TASK
|
||||||
|
|
||||||
config MMU
|
config MMU
|
||||||
@ -82,9 +84,6 @@ config NR_CPUS
|
|||||||
range 1 1
|
range 1 1
|
||||||
default 1
|
default 1
|
||||||
|
|
||||||
config ARCH_HAS_CACHE_LINE_SIZE
|
|
||||||
def_bool y
|
|
||||||
|
|
||||||
source "arch/$(HEADER_ARCH)/um/Kconfig"
|
source "arch/$(HEADER_ARCH)/um/Kconfig"
|
||||||
|
|
||||||
config MAY_HAVE_RUNTIME_DEPS
|
config MAY_HAVE_RUNTIME_DEPS
|
||||||
|
@ -160,6 +160,7 @@ config UML_RTC
|
|||||||
config UML_PCI
|
config UML_PCI
|
||||||
bool
|
bool
|
||||||
select FORCE_PCI
|
select FORCE_PCI
|
||||||
|
select IRQ_MSI_LIB
|
||||||
select UML_IOMEM_EMULATION
|
select UML_IOMEM_EMULATION
|
||||||
select UML_DMA_EMULATION
|
select UML_DMA_EMULATION
|
||||||
select PCI_MSI
|
select PCI_MSI
|
||||||
|
@ -28,7 +28,7 @@ int uml_rtc_start(bool timetravel)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (timetravel) {
|
if (timetravel) {
|
||||||
int err = os_pipe(uml_rtc_irq_fds, 1, 1);
|
err = os_pipe(uml_rtc_irq_fds, 1, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
} else {
|
} else {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <os.h>
|
#include <os.h>
|
||||||
|
|
||||||
|
#include "mconsole_kern.h"
|
||||||
#include "virt-pci.h"
|
#include "virt-pci.h"
|
||||||
#include "vfio_user.h"
|
#include "vfio_user.h"
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ static LIST_HEAD(uml_vfio_groups);
|
|||||||
static DEFINE_MUTEX(uml_vfio_groups_mtx);
|
static DEFINE_MUTEX(uml_vfio_groups_mtx);
|
||||||
|
|
||||||
static LIST_HEAD(uml_vfio_devices);
|
static LIST_HEAD(uml_vfio_devices);
|
||||||
|
static DEFINE_MUTEX(uml_vfio_devices_mtx);
|
||||||
|
|
||||||
static int uml_vfio_set_container(int group_fd)
|
static int uml_vfio_set_container(int group_fd)
|
||||||
{
|
{
|
||||||
@ -581,32 +583,44 @@ static struct uml_vfio_device *uml_vfio_find_device(const char *device)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uml_vfio_cmdline_set(const char *device, const struct kernel_param *kp)
|
static struct uml_vfio_device *uml_vfio_add_device(const char *device)
|
||||||
{
|
{
|
||||||
struct uml_vfio_device *dev;
|
struct uml_vfio_device *dev;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
guard(mutex)(¨_vfio_devices_mtx);
|
||||||
|
|
||||||
if (uml_vfio_container.fd < 0) {
|
if (uml_vfio_container.fd < 0) {
|
||||||
fd = uml_vfio_user_open_container();
|
fd = uml_vfio_user_open_container();
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return fd;
|
return ERR_PTR(fd);
|
||||||
uml_vfio_container.fd = fd;
|
uml_vfio_container.fd = fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uml_vfio_find_device(device))
|
if (uml_vfio_find_device(device))
|
||||||
return -EEXIST;
|
return ERR_PTR(-EEXIST);
|
||||||
|
|
||||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
dev->name = kstrdup(device, GFP_KERNEL);
|
dev->name = kstrdup(device, GFP_KERNEL);
|
||||||
if (!dev->name) {
|
if (!dev->name) {
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
return -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_tail(&dev->list, ¨_vfio_devices);
|
list_add_tail(&dev->list, ¨_vfio_devices);
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uml_vfio_cmdline_set(const char *device, const struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
struct uml_vfio_device *dev;
|
||||||
|
|
||||||
|
dev = uml_vfio_add_device(device);
|
||||||
|
if (IS_ERR(dev))
|
||||||
|
return PTR_ERR(dev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,6 +643,42 @@ __uml_help(uml_vfio_cmdline_param_ops,
|
|||||||
" through multiple PCI devices to UML.\n\n"
|
" through multiple PCI devices to UML.\n\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static int uml_vfio_mc_config(char *str, char **error_out)
|
||||||
|
{
|
||||||
|
struct uml_vfio_device *dev;
|
||||||
|
|
||||||
|
if (*str != '=') {
|
||||||
|
*error_out = "Invalid config";
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
str += 1;
|
||||||
|
|
||||||
|
dev = uml_vfio_add_device(str);
|
||||||
|
if (IS_ERR(dev))
|
||||||
|
return PTR_ERR(dev);
|
||||||
|
uml_vfio_open_device(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uml_vfio_mc_id(char **str, int *start_out, int *end_out)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uml_vfio_mc_remove(int n, char **error_out)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mc_device uml_vfio_mc = {
|
||||||
|
.list = LIST_HEAD_INIT(uml_vfio_mc.list),
|
||||||
|
.name = "vfio_uml.device",
|
||||||
|
.config = uml_vfio_mc_config,
|
||||||
|
.get_config = NULL,
|
||||||
|
.id = uml_vfio_mc_id,
|
||||||
|
.remove = uml_vfio_mc_remove,
|
||||||
|
};
|
||||||
|
|
||||||
static int __init uml_vfio_init(void)
|
static int __init uml_vfio_init(void)
|
||||||
{
|
{
|
||||||
struct uml_vfio_device *dev, *n;
|
struct uml_vfio_device *dev, *n;
|
||||||
@ -639,6 +689,8 @@ static int __init uml_vfio_init(void)
|
|||||||
list_for_each_entry_safe(dev, n, ¨_vfio_devices, list)
|
list_for_each_entry_safe(dev, n, ¨_vfio_devices, list)
|
||||||
uml_vfio_open_device(dev);
|
uml_vfio_open_device(dev);
|
||||||
|
|
||||||
|
mconsole_register_dev(¨_vfio_mc);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
late_initcall(uml_vfio_init);
|
late_initcall(uml_vfio_init);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/logic_iomem.h>
|
#include <linux/logic_iomem.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/irqchip/irq-msi-lib.h>
|
||||||
#include <linux/irqdomain.h>
|
#include <linux/irqdomain.h>
|
||||||
#include <linux/msi.h>
|
#include <linux/msi.h>
|
||||||
#include <linux/unaligned.h>
|
#include <linux/unaligned.h>
|
||||||
@ -29,7 +30,6 @@ static struct um_pci_device *um_pci_platform_device;
|
|||||||
static struct um_pci_device_reg um_pci_devices[MAX_DEVICES];
|
static struct um_pci_device_reg um_pci_devices[MAX_DEVICES];
|
||||||
static struct fwnode_handle *um_pci_fwnode;
|
static struct fwnode_handle *um_pci_fwnode;
|
||||||
static struct irq_domain *um_pci_inner_domain;
|
static struct irq_domain *um_pci_inner_domain;
|
||||||
static struct irq_domain *um_pci_msi_domain;
|
|
||||||
static unsigned long um_pci_msi_used[BITS_TO_LONGS(MAX_MSI_VECTORS)];
|
static unsigned long um_pci_msi_used[BITS_TO_LONGS(MAX_MSI_VECTORS)];
|
||||||
|
|
||||||
static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset,
|
static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset,
|
||||||
@ -400,21 +400,24 @@ static void um_pci_inner_domain_free(struct irq_domain *domain,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct irq_domain_ops um_pci_inner_domain_ops = {
|
static const struct irq_domain_ops um_pci_inner_domain_ops = {
|
||||||
|
.select = msi_lib_irq_domain_select,
|
||||||
.alloc = um_pci_inner_domain_alloc,
|
.alloc = um_pci_inner_domain_alloc,
|
||||||
.free = um_pci_inner_domain_free,
|
.free = um_pci_inner_domain_free,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct irq_chip um_pci_msi_irq_chip = {
|
#define UM_PCI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
|
||||||
.name = "UM virtual PCIe MSI",
|
MSI_FLAG_USE_DEF_CHIP_OPS | \
|
||||||
.irq_mask = pci_msi_mask_irq,
|
MSI_FLAG_NO_AFFINITY)
|
||||||
.irq_unmask = pci_msi_unmask_irq,
|
#define UM_PCI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
|
||||||
};
|
MSI_FLAG_PCI_MSIX)
|
||||||
|
|
||||||
static struct msi_domain_info um_pci_msi_domain_info = {
|
static const struct msi_parent_ops um_pci_msi_parent_ops = {
|
||||||
.flags = MSI_FLAG_USE_DEF_DOM_OPS |
|
.required_flags = UM_PCI_MSI_FLAGS_REQUIRED,
|
||||||
MSI_FLAG_USE_DEF_CHIP_OPS |
|
.supported_flags = UM_PCI_MSI_FLAGS_SUPPORTED,
|
||||||
MSI_FLAG_PCI_MSIX,
|
.bus_select_token = DOMAIN_BUS_NEXUS,
|
||||||
.chip = &um_pci_msi_irq_chip,
|
.bus_select_mask = MATCH_PCI_MSI,
|
||||||
|
.prefix = "UM-virtual-",
|
||||||
|
.init_dev_msi_info = msi_lib_init_dev_msi_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct resource busn_resource = {
|
static struct resource busn_resource = {
|
||||||
@ -559,17 +562,14 @@ static int __init um_pci_init(void)
|
|||||||
goto free;
|
goto free;
|
||||||
}
|
}
|
||||||
|
|
||||||
um_pci_inner_domain = irq_domain_create_linear(um_pci_fwnode, MAX_MSI_VECTORS,
|
struct irq_domain_info info = {
|
||||||
&um_pci_inner_domain_ops, NULL);
|
.fwnode = um_pci_fwnode,
|
||||||
if (!um_pci_inner_domain) {
|
.ops = &um_pci_inner_domain_ops,
|
||||||
err = -ENOMEM;
|
.size = MAX_MSI_VECTORS,
|
||||||
goto free;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
um_pci_msi_domain = pci_msi_create_irq_domain(um_pci_fwnode,
|
um_pci_inner_domain = msi_create_parent_irq_domain(&info, &um_pci_msi_parent_ops);
|
||||||
&um_pci_msi_domain_info,
|
if (!um_pci_inner_domain) {
|
||||||
um_pci_inner_domain);
|
|
||||||
if (!um_pci_msi_domain) {
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto free;
|
goto free;
|
||||||
}
|
}
|
||||||
@ -611,7 +611,6 @@ device_initcall(um_pci_init);
|
|||||||
|
|
||||||
static void __exit um_pci_exit(void)
|
static void __exit um_pci_exit(void)
|
||||||
{
|
{
|
||||||
irq_domain_remove(um_pci_msi_domain);
|
|
||||||
irq_domain_remove(um_pci_inner_domain);
|
irq_domain_remove(um_pci_inner_domain);
|
||||||
pci_free_resource_list(&bridge->windows);
|
pci_free_resource_list(&bridge->windows);
|
||||||
pci_free_host_bridge(bridge);
|
pci_free_host_bridge(bridge);
|
||||||
|
@ -42,7 +42,7 @@ struct virtio_pcidev_device {
|
|||||||
void *extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS + 1];
|
void *extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS + 1];
|
||||||
DECLARE_BITMAP(used_bufs, VIRTIO_PCIDEV_WRITE_BUFS);
|
DECLARE_BITMAP(used_bufs, VIRTIO_PCIDEV_WRITE_BUFS);
|
||||||
|
|
||||||
#define UM_PCI_STAT_WAITING 0
|
#define VIRTIO_PCIDEV_STAT_WAITING 0
|
||||||
unsigned long status;
|
unsigned long status;
|
||||||
|
|
||||||
bool platform;
|
bool platform;
|
||||||
@ -172,7 +172,7 @@ static int virtio_pcidev_send_cmd(struct virtio_pcidev_device *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* kick and poll for getting a response on the queue */
|
/* kick and poll for getting a response on the queue */
|
||||||
set_bit(UM_PCI_STAT_WAITING, &dev->status);
|
set_bit(VIRTIO_PCIDEV_STAT_WAITING, &dev->status);
|
||||||
virtqueue_kick(dev->cmd_vq);
|
virtqueue_kick(dev->cmd_vq);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ static int virtio_pcidev_send_cmd(struct virtio_pcidev_device *dev,
|
|||||||
}
|
}
|
||||||
udelay(1);
|
udelay(1);
|
||||||
}
|
}
|
||||||
clear_bit(UM_PCI_STAT_WAITING, &dev->status);
|
clear_bit(VIRTIO_PCIDEV_STAT_WAITING, &dev->status);
|
||||||
|
|
||||||
if (bounce_out)
|
if (bounce_out)
|
||||||
memcpy(out, buf->data, out_size);
|
memcpy(out, buf->data, out_size);
|
||||||
@ -439,7 +439,7 @@ static void virtio_pcidev_cmd_vq_cb(struct virtqueue *vq)
|
|||||||
void *cmd;
|
void *cmd;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (test_bit(UM_PCI_STAT_WAITING, &dev->status))
|
if (test_bit(VIRTIO_PCIDEV_STAT_WAITING, &dev->status))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while ((cmd = virtqueue_get_buf(vq, &len)))
|
while ((cmd = virtqueue_get_buf(vq, &len)))
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
|
||||||
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
#if defined(__KERNEL__) && !defined(__ASSEMBLER__)
|
||||||
|
|
||||||
#include <asm/asm.h>
|
#include <asm/asm.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
@ -137,5 +137,5 @@ t_no:
|
|||||||
#define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
|
#define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
|
||||||
boot_cpu_data.x86_model
|
boot_cpu_data.x86_model
|
||||||
|
|
||||||
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
|
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLER__) */
|
||||||
#endif /* _ASM_UM_CPUFEATURE_H */
|
#endif /* _ASM_UM_CPUFEATURE_H */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
struct task_struct;
|
struct task_struct;
|
||||||
extern struct task_struct *cpu_tasks[NR_CPUS];
|
extern struct task_struct *cpu_tasks[NR_CPUS];
|
||||||
@ -18,6 +18,6 @@ static __always_inline struct task_struct *get_current(void)
|
|||||||
|
|
||||||
#define current get_current()
|
#define current get_current()
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
#endif /* __ASM_CURRENT_H */
|
#endif /* __ASM_CURRENT_H */
|
||||||
|
@ -16,11 +16,6 @@
|
|||||||
#define activate_mm activate_mm
|
#define activate_mm activate_mm
|
||||||
static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
|
static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* This is called by fs/exec.c and sys_unshare()
|
|
||||||
* when the new ->mm is used for the first time.
|
|
||||||
*/
|
|
||||||
__switch_mm(&new->context.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||||
@ -31,8 +26,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|||||||
if (prev != next) {
|
if (prev != next) {
|
||||||
cpumask_clear_cpu(cpu, mm_cpumask(prev));
|
cpumask_clear_cpu(cpu, mm_cpumask(prev));
|
||||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||||
if(next != &init_mm)
|
|
||||||
__switch_mm(&next->context.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include <vdso/page.h>
|
#include <vdso/page.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
struct page;
|
struct page;
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ extern unsigned long uml_physmem;
|
|||||||
#include <asm-generic/memory_model.h>
|
#include <asm-generic/memory_model.h>
|
||||||
#include <asm-generic/getorder.h>
|
#include <asm-generic/getorder.h>
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
#define __HAVE_ARCH_GATE_AREA 1
|
#define __HAVE_ARCH_GATE_AREA 1
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#ifndef __UM_PTRACE_GENERIC_H
|
#ifndef __UM_PTRACE_GENERIC_H
|
||||||
#define __UM_PTRACE_GENERIC_H
|
#define __UM_PTRACE_GENERIC_H
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
#include <sysdep/ptrace.h>
|
#include <sysdep/ptrace.h>
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#define THREAD_SIZE_ORDER CONFIG_KERNEL_STACK_ORDER
|
#define THREAD_SIZE_ORDER CONFIG_KERNEL_STACK_ORDER
|
||||||
#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
|
#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
@ -43,6 +43,8 @@ struct thread_info {
|
|||||||
#define TIF_NOTIFY_RESUME 8
|
#define TIF_NOTIFY_RESUME 8
|
||||||
#define TIF_SECCOMP 9 /* secure computing */
|
#define TIF_SECCOMP 9 /* secure computing */
|
||||||
#define TIF_SINGLESTEP 10 /* single stepping userspace */
|
#define TIF_SINGLESTEP 10 /* single stepping userspace */
|
||||||
|
#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
|
||||||
|
|
||||||
|
|
||||||
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
|
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
|
||||||
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
|
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
|
||||||
@ -50,7 +52,11 @@ struct thread_info {
|
|||||||
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
|
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
|
||||||
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
|
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
|
||||||
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
|
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
|
||||||
|
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
|
||||||
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
|
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
|
||||||
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
|
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
|
||||||
|
|
||||||
|
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL | \
|
||||||
|
_TIF_NOTIFY_RESUME)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#define STUB_DATA_PAGES 2 /* must be a power of two */
|
#define STUB_DATA_PAGES 2 /* must be a power of two */
|
||||||
#define STUB_END (STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE)
|
#define STUB_END (STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE)
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
#include <sysdep/ptrace.h>
|
#include <sysdep/ptrace.h>
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@ struct mm_id {
|
|||||||
int syscall_fd_map[STUB_MAX_FDS];
|
int syscall_fd_map[STUB_MAX_FDS];
|
||||||
};
|
};
|
||||||
|
|
||||||
void __switch_mm(struct mm_id *mm_idp);
|
|
||||||
|
|
||||||
void notify_mm_kill(int pid);
|
void notify_mm_kill(int pid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <sysdep/ptrace.h>
|
#include <sysdep/ptrace.h>
|
||||||
|
|
||||||
extern int using_seccomp;
|
extern int using_seccomp;
|
||||||
extern int userspace_pid[];
|
|
||||||
|
|
||||||
extern void new_thread_handler(void);
|
extern void new_thread_handler(void);
|
||||||
extern void handle_syscall(struct uml_pt_regs *regs);
|
extern void handle_syscall(struct uml_pt_regs *regs);
|
||||||
|
@ -26,8 +26,6 @@ void flush_thread(void)
|
|||||||
|
|
||||||
get_safe_registers(current_pt_regs()->regs.gp,
|
get_safe_registers(current_pt_regs()->regs.gp,
|
||||||
current_pt_regs()->regs.fp);
|
current_pt_regs()->regs.fp);
|
||||||
|
|
||||||
__switch_mm(¤t->mm->context.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
|
void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
|
||||||
|
@ -82,14 +82,18 @@ struct task_struct *__switch_to(struct task_struct *from, struct task_struct *to
|
|||||||
void interrupt_end(void)
|
void interrupt_end(void)
|
||||||
{
|
{
|
||||||
struct pt_regs *regs = ¤t->thread.regs;
|
struct pt_regs *regs = ¤t->thread.regs;
|
||||||
|
unsigned long thread_flags;
|
||||||
|
|
||||||
if (need_resched())
|
thread_flags = read_thread_flags();
|
||||||
|
while (thread_flags & _TIF_WORK_MASK) {
|
||||||
|
if (thread_flags & _TIF_NEED_RESCHED)
|
||||||
schedule();
|
schedule();
|
||||||
if (test_thread_flag(TIF_SIGPENDING) ||
|
if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
|
||||||
test_thread_flag(TIF_NOTIFY_SIGNAL))
|
|
||||||
do_signal(regs);
|
do_signal(regs);
|
||||||
if (test_thread_flag(TIF_NOTIFY_RESUME))
|
if (thread_flags & _TIF_NOTIFY_RESUME)
|
||||||
resume_user_mode_work(regs);
|
resume_user_mode_work(regs);
|
||||||
|
thread_flags = read_thread_flags();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_current_pid(void)
|
int get_current_pid(void)
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <asm/ptrace-abi.h>
|
#include <asm/ptrace-abi.h>
|
||||||
|
|
||||||
|
#define CREATE_TRACE_POINTS
|
||||||
|
#include <trace/events/syscalls.h>
|
||||||
|
|
||||||
void user_enable_single_step(struct task_struct *child)
|
void user_enable_single_step(struct task_struct *child)
|
||||||
{
|
{
|
||||||
set_tsk_thread_flag(child, TIF_SINGLESTEP);
|
set_tsk_thread_flag(child, TIF_SINGLESTEP);
|
||||||
@ -126,6 +129,9 @@ int syscall_trace_enter(struct pt_regs *regs)
|
|||||||
UPT_SYSCALL_ARG3(®s->regs),
|
UPT_SYSCALL_ARG3(®s->regs),
|
||||||
UPT_SYSCALL_ARG4(®s->regs));
|
UPT_SYSCALL_ARG4(®s->regs));
|
||||||
|
|
||||||
|
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
|
||||||
|
trace_sys_enter(regs, UPT_SYSCALL_NR(®s->regs));
|
||||||
|
|
||||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -142,6 +148,9 @@ void syscall_trace_leave(struct pt_regs *regs)
|
|||||||
if (test_thread_flag(TIF_SINGLESTEP))
|
if (test_thread_flag(TIF_SINGLESTEP))
|
||||||
send_sigtrap(®s->regs, 0);
|
send_sigtrap(®s->regs, 0);
|
||||||
|
|
||||||
|
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
|
||||||
|
trace_sys_exit(regs, PT_REGS_SYSCALL_RET(regs));
|
||||||
|
|
||||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
/* Ensure the stub_data struct covers the allocated area */
|
/* Ensure the stub_data struct covers the allocated area */
|
||||||
static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
|
static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
|
||||||
|
|
||||||
spinlock_t mm_list_lock;
|
static spinlock_t mm_list_lock;
|
||||||
struct list_head mm_list;
|
static struct list_head mm_list;
|
||||||
|
|
||||||
int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
|
@ -26,8 +26,6 @@ static int __init start_kernel_proc(void *unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int userspace_pid[];
|
|
||||||
|
|
||||||
static char cpu0_irqstack[THREAD_SIZE] __aligned(THREAD_SIZE);
|
static char cpu0_irqstack[THREAD_SIZE] __aligned(THREAD_SIZE);
|
||||||
|
|
||||||
int __init start_uml(void)
|
int __init start_uml(void)
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#include <kern_util.h>
|
#include <kern_util.h>
|
||||||
#include <sysdep/ptrace.h>
|
#include <sysdep/ptrace.h>
|
||||||
#include <sysdep/ptrace_user.h>
|
#include <sysdep/ptrace_user.h>
|
||||||
#include <sysdep/syscalls.h>
|
|
||||||
#include <linux/time-internal.h>
|
#include <linux/time-internal.h>
|
||||||
|
#include <asm/syscall.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <asm/delay.h>
|
#include <asm/delay.h>
|
||||||
|
|
||||||
@ -43,7 +43,14 @@ void handle_syscall(struct uml_pt_regs *r)
|
|||||||
tt_extra_sched_jiffies += 1;
|
tt_extra_sched_jiffies += 1;
|
||||||
|
|
||||||
if (syscall >= 0 && syscall < __NR_syscalls) {
|
if (syscall >= 0 && syscall < __NR_syscalls) {
|
||||||
unsigned long ret = EXECUTE_SYSCALL(syscall, regs);
|
unsigned long ret;
|
||||||
|
|
||||||
|
ret = (*sys_call_table[syscall])(UPT_SYSCALL_ARG1(®s->regs),
|
||||||
|
UPT_SYSCALL_ARG2(®s->regs),
|
||||||
|
UPT_SYSCALL_ARG3(®s->regs),
|
||||||
|
UPT_SYSCALL_ARG4(®s->regs),
|
||||||
|
UPT_SYSCALL_ARG5(®s->regs),
|
||||||
|
UPT_SYSCALL_ARG6(®s->regs));
|
||||||
|
|
||||||
PT_REGS_SET_SYSCALL_RETURN(regs, ret);
|
PT_REGS_SET_SYSCALL_RETURN(regs, ret);
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi)
|
|||||||
memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
|
memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_trap(int pid, struct uml_pt_regs *regs)
|
static void handle_trap(struct uml_pt_regs *regs)
|
||||||
{
|
{
|
||||||
if ((UPT_IP(regs) >= STUB_START) && (UPT_IP(regs) < STUB_END))
|
if ((UPT_IP(regs) >= STUB_START) && (UPT_IP(regs) < STUB_END))
|
||||||
fatal_sigsegv();
|
fatal_sigsegv();
|
||||||
@ -434,7 +434,6 @@ static int __init init_stub_exe_fd(void)
|
|||||||
__initcall(init_stub_exe_fd);
|
__initcall(init_stub_exe_fd);
|
||||||
|
|
||||||
int using_seccomp;
|
int using_seccomp;
|
||||||
int userspace_pid[NR_CPUS];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* start_userspace() - prepare a new userspace process
|
* start_userspace() - prepare a new userspace process
|
||||||
@ -548,12 +547,12 @@ out_close:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unscheduled_userspace_iterations;
|
static int unscheduled_userspace_iterations;
|
||||||
extern unsigned long tt_extra_sched_jiffies;
|
extern unsigned long tt_extra_sched_jiffies;
|
||||||
|
|
||||||
void userspace(struct uml_pt_regs *regs)
|
void userspace(struct uml_pt_regs *regs)
|
||||||
{
|
{
|
||||||
int err, status, op, pid = userspace_pid[0];
|
int err, status, op;
|
||||||
siginfo_t si_ptrace;
|
siginfo_t si_ptrace;
|
||||||
siginfo_t *si;
|
siginfo_t *si;
|
||||||
int sig;
|
int sig;
|
||||||
@ -562,6 +561,8 @@ void userspace(struct uml_pt_regs *regs)
|
|||||||
interrupt_end();
|
interrupt_end();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
struct mm_id *mm_id = current_mm_id();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When we are in time-travel mode, userspace can theoretically
|
* When we are in time-travel mode, userspace can theoretically
|
||||||
* do a *lot* of work without being scheduled. The problem with
|
* do a *lot* of work without being scheduled. The problem with
|
||||||
@ -590,14 +591,12 @@ void userspace(struct uml_pt_regs *regs)
|
|||||||
current_mm_sync();
|
current_mm_sync();
|
||||||
|
|
||||||
if (using_seccomp) {
|
if (using_seccomp) {
|
||||||
struct mm_id *mm_id = current_mm_id();
|
|
||||||
struct stub_data *proc_data = (void *) mm_id->stack;
|
struct stub_data *proc_data = (void *) mm_id->stack;
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = set_stub_state(regs, proc_data, singlestepping());
|
err = set_stub_state(regs, proc_data, singlestepping());
|
||||||
if (ret) {
|
if (err) {
|
||||||
printk(UM_KERN_ERR "%s - failed to set regs: %d",
|
printk(UM_KERN_ERR "%s - failed to set regs: %d",
|
||||||
__func__, ret);
|
__func__, err);
|
||||||
fatal_sigsegv();
|
fatal_sigsegv();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,10 +622,10 @@ void userspace(struct uml_pt_regs *regs)
|
|||||||
mm_id->syscall_data_len = 0;
|
mm_id->syscall_data_len = 0;
|
||||||
mm_id->syscall_fd_num = 0;
|
mm_id->syscall_fd_num = 0;
|
||||||
|
|
||||||
ret = get_stub_state(regs, proc_data, NULL);
|
err = get_stub_state(regs, proc_data, NULL);
|
||||||
if (ret) {
|
if (err) {
|
||||||
printk(UM_KERN_ERR "%s - failed to get regs: %d",
|
printk(UM_KERN_ERR "%s - failed to get regs: %d",
|
||||||
__func__, ret);
|
__func__, err);
|
||||||
fatal_sigsegv();
|
fatal_sigsegv();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,8 +644,10 @@ void userspace(struct uml_pt_regs *regs)
|
|||||||
GET_FAULTINFO_FROM_MC(regs->faultinfo, mcontext);
|
GET_FAULTINFO_FROM_MC(regs->faultinfo, mcontext);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
int pid = mm_id->pid;
|
||||||
|
|
||||||
/* Flush out any pending syscalls */
|
/* Flush out any pending syscalls */
|
||||||
err = syscall_stub_flush(current_mm_id());
|
err = syscall_stub_flush(mm_id);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == -ENOMEM)
|
if (err == -ENOMEM)
|
||||||
report_enomem();
|
report_enomem();
|
||||||
@ -756,7 +757,7 @@ void userspace(struct uml_pt_regs *regs)
|
|||||||
handle_syscall(regs);
|
handle_syscall(regs);
|
||||||
break;
|
break;
|
||||||
case SIGTRAP + 0x80:
|
case SIGTRAP + 0x80:
|
||||||
handle_trap(pid, regs);
|
handle_trap(regs);
|
||||||
break;
|
break;
|
||||||
case SIGTRAP:
|
case SIGTRAP:
|
||||||
relay_signal(SIGTRAP, (struct siginfo *)si, regs, NULL);
|
relay_signal(SIGTRAP, (struct siginfo *)si, regs, NULL);
|
||||||
@ -777,7 +778,6 @@ void userspace(struct uml_pt_regs *regs)
|
|||||||
__func__, sig);
|
__func__, sig);
|
||||||
fatal_sigsegv();
|
fatal_sigsegv();
|
||||||
}
|
}
|
||||||
pid = userspace_pid[0];
|
|
||||||
interrupt_end();
|
interrupt_end();
|
||||||
|
|
||||||
/* Avoid -ERESTARTSYS handling in host */
|
/* Avoid -ERESTARTSYS handling in host */
|
||||||
@ -902,8 +902,3 @@ void reboot_skas(void)
|
|||||||
block_signals_trace();
|
block_signals_trace();
|
||||||
UML_LONGJMP(&initial_jmpbuf, noreboot ? INIT_JMP_HALT : INIT_JMP_REBOOT);
|
UML_LONGJMP(&initial_jmpbuf, noreboot ? INIT_JMP_HALT : INIT_JMP_REBOOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __switch_mm(struct mm_id *mm_idp)
|
|
||||||
{
|
|
||||||
userspace_pid[0] = mm_idp->pid;
|
|
||||||
}
|
|
||||||
|
@ -9,6 +9,8 @@ typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
|
|||||||
unsigned long, unsigned long,
|
unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long);
|
unsigned long, unsigned long);
|
||||||
|
|
||||||
|
extern const sys_call_ptr_t sys_call_table[];
|
||||||
|
|
||||||
static inline int syscall_get_arch(struct task_struct *task)
|
static inline int syscall_get_arch(struct task_struct *task)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
@ -44,18 +44,6 @@
|
|||||||
#include "ptrace_64.h"
|
#include "ptrace_64.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct syscall_args {
|
|
||||||
unsigned long args[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SYSCALL_ARGS(r) ((struct syscall_args) \
|
|
||||||
{ .args = { UPT_SYSCALL_ARG1(r), \
|
|
||||||
UPT_SYSCALL_ARG2(r), \
|
|
||||||
UPT_SYSCALL_ARG3(r), \
|
|
||||||
UPT_SYSCALL_ARG4(r), \
|
|
||||||
UPT_SYSCALL_ARG5(r), \
|
|
||||||
UPT_SYSCALL_ARG6(r) } } )
|
|
||||||
|
|
||||||
extern unsigned long host_fp_size;
|
extern unsigned long host_fp_size;
|
||||||
|
|
||||||
struct uml_pt_regs {
|
struct uml_pt_regs {
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifdef __i386__
|
|
||||||
#include "syscalls_32.h"
|
|
||||||
#else
|
|
||||||
#include "syscalls_64.h"
|
|
||||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
|
||||||
* Licensed under the GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <asm/unistd.h>
|
|
||||||
#include <sysdep/ptrace.h>
|
|
||||||
|
|
||||||
typedef long syscall_handler_t(struct syscall_args);
|
|
||||||
|
|
||||||
extern syscall_handler_t *sys_call_table[];
|
|
||||||
|
|
||||||
#define EXECUTE_SYSCALL(syscall, regs) \
|
|
||||||
((*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs))
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003 PathScale, Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SYSDEP_X86_64_SYSCALLS_H__
|
|
||||||
#define __SYSDEP_X86_64_SYSCALLS_H__
|
|
||||||
|
|
||||||
#include <linux/msg.h>
|
|
||||||
#include <linux/shm.h>
|
|
||||||
|
|
||||||
typedef long syscall_handler_t(long, long, long, long, long, long);
|
|
||||||
|
|
||||||
extern syscall_handler_t *sys_call_table[];
|
|
||||||
|
|
||||||
#define EXECUTE_SYSCALL(syscall, regs) \
|
|
||||||
(((*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \
|
|
||||||
UPT_SYSCALL_ARG2(®s->regs), \
|
|
||||||
UPT_SYSCALL_ARG3(®s->regs), \
|
|
||||||
UPT_SYSCALL_ARG4(®s->regs), \
|
|
||||||
UPT_SYSCALL_ARG5(®s->regs), \
|
|
||||||
UPT_SYSCALL_ARG6(®s->regs)))
|
|
||||||
|
|
||||||
extern syscall_handler_t sys_modify_ldt;
|
|
||||||
extern syscall_handler_t sys_arch_prctl;
|
|
||||||
|
|
||||||
#endif
|
|
@ -186,7 +186,7 @@ int arch_switch_tls(struct task_struct *to)
|
|||||||
/*
|
/*
|
||||||
* We have no need whatsoever to switch TLS for kernel threads; beyond
|
* We have no need whatsoever to switch TLS for kernel threads; beyond
|
||||||
* that, that would also result in us calling os_set_thread_area with
|
* that, that would also result in us calling os_set_thread_area with
|
||||||
* userspace_pid[cpu] == 0, which gives an error.
|
* task->mm == NULL, which would cause a crash.
|
||||||
*/
|
*/
|
||||||
if (likely(to->mm))
|
if (likely(to->mm))
|
||||||
return load_TLS(O_FORCE, to);
|
return load_TLS(O_FORCE, to);
|
||||||
|
Loading…
Reference in New Issue
Block a user