diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 2 | ||||
-rw-r--r-- | arch/um/include/sysdep-i386/barrier.h | 9 | ||||
-rw-r--r-- | arch/um/include/sysdep-x86_64/barrier.h | 7 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 31 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/tls.c | 2 |
7 files changed, 47 insertions, 7 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index ab974ff..22e4c466 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -70,7 +70,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return #define PREFIX "ACPI: " -int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ +int acpi_noirq; /* skip ACPI IRQ initialization */ int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ int acpi_ht __initdata = 1; /* enable HT */ diff --git a/arch/um/include/sysdep-i386/barrier.h b/arch/um/include/sysdep-i386/barrier.h new file mode 100644 index 0000000..b58d52c --- /dev/null +++ b/arch/um/include/sysdep-i386/barrier.h @@ -0,0 +1,9 @@ +#ifndef __SYSDEP_I386_BARRIER_H +#define __SYSDEP_I386_BARRIER_H + +/* Copied from include/asm-i386 for use by userspace. i386 has the option + * of using mfence, but I'm just using this, which works everywhere, for now. + */ +#define mb() asm volatile("lock; addl $0,0(%esp)") + +#endif diff --git a/arch/um/include/sysdep-x86_64/barrier.h b/arch/um/include/sysdep-x86_64/barrier.h new file mode 100644 index 0000000..7b610be --- /dev/null +++ b/arch/um/include/sysdep-x86_64/barrier.h @@ -0,0 +1,7 @@ +#ifndef __SYSDEP_X86_64_BARRIER_H +#define __SYSDEP_X86_64_BARRIER_H + +/* Copied from include/asm-x86_64 for use by userspace. */ +#define mb() asm volatile("mfence":::"memory") + +#endif diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 51f0893..c692a19 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -7,7 +7,6 @@ #include <stdio.h> #include <errno.h> #include <signal.h> -#include <linux/unistd.h> #include <sys/mman.h> #include <sys/wait.h> #include <sys/mman.h> diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 6b81739..b897e85 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -15,6 +15,7 @@ #include "user.h" #include "signal_kern.h" #include "sysdep/sigcontext.h" +#include "sysdep/barrier.h" #include "sigcontext.h" #include "mode.h" #include "os.h" @@ -34,8 +35,12 @@ #define SIGALRM_BIT 2 #define SIGALRM_MASK (1 << SIGALRM_BIT) -static int signals_enabled = 1; -static int pending = 0; +/* These are used by both the signal handlers and + * block/unblock_signals. I don't want modifications cached in a + * register - they must go straight to memory. + */ +static volatile int signals_enabled = 1; +static volatile int pending = 0; void sig_handler(int sig, struct sigcontext *sc) { @@ -152,6 +157,12 @@ int change_sig(int signal, int on) void block_signals(void) { signals_enabled = 0; + /* This must return with signals disabled, so this barrier + * ensures that writes are flushed out before the return. + * This might matter if gcc figures out how to inline this and + * decides to shuffle this code into the caller. + */ + mb(); } void unblock_signals(void) @@ -171,9 +182,23 @@ void unblock_signals(void) */ signals_enabled = 1; + /* Setting signals_enabled and reading pending must + * happen in this order. + */ + mb(); + save_pending = pending; - if(save_pending == 0) + if(save_pending == 0){ + /* This must return with signals enabled, so + * this barrier ensures that writes are + * flushed out before the return. This might + * matter if gcc figures out how to inline + * this (unlikely, given its size) and decides + * to shuffle this code into the caller. + */ + mb(); return; + } pending = 0; diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index cb9ab54..9b34fe6 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -14,7 +14,7 @@ #include <sys/mman.h> #include <sys/user.h> #include <sys/time.h> -#include <asm/unistd.h> +#include <sys/syscall.h> #include <asm/types.h> #include "user.h" #include "sysdep/ptrace.h" diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c index 9f7999f..16215b9 100644 --- a/arch/um/os-Linux/tls.c +++ b/arch/um/os-Linux/tls.c @@ -1,7 +1,7 @@ #include <errno.h> +#include <unistd.h> #include <sys/ptrace.h> #include <sys/syscall.h> -#include <unistd.h> #include <asm/ldt.h> #include "sysdep/tls.h" #include "uml-config.h" |