Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ia64/pv_ops: gate page paravirtualization.

paravirtualize gate page by allowing each pv_ops instances
to define its own gate page.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Tony Luck <tony.luck@intel.com>

authored by

Isaku Yamahata and committed by
Tony Luck
e4ff5b8f 1aec1c55

+231 -43
+38
arch/ia64/include/asm/native/patchlist.h
··· 1 + /****************************************************************************** 2 + * arch/ia64/include/asm/native/inst.h 3 + * 4 + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> 5 + * VA Linux Systems Japan K.K. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + * 21 + */ 22 + 23 + #define __paravirt_start_gate_fsyscall_patchlist \ 24 + __ia64_native_start_gate_fsyscall_patchlist 25 + #define __paravirt_end_gate_fsyscall_patchlist \ 26 + __ia64_native_end_gate_fsyscall_patchlist 27 + #define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \ 28 + __ia64_native_start_gate_brl_fsys_bubble_down_patchlist 29 + #define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \ 30 + __ia64_native_end_gate_brl_fsys_bubble_down_patchlist 31 + #define __paravirt_start_gate_vtop_patchlist \ 32 + __ia64_native_start_gate_vtop_patchlist 33 + #define __paravirt_end_gate_vtop_patchlist \ 34 + __ia64_native_end_gate_vtop_patchlist 35 + #define __paravirt_start_gate_mckinley_e9_patchlist \ 36 + __ia64_native_start_gate_mckinley_e9_patchlist 37 + #define __paravirt_end_gate_mckinley_e9_patchlist \ 38 + __ia64_native_end_gate_mckinley_e9_patchlist
+35
arch/ia64/include/asm/paravirt.h
··· 35 35 36 36 unsigned long *paravirt_get_fsyscall_table(void); 37 37 char *paravirt_get_fsys_bubble_down(void); 38 + 39 + /****************************************************************************** 40 + * patchlist addresses for gate page 41 + */ 42 + enum pv_gate_patchlist { 43 + PV_GATE_START_FSYSCALL, 44 + PV_GATE_END_FSYSCALL, 45 + 46 + PV_GATE_START_BRL_FSYS_BUBBLE_DOWN, 47 + PV_GATE_END_BRL_FSYS_BUBBLE_DOWN, 48 + 49 + PV_GATE_START_VTOP, 50 + PV_GATE_END_VTOP, 51 + 52 + PV_GATE_START_MCKINLEY_E9, 53 + PV_GATE_END_MCKINLEY_E9, 54 + }; 55 + 56 + struct pv_patchdata { 57 + unsigned long start_fsyscall_patchlist; 58 + unsigned long end_fsyscall_patchlist; 59 + unsigned long start_brl_fsys_bubble_down_patchlist; 60 + unsigned long end_brl_fsys_bubble_down_patchlist; 61 + unsigned long start_vtop_patchlist; 62 + unsigned long end_vtop_patchlist; 63 + unsigned long start_mckinley_e9_patchlist; 64 + unsigned long end_mckinley_e9_patchlist; 65 + 66 + void *gate_section; 67 + }; 68 + 69 + extern struct pv_patchdata pv_patchdata; 70 + 71 + unsigned long paravirt_get_gate_patchlist(enum pv_gate_patchlist type); 72 + void *paravirt_get_gate_section(void); 38 73 #endif 39 74 40 75 #ifdef CONFIG_PARAVIRT_GUEST
+5 -27
arch/ia64/kernel/Makefile
··· 5 5 extra-y := head.o init_task.o vmlinux.lds 6 6 7 7 obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ 8 - irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ 8 + irq_lsapic.o ivt.o machvec.o pal.o paravirt_patchlist.o patch.o process.o perfmon.o ptrace.o sal.o \ 9 9 salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ 10 10 unwind.o mca.o mca_asm.o topology.o 11 11 ··· 47 47 obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 48 48 endif 49 49 50 - # The gate DSO image is built using a special linker script. 51 - targets += gate.so gate-syms.o 52 - 53 - extra-y += gate.so gate-syms.o gate.lds gate.o 54 - 55 50 # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. 56 51 CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 57 52 58 - CPPFLAGS_gate.lds := -P -C -U$(ARCH) 59 - 60 - quiet_cmd_gate = GATE $@ 61 - cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ 62 - 63 - GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ 64 - $(call ld-option, -Wl$(comma)--hash-style=sysv) 65 - $(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE 66 - $(call if_changed,gate) 67 - 68 - $(obj)/built-in.o: $(obj)/gate-syms.o 69 - $(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o 70 - 71 - GATECFLAGS_gate-syms.o = -r 72 - $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE 73 - $(call if_changed,gate) 74 - 75 - # gate-data.o contains the gate DSO image as data in section .data.gate. 76 - # We must build gate.so before we can assemble it. 77 - # Note: kbuild does not track this dependency due to usage of .incbin 78 - $(obj)/gate-data.o: $(obj)/gate.so 53 + # The gate DSO image is built using a special linker script. 54 + include $(srctree)/arch/ia64/kernel/Makefile.gate 55 + # tell compiled for native 56 + CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_NATIVE 79 57 80 58 # Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config 81 59 define sed-y
+27
arch/ia64/kernel/Makefile.gate
··· 1 + # The gate DSO image is built using a special linker script. 2 + 3 + targets += gate.so gate-syms.o 4 + 5 + extra-y += gate.so gate-syms.o gate.lds gate.o 6 + 7 + CPPFLAGS_gate.lds := -P -C -U$(ARCH) 8 + 9 + quiet_cmd_gate = GATE $@ 10 + cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ 11 + 12 + GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ 13 + $(call ld-option, -Wl$(comma)--hash-style=sysv) 14 + $(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE 15 + $(call if_changed,gate) 16 + 17 + $(obj)/built-in.o: $(obj)/gate-syms.o 18 + $(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o 19 + 20 + GATECFLAGS_gate-syms.o = -r 21 + $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE 22 + $(call if_changed,gate) 23 + 24 + # gate-data.o contains the gate DSO image as data in section .data.gate. 25 + # We must build gate.so before we can assemble it. 26 + # Note: kbuild does not track this dependency due to usage of .incbin 27 + $(obj)/gate-data.o: $(obj)/gate.so
+9 -8
arch/ia64/kernel/gate.lds.S
··· 7 7 8 8 9 9 #include <asm/system.h> 10 + #include "paravirt_patchlist.h" 10 11 11 12 SECTIONS 12 13 { ··· 34 33 . = GATE_ADDR + 0x600; 35 34 36 35 .data.patch : { 37 - __start_gate_mckinley_e9_patchlist = .; 36 + __paravirt_start_gate_mckinley_e9_patchlist = .; 38 37 *(.data.patch.mckinley_e9) 39 - __end_gate_mckinley_e9_patchlist = .; 38 + __paravirt_end_gate_mckinley_e9_patchlist = .; 40 39 41 - __start_gate_vtop_patchlist = .; 40 + __paravirt_start_gate_vtop_patchlist = .; 42 41 *(.data.patch.vtop) 43 - __end_gate_vtop_patchlist = .; 42 + __paravirt_end_gate_vtop_patchlist = .; 44 43 45 - __start_gate_fsyscall_patchlist = .; 44 + __paravirt_start_gate_fsyscall_patchlist = .; 46 45 *(.data.patch.fsyscall_table) 47 - __end_gate_fsyscall_patchlist = .; 46 + __paravirt_end_gate_fsyscall_patchlist = .; 48 47 49 - __start_gate_brl_fsys_bubble_down_patchlist = .; 48 + __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .; 50 49 *(.data.patch.brl_fsys_bubble_down) 51 - __end_gate_brl_fsys_bubble_down_patchlist = .; 50 + __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .; 52 51 } :readable 53 52 54 53 .IA_64.unwind_info : { *(.IA_64.unwind_info*) }
+79
arch/ia64/kernel/paravirt_patchlist.c
··· 1 + /****************************************************************************** 2 + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> 3 + * VA Linux Systems Japan K.K. 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 + * 19 + */ 20 + 21 + #include <linux/bug.h> 22 + #include <asm/paravirt.h> 23 + 24 + #define DECLARE(name) \ 25 + extern unsigned long \ 26 + __ia64_native_start_gate_##name##_patchlist[]; \ 27 + extern unsigned long \ 28 + __ia64_native_end_gate_##name##_patchlist[] 29 + 30 + DECLARE(fsyscall); 31 + DECLARE(brl_fsys_bubble_down); 32 + DECLARE(vtop); 33 + DECLARE(mckinley_e9); 34 + 35 + extern unsigned long __start_gate_section[]; 36 + 37 + #define ASSIGN(name) \ 38 + .start_##name##_patchlist = \ 39 + (unsigned long)__ia64_native_start_gate_##name##_patchlist, \ 40 + .end_##name##_patchlist = \ 41 + (unsigned long)__ia64_native_end_gate_##name##_patchlist 42 + 43 + struct pv_patchdata pv_patchdata __initdata = { 44 + ASSIGN(fsyscall), 45 + ASSIGN(brl_fsys_bubble_down), 46 + ASSIGN(vtop), 47 + ASSIGN(mckinley_e9), 48 + 49 + .gate_section = (void*)__start_gate_section, 50 + }; 51 + 52 + 53 + unsigned long __init 54 + paravirt_get_gate_patchlist(enum pv_gate_patchlist type) 55 + { 56 + 57 + #define CASE(NAME, name) \ 58 + case PV_GATE_START_##NAME: \ 59 + return pv_patchdata.start_##name##_patchlist; \ 60 + case PV_GATE_END_##NAME: \ 61 + return pv_patchdata.end_##name##_patchlist; \ 62 + 63 + switch (type) { 64 + CASE(FSYSCALL, fsyscall); 65 + CASE(BRL_FSYS_BUBBLE_DOWN, brl_fsys_bubble_down); 66 + CASE(VTOP, vtop); 67 + CASE(MCKINLEY_E9, mckinley_e9); 68 + default: 69 + BUG(); 70 + break; 71 + } 72 + return 0; 73 + } 74 + 75 + void * __init 76 + paravirt_get_gate_section(void) 77 + { 78 + return pv_patchdata.gate_section; 79 + }
+28
arch/ia64/kernel/paravirt_patchlist.h
··· 1 + /****************************************************************************** 2 + * linux/arch/ia64/xen/paravirt_patchlist.h 3 + * 4 + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> 5 + * VA Linux Systems Japan K.K. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + * 21 + */ 22 + 23 + #if defined(__IA64_GATE_PARAVIRTUALIZED_XEN) 24 + #include <asm/xen/patchlist.h> 25 + #else 26 + #include <asm/native/patchlist.h> 27 + #endif 28 +
+6 -6
arch/ia64/kernel/patch.c
··· 227 227 void __init 228 228 ia64_patch_gate (void) 229 229 { 230 - # define START(name) ((unsigned long) __start_gate_##name##_patchlist) 231 - # define END(name) ((unsigned long)__end_gate_##name##_patchlist) 230 + # define START(name) paravirt_get_gate_patchlist(PV_GATE_START_##name) 231 + # define END(name) paravirt_get_gate_patchlist(PV_GATE_END_##name) 232 232 233 - patch_fsyscall_table(START(fsyscall), END(fsyscall)); 234 - patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down)); 235 - ia64_patch_vtop(START(vtop), END(vtop)); 236 - ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9)); 233 + patch_fsyscall_table(START(FSYSCALL), END(FSYSCALL)); 234 + patch_brl_fsys_bubble_down(START(BRL_FSYS_BUBBLE_DOWN), END(BRL_FSYS_BUBBLE_DOWN)); 235 + ia64_patch_vtop(START(VTOP), END(VTOP)); 236 + ia64_patch_mckinley_e9(START(MCKINLEY_E9), END(MCKINLEY_E9)); 237 237 } 238 238 239 239 void ia64_patch_phys_stack_reg(unsigned long val)
+4 -2
arch/ia64/mm/init.c
··· 260 260 static void __init 261 261 setup_gate (void) 262 262 { 263 + void *gate_section; 263 264 struct page *page; 264 265 265 266 /* ··· 268 267 * headers etc. and once execute-only page to enable 269 268 * privilege-promotion via "epc": 270 269 */ 271 - page = virt_to_page(ia64_imva(__start_gate_section)); 270 + gate_section = paravirt_get_gate_section(); 271 + page = virt_to_page(ia64_imva(gate_section)); 272 272 put_kernel_page(page, GATE_ADDR, PAGE_READONLY); 273 273 #ifdef HAVE_BUGGY_SEGREL 274 - page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE)); 274 + page = virt_to_page(ia64_imva(gate_section + PAGE_SIZE)); 275 275 put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); 276 276 #else 277 277 put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);