Skip to content

Commit 943ba89

Browse files
committed
[MANA-78] vdso was not restored properly on CentOS 7
The reason is we saved temporary vvar&vdso address in global variable, the address of which could have been changed. This is not a problem when vdso label is carried after mremap, but on CentOS 7, the label was missing which resulted in we umapped the temporary vdso segment and won't map vdso back
1 parent b2cce4c commit 943ba89

2 files changed

Lines changed: 18 additions & 7 deletions

File tree

src/mtcp/mtcp_header.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ typedef struct RestoreInfo {
101101
#endif
102102
MYINFO_GS_T myinfo_gs;
103103
int mtcp_restart_pause; // Used by env. var. DMTCP_RESTART_PAUSE0
104+
VA vvarStartTmp;
105+
VA vdsoStartTmp;
104106
const char *restart_dir; // Directory to search for checkpoint files
105107
} RestoreInfo;
106108

src/mtcp/mtcp_restart.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ uint64_t vdsoStartTmp = 0;
512512
static void
513513
remap_vdso_and_vvar_regions() {
514514
Area area;
515-
int rc = 0;
515+
void *rc = 0;
516516
uint64_t vvarStart = 0;
517517
uint64_t vdsoStart = 0;
518518
uint64_t vvarSize = 0;
@@ -543,7 +543,10 @@ remap_vdso_and_vvar_regions() {
543543

544544
while (mtcp_readmapsline(mapsfd, &area)) {
545545
if (prev_addr + vvarSize + vdsoSize <= area.addr) {
546-
vvarStartTmp = prev_addr;
546+
if (vvarSize > 0) {
547+
/* some kernel doesn't have vvar */
548+
vvarStartTmp = prev_addr;
549+
}
547550
vdsoStartTmp = prev_addr + vvarSize;
548551
break;
549552
} else {
@@ -1104,6 +1107,10 @@ restart_fast_path()
11041107

11051108
DPRINTF("We have copied mtcp_restart to higher address. We will now\n"
11061109
" jump into a copy of restorememoryareas().\n");
1110+
rinfo.vvarStartTmp = vvarStartTmp;
1111+
rinfo.vdsoStartTmp = vdsoStartTmp;
1112+
DPRINTF("%p %p %p %p\n", &vvarStartTmp, vvarStartTmp, &vdsoStartTmp, vdsoStartTmp);
1113+
/* after calling the following assembly, the address of vvarStartTmp & vdsoStartTmp changed */
11071114

11081115
#if defined(__i386__) || defined(__x86_64__)
11091116
asm volatile (CLEAN_FOR_64_BIT(mov %0, %%esp; )
@@ -1221,6 +1228,8 @@ restorememoryareas(RestoreInfo *rinfo_ptr, LowerHalfInfo_t *linfo_ptr)
12211228
{
12221229
int mtcp_sys_errno;
12231230

1231+
/* the address has been changed, the values become 0 */
1232+
DPRINTF("%p %p %p %p\n", &vvarStartTmp, vvarStartTmp, &vdsoStartTmp, vdsoStartTmp);
12241233
DPRINTF("Entering copy of restorememoryareas(). Will now unmap old memory"
12251234
"\n and restore memory sections from the checkpoint image.\n");
12261235

@@ -1374,14 +1383,14 @@ unmap_memory_areas_and_restore_vdso(RestoreInfo *rinfo, LowerHalfInfo_t *lh_info
13741383
/* Unmap everything except this image, vdso, vvar and vsyscall. */
13751384
int mtcp_sys_errno;
13761385
Area area;
1377-
#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 10, 0)
1386+
#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 10, 0)
13781387
VA vdsoStart = NULL;
13791388
VA vdsoEnd = NULL;
13801389
#else
13811390
// This Linux kernel does not re-label vdso/vvar after calling mremap on it.
13821391
// So, lower down, we will fail to find vdeso in /proc/self/maps
1383-
VA vdsoStart = (VA)vdsoStartTmp;
1384-
VA vdsoEnd = (VA)(vdsoStartTmp + 2*PAGESIZE);
1392+
VA vdsoStart = (VA)rinfo->vdsoStartTmp;
1393+
VA vdsoEnd = (VA)(rinfo->vdsoStartTmp + 2 * PAGESIZE);
13851394
#endif
13861395
VA vvarStart = NULL;
13871396
VA vvarEnd = NULL;
@@ -1396,8 +1405,8 @@ unmap_memory_areas_and_restore_vdso(RestoreInfo *rinfo, LowerHalfInfo_t *lh_info
13961405
// We create local copies of these, as they reside on the data section of
13971406
// mtcp_restart, which is unmapped later on.
13981407

1399-
uint64_t vdsoStartTmpCopy = vdsoStartTmp;
1400-
uint64_t vvarStartTmpCopy = vvarStartTmp;
1408+
uint64_t vdsoStartTmpCopy = rinfo->vdsoStartTmp;
1409+
uint64_t vvarStartTmpCopy = rinfo->vvarStartTmp;
14011410

14021411
while (mtcp_readmapsline(mapsfd, &area)) {
14031412
if (area.addr >= rinfo->restore_addr && area.addr < rinfo->restore_end) {

0 commit comments

Comments
 (0)