Commit 9453b2d4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML updates from Richard Weinberger:

 - Improve support for non-glibc systems

 - Vector: Add support for scripting and dynamic tap devices

 - Various fixes for the vector networking driver

 - Various fixes for time travel mode

* tag 'for-linus-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
  um: vector: Add dynamic tap interfaces and scripting
  um: Clean up stacktrace dump
  um: Fix incorrect assumptions about max pid length
  um: Remove dead usage of TIF_IA32
  um: Remove redundant NULL check
  um: change sigio_spinlock to a mutex
  um: time-travel: Return the sequence number in ACK messages
  um: time-travel: Fix IRQ handling in time_travel_handle_message()
  um: Allow static linking for non-glibc implementations
  um: Some fixes to build UML with musl
  um: vector: Use GFP_ATOMIC under spin lock
  um: Fix null pointer dereference in vector_user_bpf
parents 42973127 f06885b3
...@@ -62,12 +62,12 @@ config NR_CPUS ...@@ -62,12 +62,12 @@ config NR_CPUS
source "arch/$(HEADER_ARCH)/um/Kconfig" source "arch/$(HEADER_ARCH)/um/Kconfig"
config FORBID_STATIC_LINK config MAY_HAVE_RUNTIME_DEPS
bool bool
config STATIC_LINK config STATIC_LINK
bool "Force a static link" bool "Force a static link"
depends on !FORBID_STATIC_LINK depends on CC_CAN_LINK_STATIC_NO_RUNTIME_DEPS || !MAY_HAVE_RUNTIME_DEPS
help help
This option gives you the ability to force a static link of UML. This option gives you the ability to force a static link of UML.
Normally, UML is linked as a shared binary. This is inconvenient for Normally, UML is linked as a shared binary. This is inconvenient for
......
...@@ -234,7 +234,7 @@ config UML_NET_DAEMON ...@@ -234,7 +234,7 @@ config UML_NET_DAEMON
config UML_NET_VECTOR config UML_NET_VECTOR
bool "Vector I/O high performance network devices" bool "Vector I/O high performance network devices"
depends on UML_NET depends on UML_NET
select FORBID_STATIC_LINK select MAY_HAVE_RUNTIME_DEPS
help help
This User-Mode Linux network driver uses multi-message send This User-Mode Linux network driver uses multi-message send
and receive functions. The host running the UML guest must have and receive functions. The host running the UML guest must have
...@@ -246,7 +246,7 @@ config UML_NET_VECTOR ...@@ -246,7 +246,7 @@ config UML_NET_VECTOR
config UML_NET_VDE config UML_NET_VDE
bool "VDE transport (obsolete)" bool "VDE transport (obsolete)"
depends on UML_NET depends on UML_NET
select FORBID_STATIC_LINK select MAY_HAVE_RUNTIME_DEPS
help help
This User-Mode Linux network transport allows one or more running This User-Mode Linux network transport allows one or more running
UMLs on a single host to communicate with each other and also UMLs on a single host to communicate with each other and also
...@@ -294,7 +294,7 @@ config UML_NET_MCAST ...@@ -294,7 +294,7 @@ config UML_NET_MCAST
config UML_NET_PCAP config UML_NET_PCAP
bool "pcap transport (obsolete)" bool "pcap transport (obsolete)"
depends on UML_NET depends on UML_NET
select FORBID_STATIC_LINK select MAY_HAVE_RUNTIME_DEPS
help help
The pcap transport makes a pcap packet stream on the host look The pcap transport makes a pcap packet stream on the host look
like an ethernet device inside UML. This is useful for making like an ethernet device inside UML. This is useful for making
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
......
...@@ -32,7 +32,7 @@ static int pcap_user_init(void *data, void *dev) ...@@ -32,7 +32,7 @@ static int pcap_user_init(void *data, void *dev)
return 0; return 0;
} }
static int pcap_open(void *data) static int pcap_user_open(void *data)
{ {
struct pcap_data *pri = data; struct pcap_data *pri = data;
__u32 netmask; __u32 netmask;
...@@ -44,14 +44,14 @@ static int pcap_open(void *data) ...@@ -44,14 +44,14 @@ static int pcap_open(void *data)
if (pri->filter != NULL) { if (pri->filter != NULL) {
err = dev_netmask(pri->dev, &netmask); err = dev_netmask(pri->dev, &netmask);
if (err < 0) { if (err < 0) {
printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n"); printk(UM_KERN_ERR "pcap_user_open : dev_netmask failed\n");
return -EIO; return -EIO;
} }
pri->compiled = uml_kmalloc(sizeof(struct bpf_program), pri->compiled = uml_kmalloc(sizeof(struct bpf_program),
UM_GFP_KERNEL); UM_GFP_KERNEL);
if (pri->compiled == NULL) { if (pri->compiled == NULL) {
printk(UM_KERN_ERR "pcap_open : kmalloc failed\n"); printk(UM_KERN_ERR "pcap_user_open : kmalloc failed\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -59,14 +59,14 @@ static int pcap_open(void *data) ...@@ -59,14 +59,14 @@ static int pcap_open(void *data)
(struct bpf_program *) pri->compiled, (struct bpf_program *) pri->compiled,
pri->filter, pri->optimize, netmask); pri->filter, pri->optimize, netmask);
if (err < 0) { if (err < 0) {
printk(UM_KERN_ERR "pcap_open : pcap_compile failed - " printk(UM_KERN_ERR "pcap_user_open : pcap_compile failed - "
"'%s'\n", pcap_geterr(pri->pcap)); "'%s'\n", pcap_geterr(pri->pcap));
goto out; goto out;
} }
err = pcap_setfilter(pri->pcap, pri->compiled); err = pcap_setfilter(pri->pcap, pri->compiled);
if (err < 0) { if (err < 0) {
printk(UM_KERN_ERR "pcap_open : pcap_setfilter " printk(UM_KERN_ERR "pcap_user_open : pcap_setfilter "
"failed - '%s'\n", pcap_geterr(pri->pcap)); "failed - '%s'\n", pcap_geterr(pri->pcap));
goto out; goto out;
} }
...@@ -127,7 +127,7 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) ...@@ -127,7 +127,7 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
const struct net_user_info pcap_user_info = { const struct net_user_info pcap_user_info = {
.init = pcap_user_init, .init = pcap_user_init,
.open = pcap_open, .open = pcap_user_open,
.close = NULL, .close = NULL,
.remove = pcap_remove, .remove = pcap_remove,
.add_address = NULL, .add_address = NULL,
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <sys/termios.h> #include <termios.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <net_user.h> #include <net_user.h>
#include <os.h> #include <os.h>
......
...@@ -1403,7 +1403,7 @@ static int vector_net_load_bpf_flash(struct net_device *dev, ...@@ -1403,7 +1403,7 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
kfree(vp->bpf->filter); kfree(vp->bpf->filter);
vp->bpf->filter = NULL; vp->bpf->filter = NULL;
} else { } else {
vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL); vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_ATOMIC);
if (vp->bpf == NULL) { if (vp->bpf == NULL) {
netdev_err(dev, "failed to allocate memory for firmware\n"); netdev_err(dev, "failed to allocate memory for firmware\n");
goto flash_fail; goto flash_fail;
...@@ -1415,7 +1415,7 @@ static int vector_net_load_bpf_flash(struct net_device *dev, ...@@ -1415,7 +1415,7 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
if (request_firmware(&fw, efl->data, &vdevice->pdev.dev)) if (request_firmware(&fw, efl->data, &vdevice->pdev.dev))
goto flash_fail; goto flash_fail;
vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_KERNEL); vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_ATOMIC);
if (!vp->bpf->filter) if (!vp->bpf->filter)
goto free_buffer; goto free_buffer;
......
...@@ -18,9 +18,7 @@ ...@@ -18,9 +18,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <net/ethernet.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/ether.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <sys/wait.h> #include <sys/wait.h>
...@@ -39,6 +37,7 @@ ...@@ -39,6 +37,7 @@
#define ID_MAX 2 #define ID_MAX 2
#define TOKEN_IFNAME "ifname" #define TOKEN_IFNAME "ifname"
#define TOKEN_SCRIPT "ifup"
#define TRANS_RAW "raw" #define TRANS_RAW "raw"
#define TRANS_RAW_LEN strlen(TRANS_RAW) #define TRANS_RAW_LEN strlen(TRANS_RAW)
...@@ -55,6 +54,9 @@ ...@@ -55,6 +54,9 @@
#define MAX_UN_LEN 107 #define MAX_UN_LEN 107
static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const char *template = "tapXXXXXX";
/* This is very ugly and brute force lookup, but it is done /* This is very ugly and brute force lookup, but it is done
* only once at initialization so not worth doing hashes or * only once at initialization so not worth doing hashes or
* anything more intelligent * anything more intelligent
...@@ -191,16 +193,21 @@ static int create_raw_fd(char *iface, int flags, int proto) ...@@ -191,16 +193,21 @@ static int create_raw_fd(char *iface, int flags, int proto)
return err; return err;
} }
static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
{ {
int fd = -1; int fd = -1, i;
char *iface; char *iface;
struct vector_fds *result = NULL; struct vector_fds *result = NULL;
bool dynamic = false;
char dynamic_ifname[IFNAMSIZ];
char *argv[] = {NULL, NULL, NULL, NULL};
iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
if (iface == NULL) { if (iface == NULL) {
printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n"); dynamic = true;
goto tap_cleanup; iface = dynamic_ifname;
srand(getpid());
} }
result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
...@@ -214,14 +221,30 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) ...@@ -214,14 +221,30 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
result->remote_addr_size = 0; result->remote_addr_size = 0;
/* TAP */ /* TAP */
do {
if (dynamic) {
strcpy(iface, template);
for (i = 0; i < strlen(iface); i++) {
if (iface[i] == 'X') {
iface[i] = padchar[rand() % strlen(padchar)];
}
}
}
fd = create_tap_fd(iface);
if ((fd < 0) && (!dynamic)) {
printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
goto tap_cleanup;
}
result->tx_fd = fd;
result->rx_fd = fd;
} while (fd < 0);
fd = create_tap_fd(iface); argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
if (fd < 0) { if (argv[0]) {
printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n"); argv[1] = iface;
goto tap_cleanup; run_helper(NULL, NULL, argv);
} }
result->tx_fd = fd;
result->rx_fd = fd;
return result; return result;
tap_cleanup: tap_cleanup:
printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd); printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd);
...@@ -233,6 +256,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec) ...@@ -233,6 +256,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
{ {
char *iface; char *iface;
struct vector_fds *result = NULL; struct vector_fds *result = NULL;
char *argv[] = {NULL, NULL, NULL, NULL};
iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
if (iface == NULL) { if (iface == NULL) {
...@@ -266,6 +290,12 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec) ...@@ -266,6 +290,12 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
"uml_tap: failed to create paired raw socket: %i\n", result->rx_fd); "uml_tap: failed to create paired raw socket: %i\n", result->rx_fd);
goto hybrid_cleanup; goto hybrid_cleanup;
} }
argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
if (argv[0]) {
argv[1] = iface;
run_helper(NULL, NULL, argv);
}
return result; return result;
hybrid_cleanup: hybrid_cleanup:
printk(UM_KERN_ERR "user_init_hybrid: init failed"); printk(UM_KERN_ERR "user_init_hybrid: init failed");
...@@ -332,7 +362,7 @@ static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id) ...@@ -332,7 +362,7 @@ static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
} }
switch (id) { switch (id) {
case ID_BESS: case ID_BESS:
if (connect(fd, remote_addr, sizeof(struct sockaddr_un)) < 0) { if (connect(fd, (const struct sockaddr *) remote_addr, sizeof(struct sockaddr_un)) < 0) {
printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno); printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno);
goto unix_cleanup; goto unix_cleanup;
} }
...@@ -399,8 +429,7 @@ static struct vector_fds *user_init_fd_fds(struct arglist *ifspec) ...@@ -399,8 +429,7 @@ static struct vector_fds *user_init_fd_fds(struct arglist *ifspec)
fd_cleanup: fd_cleanup:
if (fd >= 0) if (fd >= 0)
os_close_file(fd); os_close_file(fd);
if (result != NULL) kfree(result);
kfree(result);
return NULL; return NULL;
} }
...@@ -410,6 +439,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) ...@@ -410,6 +439,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
int err = -ENOMEM; int err = -ENOMEM;
char *iface; char *iface;
struct vector_fds *result = NULL; struct vector_fds *result = NULL;
char *argv[] = {NULL, NULL, NULL, NULL};
iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
if (iface == NULL) if (iface == NULL)
...@@ -432,6 +462,11 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) ...@@ -432,6 +462,11 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
result->remote_addr = NULL; result->remote_addr = NULL;
result->remote_addr_size = 0; result->remote_addr_size = 0;
} }
argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
if (argv[0]) {
argv[1] = iface;
run_helper(NULL, NULL, argv);
}
return result; return result;
raw_cleanup: raw_cleanup:
printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
...@@ -789,10 +824,12 @@ void *uml_vector_user_bpf(char *filename) ...@@ -789,10 +824,12 @@ void *uml_vector_user_bpf(char *filename)
return false; return false;
} }
bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL); bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
if (bpf_prog != NULL) { if (bpf_prog == NULL) {
bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter); printk(KERN_ERR "Failed to allocate bpf prog buffer");
bpf_prog->filter = NULL; return NULL;
} }
bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter);
bpf_prog->filter = NULL;
ffd = os_open_file(filename, of_read(OPENFLAGS()), 0); ffd = os_open_file(filename, of_read(OPENFLAGS()), 0);
if (ffd < 0) { if (ffd < 0) {
printk(KERN_ERR "Error %d opening bpf file", -errno); printk(KERN_ERR "Error %d opening bpf file", -errno);
......
...@@ -35,14 +35,14 @@ int write_sigio_irq(int fd) ...@@ -35,14 +35,14 @@ int write_sigio_irq(int fd)
} }
/* These are called from os-Linux/sigio.c to protect its pollfds arrays. */ /* These are called from os-Linux/sigio.c to protect its pollfds arrays. */
static DEFINE_SPINLOCK(sigio_spinlock); static DEFINE_MUTEX(sigio_mutex);
void sigio_lock(void) void sigio_lock(void)
{ {
spin_lock(&sigio_spinlock); mutex_lock(&sigio_mutex);
} }
void sigio_unlock(void) void sigio_unlock(void)
{ {
spin_unlock(&sigio_spinlock); mutex_unlock(&sigio_mutex);
} }
...@@ -47,12 +47,10 @@ void show_stack(struct task_struct *task, unsigned long *stack, ...@@ -47,12 +47,10 @@ void show_stack(struct task_struct *task, unsigned long *stack,
if (kstack_end(stack)) if (kstack_end(stack))
break; break;
if (i && ((i % STACKSLOTS_PER_LINE) == 0)) if (i && ((i % STACKSLOTS_PER_LINE) == 0))
printk("%s\n", loglvl); pr_cont("\n");
pr_cont(" %08lx", *stack++); pr_cont(" %08lx", *stack++);
} }
printk("%s\n", loglvl);
printk("%sCall Trace:\n", loglvl); printk("%sCall Trace:\n", loglvl);
dump_trace(current, &stackops, (void *)loglvl); dump_trace(current, &stackops, (void *)loglvl);
printk("%s\n", loglvl);
} }
...@@ -70,13 +70,17 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg, ...@@ -70,13 +70,17 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg,
* read of the message and write of the ACK. * read of the message and write of the ACK.
*/ */
if (mode != TTMH_READ) { if (mode != TTMH_READ) {
bool disabled = irqs_disabled();
BUG_ON(mode == TTMH_IDLE && !disabled);
if (disabled)
local_irq_enable();
while (os_poll(1, &time_travel_ext_fd) != 0) { while (os_poll(1, &time_travel_ext_fd) != 0) {
if (mode == TTMH_IDLE) { /* nothing */
BUG_ON(!irqs_disabled());
local_irq_enable();
local_irq_disable();
}
} }
if (disabled)
local_irq_disable();
} }
ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg)); ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg));
...@@ -102,6 +106,7 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg, ...@@ -102,6 +106,7 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg,
break; break;
} }
resp.seq = msg->seq;
os_write_file(time_travel_ext_fd, &resp, sizeof(resp)); os_write_file(time_travel_ext_fd, &resp, sizeof(resp));
} }
......
...@@ -97,7 +97,7 @@ static int remove_files_and_dir(char *dir) ...@@ -97,7 +97,7 @@ static int remove_files_and_dir(char *dir)
while ((ent = readdir(directory)) != NULL) { while ((ent = readdir(directory)) != NULL) {
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue; continue;
len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; len = strlen(dir) + strlen("/") + strlen(ent->d_name) + 1;
if (len > sizeof(file)) { if (len > sizeof(file)) {
ret = -E2BIG; ret = -E2BIG;
goto out; goto out;
...@@ -135,7 +135,7 @@ static int remove_files_and_dir(char *dir) ...@@ -135,7 +135,7 @@ static int remove_files_and_dir(char *dir)
*/ */
static inline int is_umdir_used(char *dir) static inline int is_umdir_used(char *dir)
{ {
char pid[sizeof("nnnnn\0")], *end, *file; char pid[sizeof("nnnnnnnnn")], *end, *file;
int dead, fd, p, n, err; int dead, fd, p, n, err;
size_t filelen; size_t filelen;
...@@ -217,10 +217,10 @@ static int umdir_take_if_dead(char *dir) ...@@ -217,10 +217,10 @@ static int umdir_take_if_dead(char *dir)
static void __init create_pid_file(void) static void __init create_pid_file(void)
{ {
char pid[sizeof("nnnnn\0")], *file; char pid[sizeof("nnnnnnnnn")], *file;
int fd, n; int fd, n;
n = strlen(uml_dir) + UMID_LEN + sizeof("/pid\0"); n = strlen(uml_dir) + UMID_LEN + sizeof("/pid");
file = malloc(n); file = malloc(n);
if (!file) if (!file)
return; return;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
#include <termios.h> #include <termios.h>
#include <wait.h> #include <sys/wait.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/utsname.h> #include <sys/utsname.h>
#include <init.h> #include <init.h>
......
...@@ -52,14 +52,6 @@ static const int reg_offsets[] = ...@@ -52,14 +52,6 @@ static const int reg_offsets[] =
int putreg(struct task_struct *child, int regno, unsigned long value) int putreg(struct task_struct *child, int regno, unsigned long value)
{ {
#ifdef TIF_IA32
/*
* Some code in the 64bit emulation may not be 64bit clean.
* Don't take any chances.
*/
if (test_tsk_thread_flag(child, TIF_IA32))
value &= 0xffffffff;
#endif
switch (regno) { switch (regno) {
case R8: case R8:
case R9: case R9:
...@@ -137,10 +129,7 @@ int poke_user(struct task_struct *child, long addr, long data) ...@@ -137,10 +129,7 @@ int poke_user(struct task_struct *child, long addr, long data)
unsigned long getreg(struct task_struct *child, int regno) unsigned long getreg(struct task_struct *child, int regno)
{ {
unsigned long mask = ~0UL; unsigned long mask = ~0UL;
#ifdef TIF_IA32
if (test_tsk_thread_flag(child, TIF_IA32))
mask = 0xffffffff;
#endif
switch (regno) { switch (regno) {
case R8: case R8:
case R9: case R9:
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <stddef.h> #include <stddef.h>
#include <signal.h> #include <signal.h>
#include <sys/poll.h> #include <poll.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/user.h> #include <sys/user.h>
#define __FRAME_OFFSETS #define __FRAME_OFFSETS
......
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