summaryrefslogtreecommitdiff
path: root/arch/x86_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64.c')
-rw-r--r--arch/x86_64.c90
1 files changed, 35 insertions, 55 deletions
diff --git a/arch/x86_64.c b/arch/x86_64.c
index ddf7be6..893cd51 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -21,17 +21,6 @@
extern struct vmap_pfns *gvmem_pfns;
extern int nr_gvmem_pfns;
-int
-is_vmalloc_addr_x86_64(ulong vaddr)
-{
- /*
- * vmalloc, virtual memmap, and module space as VMALLOC space.
- */
- return ((vaddr >= VMALLOC_START && vaddr <= VMALLOC_END)
- || (vaddr >= VMEMMAP_START && vaddr <= VMEMMAP_END)
- || (vaddr >= MODULES_VADDR && vaddr <= MODULES_END));
-}
-
static unsigned long
get_xen_p2m_mfn(void)
{
@@ -44,6 +33,24 @@ get_xen_p2m_mfn(void)
return NOT_FOUND_LONG_VALUE;
}
+static int
+get_page_offset_x86_64(void)
+{
+ int i;
+ unsigned long long phys_start;
+ unsigned long long virt_start;
+
+ for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
+ if (virt_start < __START_KERNEL_map) {
+ info->page_offset = virt_start - phys_start;
+ return TRUE;
+ }
+ }
+
+ ERRMSG("Can't get any pt_load to calculate page offset.\n");
+ return FALSE;
+}
+
int
get_phys_base_x86_64(void)
{
@@ -55,10 +62,21 @@ get_phys_base_x86_64(void)
* Get the relocatable offset
*/
info->phys_base = 0; /* default/traditional */
+ if (NUMBER(phys_base) != NOT_FOUND_NUMBER) {
+ info->phys_base = NUMBER(phys_base);
+ return TRUE;
+ }
+
+ /* linux-2.6.21 or older don't have phys_base, should be set to 0. */
+ if (!has_vmcoreinfo()) {
+ SYMBOL_INIT(phys_base, "phys_base");
+ if (SYMBOL(phys_base) == NOT_FOUND_SYMBOL) {
+ return TRUE;
+ }
+ }
for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
- if ((virt_start >= __START_KERNEL_map) &&
- !(is_vmalloc_addr_x86_64(virt_start))) {
+ if (virt_start >= __START_KERNEL_map) {
info->phys_base = phys_start -
(virt_start & ~(__START_KERNEL_map));
@@ -159,19 +177,13 @@ get_versiondep_info_x86_64(void)
else
info->max_physmem_bits = _MAX_PHYSMEM_BITS_2_6_31;
- if (info->kernel_version < KERNEL_VERSION(2, 6, 27))
- info->page_offset = __PAGE_OFFSET_ORIG;
- else
- info->page_offset = __PAGE_OFFSET_2_6_27;
+ if (!get_page_offset_x86_64())
+ return FALSE;
if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
- info->vmalloc_start = VMALLOC_START_ORIG;
- info->vmalloc_end = VMALLOC_END_ORIG;
info->vmemmap_start = VMEMMAP_START_ORIG;
info->vmemmap_end = VMEMMAP_END_ORIG;
} else {
- info->vmalloc_start = VMALLOC_START_2_6_31;
- info->vmalloc_end = VMALLOC_END_2_6_31;
info->vmemmap_start = VMEMMAP_START_2_6_31;
info->vmemmap_end = VMEMMAP_END_2_6_31;
}
@@ -196,9 +208,9 @@ vtop4_x86_64(unsigned long vaddr)
/*
* Get PGD.
*/
- page_dir = SYMBOL(init_level4_pgt);
+ page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + info->phys_base;
page_dir += pml4_index(vaddr) * sizeof(unsigned long);
- if (!readmem(VADDR, page_dir, &pml4, sizeof pml4)) {
+ if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
return NOT_PADDR;
}
@@ -269,38 +281,6 @@ vtop4_x86_64(unsigned long vaddr)
return (pte & ENTRY_MASK) + PAGEOFFSET(vaddr);
}
-unsigned long long
-vaddr_to_paddr_x86_64(unsigned long vaddr)
-{
- unsigned long phys_base;
- unsigned long long paddr;
-
- /*
- * Check the relocatable kernel.
- */
- if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
- phys_base = info->phys_base;
- else
- phys_base = 0;
-
- if (is_vmalloc_addr_x86_64(vaddr)) {
- if ((paddr = vtop4_x86_64(vaddr)) == NOT_PADDR) {
- ERRMSG("Can't convert a virtual address(%lx) to " \
- "physical address.\n", vaddr);
- return NOT_PADDR;
- }
- } else if (vaddr >= __START_KERNEL_map) {
- paddr = vaddr - __START_KERNEL_map + phys_base;
-
- } else {
- if (is_xen_memory())
- paddr = vaddr - PAGE_OFFSET_XEN_DOM0;
- else
- paddr = vaddr - PAGE_OFFSET;
- }
- return paddr;
-}
-
/*
* for Xen extraction
*/