浏览代码

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>
Anton Ivanov 11 年之前
父节点
当前提交
0565103d1a
共有 3 个文件被更改,包括 8 次插入0 次删除
  1. 1 0
      arch/um/include/shared/os.h
  2. 1 0
      arch/um/kernel/physmem.c
  3. 6 0
      arch/um/os-Linux/file.c

+ 1 - 0
arch/um/include/shared/os.h

@@ -136,6 +136,7 @@ extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
 extern int os_get_ifname(int fd, char *namebuf);
 extern int os_get_ifname(int fd, char *namebuf);
 extern int os_set_slip(int fd);
 extern int os_set_slip(int fd);
 extern int os_mode_fd(int fd, int mode);
 extern int os_mode_fd(int fd, int mode);
+extern int os_fsync_file(int fd);
 
 
 extern int os_seek_file(int fd, unsigned long long offset);
 extern int os_seek_file(int fd, unsigned long long offset);
 extern int os_open_file(const char *file, struct openflags flags, int mode);
 extern int os_open_file(const char *file, struct openflags flags, int mode);

+ 1 - 0
arch/um/kernel/physmem.c

@@ -103,6 +103,7 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
 	 */
 	 */
 	os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
 	os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
 	os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
 	os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
+	os_fsync_file(physmem_fd);
 
 
 	bootmap_size = init_bootmem(pfn, pfn + delta);
 	bootmap_size = init_bootmem(pfn, pfn + delta);
 	free_bootmem(__pa(reserve_end) + bootmap_size,
 	free_bootmem(__pa(reserve_end) + bootmap_size,

+ 6 - 0
arch/um/os-Linux/file.c

@@ -237,6 +237,12 @@ void os_close_file(int fd)
 {
 {
 	close(fd);
 	close(fd);
 }
 }
+int os_fsync_file(int fd)
+{
+	if (fsync(fd) < 0)
+	    return -errno;
+	return 0;
+}
 
 
 int os_seek_file(int fd, unsigned long long offset)
 int os_seek_file(int fd, unsigned long long offset)
 {
 {