|
@@ -93,7 +93,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
|
|
{
|
|
{
|
|
struct mm_struct *mm = current->mm;
|
|
struct mm_struct *mm = current->mm;
|
|
struct vm_area_struct *vma;
|
|
struct vm_area_struct *vma;
|
|
- unsigned long addr;
|
|
|
|
|
|
+ unsigned long addr, text_start;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
static struct page *no_pages[] = {NULL};
|
|
static struct page *no_pages[] = {NULL};
|
|
static struct vm_special_mapping vvar_mapping = {
|
|
static struct vm_special_mapping vvar_mapping = {
|
|
@@ -103,26 +103,28 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
|
|
|
|
|
|
if (calculate_addr) {
|
|
if (calculate_addr) {
|
|
addr = vdso_addr(current->mm->start_stack,
|
|
addr = vdso_addr(current->mm->start_stack,
|
|
- image->sym_end_mapping);
|
|
|
|
|
|
+ image->size - image->sym_vvar_start);
|
|
} else {
|
|
} else {
|
|
addr = 0;
|
|
addr = 0;
|
|
}
|
|
}
|
|
|
|
|
|
down_write(&mm->mmap_sem);
|
|
down_write(&mm->mmap_sem);
|
|
|
|
|
|
- addr = get_unmapped_area(NULL, addr, image->sym_end_mapping, 0, 0);
|
|
|
|
|
|
+ addr = get_unmapped_area(NULL, addr,
|
|
|
|
+ image->size - image->sym_vvar_start, 0, 0);
|
|
if (IS_ERR_VALUE(addr)) {
|
|
if (IS_ERR_VALUE(addr)) {
|
|
ret = addr;
|
|
ret = addr;
|
|
goto up_fail;
|
|
goto up_fail;
|
|
}
|
|
}
|
|
|
|
|
|
- current->mm->context.vdso = (void __user *)addr;
|
|
|
|
|
|
+ text_start = addr - image->sym_vvar_start;
|
|
|
|
+ current->mm->context.vdso = (void __user *)text_start;
|
|
|
|
|
|
/*
|
|
/*
|
|
* MAYWRITE to allow gdb to COW and set breakpoints
|
|
* MAYWRITE to allow gdb to COW and set breakpoints
|
|
*/
|
|
*/
|
|
vma = _install_special_mapping(mm,
|
|
vma = _install_special_mapping(mm,
|
|
- addr,
|
|
|
|
|
|
+ text_start,
|
|
image->size,
|
|
image->size,
|
|
VM_READ|VM_EXEC|
|
|
VM_READ|VM_EXEC|
|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
|
@@ -134,8 +136,8 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
|
|
}
|
|
}
|
|
|
|
|
|
vma = _install_special_mapping(mm,
|
|
vma = _install_special_mapping(mm,
|
|
- addr + image->size,
|
|
|
|
- image->sym_end_mapping - image->size,
|
|
|
|
|
|
+ addr,
|
|
|
|
+ -image->sym_vvar_start,
|
|
VM_READ,
|
|
VM_READ,
|
|
&vvar_mapping);
|
|
&vvar_mapping);
|
|
|
|
|
|
@@ -146,7 +148,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
|
|
|
|
|
|
if (image->sym_vvar_page)
|
|
if (image->sym_vvar_page)
|
|
ret = remap_pfn_range(vma,
|
|
ret = remap_pfn_range(vma,
|
|
- addr + image->sym_vvar_page,
|
|
|
|
|
|
+ text_start + image->sym_vvar_page,
|
|
__pa_symbol(&__vvar_page) >> PAGE_SHIFT,
|
|
__pa_symbol(&__vvar_page) >> PAGE_SHIFT,
|
|
PAGE_SIZE,
|
|
PAGE_SIZE,
|
|
PAGE_READONLY);
|
|
PAGE_READONLY);
|
|
@@ -157,7 +159,7 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
|
|
#ifdef CONFIG_HPET_TIMER
|
|
#ifdef CONFIG_HPET_TIMER
|
|
if (hpet_address && image->sym_hpet_page) {
|
|
if (hpet_address && image->sym_hpet_page) {
|
|
ret = io_remap_pfn_range(vma,
|
|
ret = io_remap_pfn_range(vma,
|
|
- addr + image->sym_hpet_page,
|
|
|
|
|
|
+ text_start + image->sym_hpet_page,
|
|
hpet_address >> PAGE_SHIFT,
|
|
hpet_address >> PAGE_SHIFT,
|
|
PAGE_SIZE,
|
|
PAGE_SIZE,
|
|
pgprot_noncached(PAGE_READONLY));
|
|
pgprot_noncached(PAGE_READONLY));
|