Commit 81bd5a84 authored by David Mosberger's avatar David Mosberger

ia64: Fine-tune the gate DSO support a bit.

parent 867cd55e
...@@ -23,7 +23,7 @@ AFLAGS_gate.lds.o += -P -C -U$(ARCH) ...@@ -23,7 +23,7 @@ AFLAGS_gate.lds.o += -P -C -U$(ARCH)
arch/ia64/kernel/gate.lds.s: %.s: %.S scripts FORCE arch/ia64/kernel/gate.lds.s: %.s: %.S scripts FORCE
$(call if_changed_dep,as_s_S) $(call if_changed_dep,as_s_S)
$(obj)/gate.so: $(src)/gate.lds.s $(obj)/gate.o $(obj)/gate.so: $(src)/gate.lds.s $(obj)/gate.o
$(CC) -nostdlib -shared -Wl,-soname=linux-gate.so.1 \ $(CC) -nostdlib -shared -s -Wl,-soname=linux-gate.so.1 \
-o $@ -Wl,-T,$^ -o $@ -Wl,-T,$^
extra-y += gate.so extra-y += gate.so
......
/* /*
* Linker script for gate DSO. The gate pages are an ELF shared * Linker script for gate DSO. The gate pages are an ELF shared object prelinked to its
* object prelinked to its virtual address, with only one read-only * virtual address, with only one read-only segment and one execute-only segment (both fit
* segment and one execute-only segment (both fit in one page). * in one page). This script controls its layout.
* This script controls its layout.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -19,20 +18,17 @@ SECTIONS ...@@ -19,20 +18,17 @@ SECTIONS
.gnu.version : { *(.gnu.version) } .gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) } .gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) } .gnu.version_r : { *(.gnu.version_r) }
.rela.dyn : { *(.rela*) } .data.patch.mckinley_e9 : { *(.data.patch.mckinley_e9) }
.dynamic : { *(.dynamic) } :rodata :dynamic
.data.patch.mckinley_e9 : { *(.data.patch.mckinley_e9) } :rodata
.data.patch.fsyscall_table : { *(.data.patch.fsyscall_table) } .data.patch.fsyscall_table : { *(.data.patch.fsyscall_table) }
.data.patch.vtop : { *(.data.patch.vtop) } .data.patch.vtop : { *(.data.patch.vtop) }
.data.patch.brl_fsys_bubble_down : { *(.data.patch.brl_fsys_bubble_down) } .data.patch.brl_fsys_bubble_down : { *(.data.patch.brl_fsys_bubble_down) }
.IA_64.unwind_info : { *(.IA_64.unwind_info*) } .IA_64.unwind_info : { *(.IA_64.unwind_info*) }
.IA_64.unwind : { *(.IA_64.unwind*) } :rodata :unwind .IA_64.unwind : { *(.IA_64.unwind*) } :rodata :unwind
.dynamic : { *(.dynamic) } :rodata :dynamic
. = GATE_ADDR + PAGE_SIZE; .text (GATE_ADDR + PAGE_SIZE) : { *(.text) } :rodata
.text : { *(.text) } :rodata
.useless : { /DISCARD/ : {
*(.got.plt) *(.got) *(.got.plt) *(.got)
*(.data .data.* .gnu.linkonce.d.*) *(.data .data.* .gnu.linkonce.d.*)
*(.dynbss) *(.dynbss)
...@@ -47,9 +43,9 @@ SECTIONS ...@@ -47,9 +43,9 @@ SECTIONS
*/ */
PHDRS PHDRS
{ {
rodata PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */ rodata PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */
dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
unwind 0x70000001; /* PT_IA_64_UNWIND */ unwind 0x70000001; /* PT_IA_64_UNWIND */
} }
/* /*
......
...@@ -287,12 +287,17 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot) ...@@ -287,12 +287,17 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
static void static void
setup_gate (void) setup_gate (void)
{ {
struct page *page0, *page1;
extern char __start_gate_section[]; extern char __start_gate_section[];
/* install the read-only and privilege-promote pages in the global page table: */ /*
put_kernel_page(virt_to_page(ia64_imva(__start_gate_section)), GATE_ADDR, PAGE_READONLY); * Install the gate pages: one read-only page containing the ELF headers etc. and
put_kernel_page(virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE)), * one execute-only page, which enables privilege-promotion via "epc":
GATE_ADDR + PAGE_SIZE, PAGE_GATE); */
page0 = virt_to_page(ia64_imva(__start_gate_section));
page1 = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE));
put_kernel_page(page0, GATE_ADDR, PAGE_READONLY);
put_kernel_page(page1, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
ia64_patch_gate((Elf64_Ehdr *) __start_gate_section); ia64_patch_gate((Elf64_Ehdr *) __start_gate_section);
} }
......
...@@ -162,8 +162,8 @@ SECTIONS ...@@ -162,8 +162,8 @@ SECTIONS
*(.data.gate) *(.data.gate)
__stop_gate_section = .; __stop_gate_section = .;
} }
. = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */
. = ALIGN(SMP_CACHE_BYTES);
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET)
{ *(.data.cacheline_aligned) } { *(.data.cacheline_aligned) }
......
...@@ -224,7 +224,6 @@ do { \ ...@@ -224,7 +224,6 @@ do { \
struct elf_phdr phdr = gate_phdrs[i]; \ struct elf_phdr phdr = gate_phdrs[i]; \
if (phdr.p_type == PT_LOAD) { \ if (phdr.p_type == PT_LOAD) { \
ofs = phdr.p_offset = offset; \ ofs = phdr.p_offset = offset; \
phdr.p_filesz = PAGE_SIZE; /* just cover RO-data */ \
offset += phdr.p_filesz; \ offset += phdr.p_filesz; \
} else \ } else \
phdr.p_offset += ofs; \ phdr.p_offset += ofs; \
......
...@@ -489,6 +489,6 @@ typedef pte_t *pte_addr_t; ...@@ -489,6 +489,6 @@ typedef pte_t *pte_addr_t;
/* These tell get_user_pages() that the first gate page is accessible from user-level. */ /* These tell get_user_pages() that the first gate page is accessible from user-level. */
#define FIXADDR_START GATE_ADDR #define FIXADDR_START GATE_ADDR
#define FIXADDR_TOP (GATE_ADDR + PAGE_SIZE) #define FIXADDR_TOP (GATE_ADDR + 2*PAGE_SIZE)
#endif /* _ASM_IA64_PGTABLE_H */ #endif /* _ASM_IA64_PGTABLE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment