aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorAnton Ivanov <antivano@cisco.com>2014-03-07 13:37:47 -0500
committerRichard Weinberger <richard@nod.at>2014-04-20 17:57:21 -0400
commit0565103d1adbd765ca45248d04c327c076dd1571 (patch)
treebc72dc69499b068766284276bee91884afb1218b /arch/um
parent9fcb663be42e4727c1beabc7c80e2d839199e6b1 (diff)
um: Memory corruption on startup
The reverse case of this race (you must msync before read) is well known. This is the not so common one. It can be triggered only on systems which do a lot of task switching and only at UML startup. If you are starting 200+ UMLs ~ 0.5% will always die without this fix. Signed-off-by: Anton Ivanov <antivano@cisco.com> [rw: minor whitespace fixes] Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/include/shared/os.h1
-rw-r--r--arch/um/kernel/physmem.c1
-rw-r--r--arch/um/os-Linux/file.c6
3 files changed, 8 insertions, 0 deletions
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 75298d3358e7..08eec0b691b0 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -136,6 +136,7 @@ extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
136extern int os_get_ifname(int fd, char *namebuf); 136extern int os_get_ifname(int fd, char *namebuf);
137extern int os_set_slip(int fd); 137extern int os_set_slip(int fd);
138extern int os_mode_fd(int fd, int mode); 138extern int os_mode_fd(int fd, int mode);
139extern int os_fsync_file(int fd);
139 140
140extern int os_seek_file(int fd, unsigned long long offset); 141extern int os_seek_file(int fd, unsigned long long offset);
141extern int os_open_file(const char *file, struct openflags flags, int mode); 142extern int os_open_file(const char *file, struct openflags flags, int mode);
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index f116db15d402..30fdd5d0067b 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -103,6 +103,7 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
103 */ 103 */
104 os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); 104 os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
105 os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); 105 os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
106 os_fsync_file(physmem_fd);
106 107
107 bootmap_size = init_bootmem(pfn, pfn + delta); 108 bootmap_size = init_bootmem(pfn, pfn + delta);
108 free_bootmem(__pa(reserve_end) + bootmap_size, 109 free_bootmem(__pa(reserve_end) + bootmap_size,
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 07a750197bb0..08d90fba952c 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -237,6 +237,12 @@ void os_close_file(int fd)
237{ 237{
238 close(fd); 238 close(fd);
239} 239}
240int os_fsync_file(int fd)
241{
242 if (fsync(fd) < 0)
243 return -errno;
244 return 0;
245}
240 246
241int os_seek_file(int fd, unsigned long long offset) 247int os_seek_file(int fd, unsigned long long offset)
242{ 248{