Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 356247
b: refs/heads/master
c: 084d128
h: refs/heads/master
i:
  356245: c0de433
  356243: 9cb23bc
  356239: 884fc40
v: v3
  • Loading branch information
Yinghai Lu authored and H. Peter Anvin committed Jan 29, 2013
1 parent 702c730 commit 59752bf
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 577af55d802d9fe114287e750504e09e7c677c9c
refs/heads/master: 084d1283986a530828b8898f206adf44d5d3146d
43 changes: 37 additions & 6 deletions trunk/arch/x86/kernel/machine_kexec_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ static int init_one_level2_page(struct kimage *image, pgd_t *pgd,
return result;
}

static int ident_mapping_init(struct kimage *image, pgd_t *level4p,
unsigned long mstart, unsigned long mend)
{
int result;

mstart = round_down(mstart, PMD_SIZE);
mend = round_up(mend - 1, PMD_SIZE);

while (mstart < mend) {
result = init_one_level2_page(image, level4p, mstart);
if (result)
return result;

mstart += PMD_SIZE;
}

return 0;
}

static void init_level2_page(pmd_t *level2p, unsigned long addr)
{
unsigned long end_addr;
Expand Down Expand Up @@ -184,22 +203,34 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
return result;
}


static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
{
unsigned long mstart, mend;
pgd_t *level4p;
int result;
int i;

level4p = (pgd_t *)__va(start_pgtable);
result = init_level4_page(image, level4p, 0, max_pfn << PAGE_SHIFT);
if (result)
return result;

/*
* image->start may be outside 0 ~ max_pfn, for example when
* jump back to original kernel from kexeced kernel
* segments's mem ranges could be outside 0 ~ max_pfn,
* for example when jump back to original kernel from kexeced kernel.
* or first kernel is booted with user mem map, and second kernel
* could be loaded out of that range.
*/
result = init_one_level2_page(image, level4p, image->start);
if (result)
return result;
for (i = 0; i < image->nr_segments; i++) {
mstart = image->segment[i].mem;
mend = mstart + image->segment[i].memsz;

result = ident_mapping_init(image, level4p, mstart, mend);

if (result)
return result;
}

return init_transition_pgtable(image, level4p);
}

Expand Down

0 comments on commit 59752bf

Please sign in to comment.