x86: move patching code to arch-specific file.
The core patching code for paravirt is sufficiently different among i386 and x86_64, and we move them to specific files. Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
		
							parent
							
								
									21438f7c13
								
							
						
					
					
						commit
						2f485ef568
					
				| @ -48,7 +48,7 @@ obj-$(CONFIG_K8_NB)		+= k8.o | ||||
| obj-$(CONFIG_MGEODE_LX)		+= geode_32.o mfgpt_32.o | ||||
| 
 | ||||
| obj-$(CONFIG_VMI)		+= vmi_32.o vmiclock_32.o | ||||
| obj-$(CONFIG_PARAVIRT)		+= paravirt.o | ||||
| obj-$(CONFIG_PARAVIRT)		+= paravirt.o paravirt_patch_32.o | ||||
| obj-y				+= pcspeaker.o | ||||
| 
 | ||||
| obj-$(CONFIG_SCx200)		+= scx200_32.o | ||||
|  | ||||
| @ -58,59 +58,9 @@ char *memory_setup(void) | ||||
| 	extern const char start_##ops##_##name[], end_##ops##_##name[];	\ | ||||
| 	asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") | ||||
| 
 | ||||
| DEF_NATIVE(pv_irq_ops, irq_disable, "cli"); | ||||
| DEF_NATIVE(pv_irq_ops, irq_enable, "sti"); | ||||
| DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf"); | ||||
| DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax"); | ||||
| DEF_NATIVE(pv_cpu_ops, iret, "iret"); | ||||
| DEF_NATIVE(pv_cpu_ops, irq_enable_syscall_ret, "sti; sysexit"); | ||||
| DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax"); | ||||
| DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3"); | ||||
| DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax"); | ||||
| DEF_NATIVE(pv_cpu_ops, clts, "clts"); | ||||
| DEF_NATIVE(pv_cpu_ops, read_tsc, "rdtsc"); | ||||
| 
 | ||||
| /* Undefined instruction for dealing with missing ops pointers. */ | ||||
| static const unsigned char ud2a[] = { 0x0f, 0x0b }; | ||||
| 
 | ||||
| static unsigned native_patch(u8 type, u16 clobbers, void *ibuf, | ||||
| 			     unsigned long addr, unsigned len) | ||||
| { | ||||
| 	const unsigned char *start, *end; | ||||
| 	unsigned ret; | ||||
| 
 | ||||
| 	switch(type) { | ||||
| #define SITE(ops, x)						\ | ||||
| 	case PARAVIRT_PATCH(ops.x):				\ | ||||
| 		start = start_##ops##_##x;			\ | ||||
| 		end = end_##ops##_##x;				\ | ||||
| 		goto patch_site | ||||
| 
 | ||||
| 	SITE(pv_irq_ops, irq_disable); | ||||
| 	SITE(pv_irq_ops, irq_enable); | ||||
| 	SITE(pv_irq_ops, restore_fl); | ||||
| 	SITE(pv_irq_ops, save_fl); | ||||
| 	SITE(pv_cpu_ops, iret); | ||||
| 	SITE(pv_cpu_ops, irq_enable_syscall_ret); | ||||
| 	SITE(pv_mmu_ops, read_cr2); | ||||
| 	SITE(pv_mmu_ops, read_cr3); | ||||
| 	SITE(pv_mmu_ops, write_cr3); | ||||
| 	SITE(pv_cpu_ops, clts); | ||||
| 	SITE(pv_cpu_ops, read_tsc); | ||||
| #undef SITE | ||||
| 
 | ||||
| 	patch_site: | ||||
| 		ret = paravirt_patch_insns(ibuf, len, start, end); | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| unsigned paravirt_patch_nop(void) | ||||
| { | ||||
| 	return 0; | ||||
|  | ||||
							
								
								
									
										49
									
								
								arch/x86/kernel/paravirt_patch_32.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								arch/x86/kernel/paravirt_patch_32.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| #include <asm/paravirt.h> | ||||
| 
 | ||||
| DEF_NATIVE(pv_irq_ops, irq_disable, "cli"); | ||||
| DEF_NATIVE(pv_irq_ops, irq_enable, "sti"); | ||||
| DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf"); | ||||
| DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax"); | ||||
| DEF_NATIVE(pv_cpu_ops, iret, "iret"); | ||||
| DEF_NATIVE(pv_cpu_ops, irq_enable_syscall_ret, "sti; sysexit"); | ||||
| DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax"); | ||||
| DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3"); | ||||
| DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax"); | ||||
| DEF_NATIVE(pv_cpu_ops, clts, "clts"); | ||||
| DEF_NATIVE(pv_cpu_ops, read_tsc, "rdtsc"); | ||||
| 
 | ||||
| unsigned native_patch(u8 type, u16 clobbers, void *ibuf, | ||||
| 		      unsigned long addr, unsigned len) | ||||
| { | ||||
| 	const unsigned char *start, *end; | ||||
| 	unsigned ret; | ||||
| 
 | ||||
| #define PATCH_SITE(ops, x)					\ | ||||
| 		case PARAVIRT_PATCH(ops.x):			\ | ||||
| 			start = start_##ops##_##x;		\ | ||||
| 			end = end_##ops##_##x;			\ | ||||
| 			goto patch_site | ||||
| 	switch(type) { | ||||
| 		PATCH_SITE(pv_irq_ops, irq_disable); | ||||
| 		PATCH_SITE(pv_irq_ops, irq_enable); | ||||
| 		PATCH_SITE(pv_irq_ops, restore_fl); | ||||
| 		PATCH_SITE(pv_irq_ops, save_fl); | ||||
| 		PATCH_SITE(pv_cpu_ops, iret); | ||||
| 		PATCH_SITE(pv_cpu_ops, irq_enable_syscall_ret); | ||||
| 		PATCH_SITE(pv_mmu_ops, read_cr2); | ||||
| 		PATCH_SITE(pv_mmu_ops, read_cr3); | ||||
| 		PATCH_SITE(pv_mmu_ops, write_cr3); | ||||
| 		PATCH_SITE(pv_cpu_ops, clts); | ||||
| 		PATCH_SITE(pv_cpu_ops, read_tsc); | ||||
| 
 | ||||
| 	patch_site: | ||||
| 		ret = paravirt_patch_insns(ibuf, len, start, end); | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); | ||||
| 		break; | ||||
| 	} | ||||
| #undef PATCH_SITE | ||||
| 	return ret; | ||||
| } | ||||
| @ -308,6 +308,11 @@ extern struct pv_mmu_ops pv_mmu_ops; | ||||
| #define paravirt_alt(insn_string)					\ | ||||
| 	_paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") | ||||
| 
 | ||||
| /* Simple instruction patching code. */ | ||||
| #define DEF_NATIVE(ops, name, code) 					\ | ||||
| 	extern const char start_##ops##_##name[], end_##ops##_##name[];	\ | ||||
| 	asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") | ||||
| 
 | ||||
| unsigned paravirt_patch_nop(void); | ||||
| unsigned paravirt_patch_ignore(unsigned len); | ||||
| unsigned paravirt_patch_call(void *insnbuf, | ||||
| @ -322,6 +327,9 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, | ||||
| unsigned paravirt_patch_insns(void *insnbuf, unsigned len, | ||||
| 			      const char *start, const char *end); | ||||
| 
 | ||||
| unsigned native_patch(u8 type, u16 clobbers, void *ibuf, | ||||
| 		      unsigned long addr, unsigned len); | ||||
| 
 | ||||
| int paravirt_disable_iospace(void); | ||||
| 
 | ||||
| /*
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user