Revision: c8beb0a4d99e
Branch: default
Author: Kevin Pedretti <
ktp...@sandia.gov>
Date: Wed Sep 4 11:42:11 2013 UTC
Log: Fix bug where init_task copy to umem could truncate init_task ELF
image due to memory zero'ing.
Introduce an explicit pmem_zero() system call to zero a region of physical
memory.
Memory zero'ing is moved out of the pmem_alloc() critical section.
pmem_alloc() and pmem_alloc_umem() no longer zero memory -- the caller must
do this via pmem_zero().
There may be certain cases where the PCT does not want to zero memory, or
can do it some other way
more efficiently. Making pmem allocation and zero'ing separate operations
allows this.
http://code.google.com/p/kitten/source/detail?r=c8beb0a4d99e
Modified:
/arch/x86_64/kernel/palacios/palacios.c
/include/arch-x86_64/unistd.h
/include/lwk/pmem.h
/kernel/lwk_syscalls/Makefile
/kernel/mm/pmem.c
/user/liblwk/elf.c
/user/liblwk/syscalls.c
/user/runtime/pct/pmem.cpp
/user/runtime2/pct/pct.c
=======================================
--- /arch/x86_64/kernel/palacios/palacios.c Thu Aug 22 11:28:39 2013 UTC
+++ /arch/x86_64/kernel/palacios/palacios.c Wed Sep 4 11:42:11 2013 UTC
@@ -128,6 +128,11 @@
if (status)
return NULL;
+ /* Zero the memory before handing it to Palacios */
+ status = pmem_zero(&result);
+ if (status)
+ return NULL;
+
/* Return the physical address of the region */
return (void *) result.start;
}
=======================================
--- /include/arch-x86_64/unistd.h Thu Jul 25 23:44:46 2013 UTC
+++ /include/arch-x86_64/unistd.h Wed Sep 4 11:42:11 2013 UTC
@@ -653,52 +653,54 @@
__SYSCALL(__NR_pmem_query, sys_pmem_query)
#define __NR_pmem_alloc 503
__SYSCALL(__NR_pmem_alloc, sys_pmem_alloc)
+#define __NR_pmem_zero 504
+__SYSCALL(__NR_pmem_zero, sys_pmem_zero)
-#define __NR_aspace_get_myid 504
+#define __NR_aspace_get_myid 505
__SYSCALL(__NR_aspace_get_myid, sys_aspace_get_myid)
-#define __NR_aspace_create 505
+#define __NR_aspace_create 506
__SYSCALL(__NR_aspace_create, sys_aspace_create)
-#define __NR_aspace_destroy 506
+#define __NR_aspace_destroy 507
__SYSCALL(__NR_aspace_destroy, sys_aspace_destroy)
-#define __NR_aspace_find_hole 507
+#define __NR_aspace_find_hole 508
__SYSCALL(__NR_aspace_find_hole, sys_aspace_find_hole)
-#define __NR_aspace_add_region 508
+#define __NR_aspace_add_region 509
__SYSCALL(__NR_aspace_add_region, sys_aspace_add_region)
-#define __NR_aspace_del_region 509
+#define __NR_aspace_del_region 510
__SYSCALL(__NR_aspace_del_region, sys_aspace_del_region)
-#define __NR_aspace_map_pmem 510
+#define __NR_aspace_map_pmem 511
__SYSCALL(__NR_aspace_map_pmem, sys_aspace_map_pmem)
-#define __NR_aspace_unmap_pmem 511
+#define __NR_aspace_unmap_pmem 512
__SYSCALL(__NR_aspace_unmap_pmem, sys_aspace_unmap_pmem)
-#define __NR_aspace_virt_to_phys 512
+#define __NR_aspace_virt_to_phys 513
__SYSCALL(__NR_aspace_virt_to_phys, sys_aspace_virt_to_phys)
-#define __NR_aspace_smartmap 513
+#define __NR_aspace_smartmap 514
__SYSCALL(__NR_aspace_smartmap, sys_aspace_smartmap)
-#define __NR_aspace_unsmartmap 514
+#define __NR_aspace_unsmartmap 515
__SYSCALL(__NR_aspace_unsmartmap, sys_aspace_unsmartmap)
-#define __NR_aspace_dump2console 515
+#define __NR_aspace_dump2console 516
__SYSCALL(__NR_aspace_dump2console, sys_aspace_dump2console)
-#define __NR_task_create 516
+#define __NR_task_create 517
__SYSCALL(__NR_task_create, sys_task_create)
-#define __NR_task_switch_cpus 517
+#define __NR_task_switch_cpus 518
__SYSCALL(__NR_task_switch_cpus, sys_task_switch_cpus)
-#define __NR_elf_hwcap 518
+#define __NR_elf_hwcap 519
__SYSCALL(__NR_elf_hwcap, sys_elf_hwcap)
-#define __NR_v3_start_guest 519
+#define __NR_v3_start_guest 520
__SYSCALL(__NR_v3_start_guest, syscall_not_implemented) /* registered
later */
-#define __NR_getcpu 520
+#define __NR_getcpu 521
__SYSCALL(__NR_getcpu, sys_getcpu)
-#define __NR_mce_inject 521
+#define __NR_mce_inject 522
__SYSCALL(__NR_mce_inject, syscall_not_implemented)
-#define __NR_lwk_arp 522
+#define __NR_lwk_arp 523
#ifdef CONFIG_LINUX
__SYSCALL(__NR_lwk_arp, sys_lwk_arp)
#else
__SYSCALL(__NR_lwk_arp, syscall_not_implemented)
#endif
-#define __NR_lwk_ifconfig 523
+#define __NR_lwk_ifconfig 524
#ifdef CONFIG_LINUX
__SYSCALL(__NR_lwk_ifconfig, sys_lwk_ifconfig)
#else
=======================================
--- /include/lwk/pmem.h Tue Dec 20 22:31:41 2011 UTC
+++ /include/lwk/pmem.h Wed Sep 4 11:42:11 2013 UTC
@@ -47,6 +47,7 @@
int pmem_alloc(size_t size, size_t alignment,
const struct pmem_region *constraint,
struct pmem_region *result);
+int pmem_zero(const struct pmem_region *rgn);
/**
* Convenience functions.
@@ -69,6 +70,7 @@
int sys_pmem_alloc(size_t size, size_t alignment,
const struct pmem_region __user *constraint,
struct pmem_region __user *result);
+int sys_pmem_zero(const struct pmem_region __user *rgn);
#endif
#endif
=======================================
--- /kernel/lwk_syscalls/Makefile Wed Oct 26 22:25:16 2011 UTC
+++ /kernel/lwk_syscalls/Makefile Wed Sep 4 11:42:11 2013 UTC
@@ -3,6 +3,7 @@
pmem_update.o \
pmem_query.o \
pmem_alloc.o \
+ pmem_zero.o \
aspace_create.o \
aspace_destroy.o \
aspace_get_myid.o \
=======================================
--- /kernel/mm/pmem.c Mon Apr 1 19:36:32 2013 UTC
+++ /kernel/mm/pmem.c Wed Sep 4 11:42:11 2013 UTC
@@ -187,13 +187,6 @@
}
}
}
-
-static void
-zero_pmem(const struct pmem_region *rgn)
-{
- /* access pmem region via the kernel's identity map */
- memset(__va(rgn->start), 0, rgn->end - rgn->start);
-}
static int
__pmem_add(const struct pmem_region *rgn)
@@ -371,7 +364,6 @@
candidate.allocated = true;
status = __pmem_update(&candidate);
BUG_ON(status);
- zero_pmem(&candidate);
if (result)
*result = candidate;
return 0;
@@ -398,3 +390,15 @@
return status;
}
+
+int
+pmem_zero(const struct pmem_region *rgn)
+{
+ if (!region_is_sane(rgn))
+ return -EINVAL;
+
+ /* access pmem region via the kernel's identity map */
+ memset(__va(rgn->start), 0, rgn->end - rgn->start);
+
+ return 0;
+}
=======================================
--- /user/liblwk/elf.c Fri Nov 4 22:03:32 2011 UTC
+++ /user/liblwk/elf.c Wed Sep 4 11:42:11 2013 UTC
@@ -464,6 +464,9 @@
if (pmem_alloc_umem(size, alignment, &result))
return 0;
+ if (pmem_zero(&result))
+ return 0;
+
/* Mark the memory as being used by the init task */
result.type = PMEM_TYPE_INIT_TASK;
pmem_update(&result);
=======================================
--- /user/liblwk/syscalls.c Wed Mar 20 17:55:01 2013 UTC
+++ /user/liblwk/syscalls.c Wed Sep 4 11:42:11 2013 UTC
@@ -172,6 +172,7 @@
SYSCALL2(pmem_query, const struct pmem_region *, struct pmem_region *);
SYSCALL4(pmem_alloc, size_t, size_t,
const struct pmem_region *, struct pmem_region *);
+SYSCALL1(pmem_zero, const struct pmem_region *);
/**
* Address space management.
=======================================
--- /user/runtime/pct/pmem.cpp Mon Apr 19 14:40:24 2010 UTC
+++ /user/runtime/pct/pmem.cpp Wed Sep 4 11:42:11 2013 UTC
@@ -33,6 +33,9 @@
if ( pmem_alloc_umem( size, PAGE_SIZE, request ) ) {
return -1;
}
+
+ if (pmem_zero(request))
+ return -1;
void* vaddr = map( request->start, size );
if ( vaddr == (void*) -1 ) {
=======================================
--- /user/runtime2/pct/pct.c Wed Aug 7 19:54:32 2013 UTC
+++ /user/runtime2/pct/pct.c Wed Sep 4 11:42:11 2013 UTC
@@ -36,6 +36,9 @@
if (pmem_alloc_umem(size, alignment, &result))
return (paddr_t) NULL;
+ if (pmem_zero(&result))
+ return (paddr_t) NULL;
+
// Mark allocated region with the name passed in
result.name_is_set = true;
strncpy(
result.name, name, sizeof(
result.name));