Basic infrastructure patches for a paravirtualized kernel
Subsystems (3)
cover Basic infrastructure patches for a paravirtualized kernel
Hi Andrew,
This series of patches lays the basic ground work for the paravirtualized kernel patches coming later on. I think this lot is ready for the rough-and-tumble world of the -mm tree.
The main change from the last posting is that all the page-table related patches have been moved out, and will be posted separately.
Also, the off-by-one in reserving the top of address space has been fixed.
For the most part, these patches do nothing or very little. The patches should be self explanatory, but the overview is:
Helper functions for later use:
2/8: Implement always-locked bit ops...
8/8: Put .note.* sections into a PT_NOTE segment in vmlinux
Cleanups:
1/8: Remove locally-defined ldt structure in favour of standard type 3/8: Allow a kernel to not be in ring 0
5/8: Roll all the cpuid asm into one __cpuid call
Hooks:
4/8: Replace sensitive instructions with macros 6/8: Make __FIXADDR_TOP variable to allow it to make space... 7/8: Add a bootparameter to reserve high linear address...
8/8 "Put .note.* sections into a PT_NOTE segment in vmlinux" is mostly here to shake out problems early. It slightly changes the way the vmlinux image is linked together, and it uses the somewhat esoteric PHDRS command in vmlinux.lds. I want to make sure that this doesn't provoke any problems in the various binutils people are using.
Thanks,
J
PATCH 1/8 Remove locally-defined ldt structure in favour of standard type.
arch/i386/kernel/reboot.c defines its own struct to describe an ldt
entry: it should use struct Xgt_desc_struct (currently load_ldt is a macro, so doesn't complain: paravirt patches make it warn).
--- arch/i386/kernel/reboot.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
===================================================================
arch/i386/kernel/reboot.c +4 -8
@@ -145,14 +145,10 @@ real_mode_gdt_entries [3] = 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ }; -static struct -{ -unsigned short size __attribute__ ((packed)); -unsigned long long * base __attribute__ ((packed)); -} -real_mode_gdt = {sizeof (real_mode_gdt_entries) -1 , real_mode_gdt_entries }, -real_mode_idt = {0x3ff ,NULL }, -no_idt = {0 ,NULL }; +static struct Xgt_desc_struct +real_mode_gdt = {sizeof (real_mode_gdt_entries) -1 , (long )real_mode_gdt_entries }, +real_mode_idt = {0x3ff ,0 }, +no_idt = {0 ,0 };/* This is 16-bit protected mode code to disable paging and the cache,
--
PATCH 2/8 Implement always-locked bit ops, for memory shared with an SMP hypervisor.
In reply to Jeremy FitzhardingeAdd "always lock'd" implementations of set_bit, clear_bit and change_bit and the corresponding test_and_ functions. Also add "always lock'd" implementation of cmpxchg. These give guaranteed strong synchronisation and are required for non-SMP kernels running on an SMP hypervisor.
--- include/asm-i386/sync_bitops.h | 156 ++++++++++++++++++++++++++++++++++++++++ include/asm-i386/system.h | 36 +++++++++ 2 files changed, 192 insertions(+)
===================================================================
include/asm-i386/system.h +36 -0
@@ -261,6 +261,9 @@ static inline unsigned long __xchg(unsig#define cmpxchg (ptr,o,n)\ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ (unsigned long)(n),sizeof(*(ptr)))) +#define sync_cmpxchg (ptr,o,n)\ + ((__typeof__(*(ptr)))__sync_cmpxchg((ptr),(unsigned long)(o),\ + (unsigned long)(n),sizeof(*(ptr))))#endif static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
@@ -282,6 +285,39 @@ static inline unsigned long __cmpxchg(voreturn prev;case 4 : __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" + :"=a" (prev) + :"r" (new),"m" (*__xg (ptr)),"0" (old) + :"memory" ); +return prev; + } +return old; +} + +/* +* Always use locked operations when touching memory shared with a +* hypervisor, since the system may be SMP even if the guest kernel +* isn't. +*/ +static inline unsigned long __sync_cmpxchg (volatile void *ptr, +unsigned long old, +unsigned long new,int size) +{ +unsigned long prev; +switch (size) { +case 1 : + __asm__ __volatile__("lock; cmpxchgb %b1,%2" + :"=a" (prev) + :"q" (new),"m" (*__xg (ptr)),"0" (old) + :"memory" ); +return prev; +case 2 : + __asm__ __volatile__("lock; cmpxchgw %w1,%2" + :"=a" (prev) + :"r" (new),"m" (*__xg (ptr)),"0" (old) + :"memory" ); +return prev; +case 4 : + __asm__ __volatile__("lock; cmpxchgl %1,%2" :"=a" (prev) :"r" (new),"m" (*__xg (ptr)),"0" (old) :"memory" );
===================================================================
include/asm-i386/sync_bitops.h new file +156 -0
156 lines not on this page · raw message
--
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 5 lines · Jeremy Fitzhardinge
Add "always lock'd" implementations of
set_bit,clear_bitandchange_bitand the correspondingtest_and_functions. Also add "always lock'd" implementation of cmpxchg. These give guaranteed strong synchronisation and are required for non-SMP kernels running on an SMP hypervisor.
I think I asked this before....
Would it not be simpler to always use the locked implementation on UP? At least when the kernel is compiled with hypervisor support? This is going to add yet another series of bit operations.
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 3 lines · Christoph Lameter
I think I asked this before....
Would it not be simpler to always use the locked implementation on UP? At least when the kernel is compiled with hypervisor support? This is going to add yet another series of bit operations
You mean make the standard bit-ops atomic on UP when compiling for CONFIG_PARAVIRT? We think its too much of a burden; there are only a few operations which must be locked in the hypervisor case, and bit ops are used everywhere. I'd like to get it to the point where there's no significant overhead in configuring for PARAVIRT, even if you run on native hardware.
J
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 9 lines · Jeremy Fitzhardinge
Quoted 3 lines
Would it not be simpler to always use the locked implementation on UP? At least when the kernel is compiled with hypervisor support? This is going to add yet another series of bit operations
You mean make the standard bit-ops atomic on UP when compiling for
CONFIG_PARAVIRT? We think its too much of a burden; there are only a few operations which must be locked in the hypervisor case, and bit ops are used everywhere. I'd like to get it to the point where there's no significant overhead in configuring for PARAVIRT, even if you run on native hardware.
Thats a good goal but what about the rest of us who have to maintain additional forms of bit operations for all architectures. How much is this burden? Are locked atomic bitops really that more expensive?
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 2 lines · Christoph Lameter
Thats a good goal but what about the rest of us who have to maintain additional forms of bit operations for all architectures. How much is this burden? Are locked atomic bitops really that more expensive?
It needn't be all architectures yet - only architectures that want to compile Xen drivers are really affected. Perhaps a better place for these locking primitives is in a Xen-specific driver header which defines appropriate primitives for the architectures required? Last I remember, there were still some issues here where atomic partial word operations couldn't be supported on some architectures.
To answer your question, yes. On most i386 cores, locks destroy performance, and even unintentional use of a single locked operation in a critical path, on uncontended local memory, can have several hundred cycles downstream penalty. I accidentally used one once during context switch, and saw a 30% reduction in switch performance - on a modern processor.
Zach
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 6 lines · Zachary Amsden
It needn't be all architectures yet - only architectures that want to compile Xen drivers are really affected. Perhaps a better place for these locking primitives is in a Xen-specific driver header which defines appropriate primitives for the architectures required? Last I remember, there were still some issues here where atomic partial word operations couldn't be supported on some architectures.
Good idea. This will also make it easier to support this special functionality. And it will avoid use in contexts where these are not necessary.
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 3 lines · Christoph Lameter
Good idea. This will also make it easier to support this special functionality. And it will avoid use in contexts where these are not necessary.
I think it's a bad idea. We don't want lots of architecture ifdefs in some Xen specific file
-Andi
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 8 lines · Andi Kleen
Quoted 3 lines · Christoph Lameter
Good idea. This will also make it easier to support this special functionality. And it will avoid use in contexts where these are not necessary.
I think it's a bad idea. We don't want lots of architecture ifdefs in some Xen specific file
Thats not how it would be done. We would do this with architecture specific xen files and a default in asm-generic.
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 8 lines · Christoph Lameter
Quoted 6 lines · Andi Kleen
Quoted 3 lines · Christoph Lameter
Good idea. This will also make it easier to support this special functionality. And it will avoid use in contexts where these are not necessary.
Quoted 5 lines
Quoted 2 lines
I think it's a bad idea. We don't want lots of architecture ifdefs in some Xen specific file
Thats not how it would be done. We would do this with architecture specific xen files and a default in asm-generic.
It's cleaner to just do it in the generic code.
I think for most architectures it is only a one liner anyways if done properly.
-Andi
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
In reply to Christoph LameterQuoted 4 lines
Thats a good goal but what about the rest of us who have to maintain additional forms of bit operations for all architectures. How much is this burden?
I don't think it's that big an issue because most architectures either use always locked bitops already or don't need them because they don't do SMP.
So it will be fine with just a asm-generic header that defines them to the normal bitops. Not much burden.
-Andi
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 8 lines · Andi Kleen
Quoted 4 lines
Thats a good goal but what about the rest of us who have to maintain additional forms of bit operations for all architectures. How much is this burden?
I don't think it's that big an issue because most architectures either use always locked bitops already or don't need them because they don't do SMP.
Those architectures that always use locked bitops or dont need them would not need to be modified if we put this in a special fail. I think this is a i386 speciality here?
Those operations are only needed for special xen driver and not for regular kernel code!
Quoted 2 lines
So it will be fine with just a asm-generic header that defines them to the normal bitops. Not much burden.
asm-generic/xen-bitops.h asm-i386/xen-bitops.h is even less of a burden and would only require a
#include <asm/xen-bitops.h>
for those special xen drivers.
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 7 lines · Christoph Lameter
Quoted 5 lines · Andi Kleen
Quoted 4 lines
Thats a good goal but what about the rest of us who have to maintain additional forms of bit operations for all architectures. How much is this burden?
Quoted 7 lines
Quoted 3 lines
I don't think it's that big an issue because most architectures either use always locked bitops already or don't need them because they don't do SMP.
Those architectures that always use locked bitops or dont need them would not need to be modified if we put this in a special fail. I think this is a i386 speciality here?
i386/x86-64
They could do a single line #include for asm-generic that defines them to the normal bitops.
Quoted 3 lines
Those operations are only needed for special xen driver and not for regular kernel code!
The Xen driver will be "regular" kernel code.
Quoted 9 lines
Quoted 2 lines
So it will be fine with just a asm-generic header that defines them to the normal bitops. Not much burden.
asm-generic/xen-bitops.hasm-i386/xen-bitops.his even less of a burden and would only require a#include <
asm/xen-bitops.h>for those special xen drivers.
Well there might be reasons someone else uses this in the future too. It's also not exactly Linux style - normally we try to add generic facilities.
-Andi
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 4 lines · Andi Kleen
Quoted 2 lines
Those operations are only needed for special xen driver and not for regular kernel code!
The Xen driver will be "regular" kernel code.
As far as I can tell from this conversation there are special "Xen" drivers that need this not the rest of the system.
Quoted 5 lines
Quoted 1 line
for those special xen drivers.
Well there might be reasons someone else uses this in the future too. It's also not exactly Linux style - normally we try to add generic facilities.
What possible use could there be to someone else?
The "atomic" ops lock/unlock crap exists only for i386 as far as I can tell. As you said most architectures either always use atomic ops or never. The lock/unlock atomic ops are i386 specific material that better stay contained. Its arch specific and not generic.
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 3 lines
As far as I can tell from this conversation there are special "Xen" drivers that need this not the rest of the system.
Yes, but in general when a driver that runs on multiple architectures (including IA64 btw) needs something architecture specific we usually add it to asm, not add ifdefs.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
for those special xen drivers.
Well there might be reasons someone else uses this in the future too. It's also not exactly Linux style - normally we try to add generic facilities.
What possible use could there be to someone else?
e.g. for other hypervisors or possibly for special hardware access (e.g. I could imagine it being used for some kind of cluster interconnect) I remember Alan was using a similar hack in his EDAC drivers because it was the only way to clear ECC errors.
Quoted 4 lines
The "atomic" ops lock/unlock crap exists only for i386 as far as I can tell. As you said most architectures either always use atomic ops or never. The lock/unlock atomic ops are i386 specific material that better stay contained. Its arch specific and not generic.
Well we have our share of weird hacks for IA64 too in generic code.
Just adding a single line #include for a wrapper asm-generic surely isn't a undue burden for the other architectures, and it will save some mess in the Xen drivers.
-Andi
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 6 lines · Andi Kleen
Quoted 2 lines
As far as I can tell from this conversation there are special "Xen" drivers that need this not the rest of the system.
Yes, but in general when a driver that runs on multiple architectures (including IA64 btw) needs something architecture specific we usually add it to asm, not add ifdefs.
I still wonder why you are so focused on ifdefs. Why would we need those?
Quoted 6 lines
Quoted 1 line
What possible use could there be to someone else?
e.g. for other hypervisors or possibly for special hardware access (e.g. I could imagine it being used for some kind of cluster interconnect) I remember Alan was using a similar hack in his EDAC drivers because it was the only way to clear ECC errors.
Maybe the best thing would be to have proper atomic ops in UP mode on i386? The current way of just dropping the lock bit is the source of the troubles.
Quoted 6 lines
Quoted 4 lines
The "atomic" ops lock/unlock crap exists only for i386 as far as I can tell. As you said most architectures either always use atomic ops or never. The lock/unlock atomic ops are i386 specific material that better stay contained. Its arch specific and not generic.
Well we have our share of weird hacks for IA64 too in generic code.
But we all try to contain them. Here we have i386 hacks multiplying all over the system.
Quoted 3 lines
Just adding a single line #include for a wrapper asm-generic surely isn't a undue burden for the other architectures, and it will save some mess in the Xen drivers.
Just adding a single line #include <asm/xen-bitops.h> to drivers that need this functionality is not an undue burden for the drivers that support Xen. They have to use special _xxx bitops anyways.
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 10 lines · Christoph Lameter
Quoted 6 lines · Andi Kleen
Quoted 2 lines
As far as I can tell from this conversation there are special "Xen" drivers that need this not the rest of the system.
Yes, but in general when a driver that runs on multiple architectures (including IA64 btw) needs something architecture specific we usually add it to asm, not add ifdefs.
I still wonder why you are so focused on ifdefs. Why would we need those?
Because the Xen drivers will run on a couple of architectures, including IA64 and PPC.
If IA64 or PPC didn't implement at least wrappers for the sync ops then they would all need special ifdefs to handle this.
Quoted 11 lines
Quoted 7 lines
Quoted 2 lines
What possible use could there be to someone else?
e.g. for other hypervisors or possibly for special hardware access (e.g. I could imagine it being used for some kind of cluster interconnect) I remember Alan was using a similar hack in his EDAC drivers because it was the only way to clear ECC errors.
Maybe the best thing would be to have proper atomic ops in UP mode on i386? The current way of just dropping the lock bit is the source of the troubles.
It's a huge performance difference.
Quoted 7 lines
Quoted 3 lines
Just adding a single line #include for a wrapper asm-generic surely isn't a undue burden for the other architectures, and it will save some mess in the Xen drivers.
Just adding a single line #include <
asm/xen-bitops.h> to drivers that need this functionality is not an undue burden for the drivers that support Xen. They have to use special_xxxbitops anyways.
Ok it could be put into a separate file (although with a neutral name)
But you would still need to add that to IA64, PPC etc. too, so it would only avoid adding a single to the other architectures. -Andi
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 7 lines · Andi Kleen
Quoted 1 line
I still wonder why you are so focused on ifdefs. Why would we need those?
Because the Xen drivers will run on a couple of architectures, including IA64 and PPC.
If IA64 or PPC didn't implement at least wrappers for the sync ops then they would all need special ifdefs to handle this.
No they would just need to do an #include <xen-bitops.h>
Quoted 5 lines
Quoted 3 lines
Maybe the best thing would be to have proper atomic ops in UP mode on i386? The current way of just dropping the lock bit is the source of the troubles.
It's a huge performance difference.
I understand but why dont we use regular ops explicitly instead of hacking the atomic ops. Then we would not have unhack them now.
Quoted 8 lines
Quoted 3 lines
Just adding a single line #include <
asm/xen-bitops.h> to drivers that need this functionality is not an undue burden for the drivers that support Xen. They have to use special_xxxbitops anyways.Ok it could be put into a separate file (although with a neutral name)
But you would still need to add that to IA64, PPC etc. too, so it would only avoid adding a single to the other architectures.
Could we not just add one fallback definition to asm-generic?
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 11 lines · Christoph Lameter
Quoted 7 lines · Andi Kleen
Quoted 1 line
I still wonder why you are so focused on ifdefs. Why would we need those?
Because the Xen drivers will run on a couple of architectures, including IA64 and PPC.
If IA64 or PPC didn't implement at least wrappers for the sync ops then they would all need special ifdefs to handle this.
No they would just need to do an #include <
xen-bitops.h>
If IA64 and PPC64 wouldn't have xen-bitops.h (which you seem to argue for) then they would need ifdefs.
Quoted 4 lines
Quoted 2 lines
But you would still need to add that to IA64, PPC etc. too, so it would only avoid adding a single to the other architectures.
Could we not just add one fallback definition to asm-generic?
You mean into asm-generic/bitops.h? Then it would need ifdefs to handle the i386/x86-64 case.
-Andi
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 8 lines · Andi Kleen
Quoted 7 lines · Christoph Lameter
Quoted 5 lines · Andi Kleen
Quoted 1 line
I still wonder why you are so focused on ifdefs. Why would we need those?
Because the Xen drivers will run on a couple of architectures, including IA64 and PPC.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
If IA64 or PPC didn't implement at least wrappers for the sync ops then they would all need special ifdefs to handle this.
No they would just need to do an #include <
xen-bitops.h>If IA64 and PPC64 wouldn't have
xen-bitops.h(which you seem to argue for) then they would need ifdefs.
An include <asm/xen-bitops.h> would need to fall back to asm-generic if there is no file in asm-arch/xen-bitops.h. I thought we had such a mechanism?
Quoted 2 lines
You mean into
asm-generic/bitops.h? Then it would need ifdefs to handle the i386/x86-64 case.
No. Into asm-generic/xen-bitops.h.
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 3 lines · * Christoph Lameter ([email protected]) wrote:
An include <
asm/xen-bitops.h> would need to fall back to asm-generic if there is no file inasm-arch/xen-bitops.h. I thought we had such a mechanism?
While Xen is the primary user, it is a misnomer to call it xen-bitops. These are simply always locked, hence the sync-bitops name. Also, there's a use of sync_cmpxchg, and cmpxchg is not in bitops.h.
As for the mechanism, it is manual. Arch specific header includes asm-generic one.
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
In reply to Christoph LameterQuoted 4 lines
An include <
asm/xen-bitops.h> would need to fall back to asm-generic if there is no file inasm-arch/xen-bitops.h. I thought we had such a mechanism?
AFAIK not. If you want generic you need a proxy include file.
-Andi
Re: [patch 2/8] Implement always-locked bit ops, for memory shared with an SMP hypervisor.
Quoted 4 lines · Andi Kleen
Quoted 3 lines
An include <
asm/xen-bitops.h> would need to fall back to asm-generic if there is no file inasm-arch/xen-bitops.h. I thought we had such a mechanism?AFAIK not. If you want generic you need a proxy include file.
Hmm... Well then we have no way of adding a new asm-arch file without adding them to each arch. Makes it difficult to add new functionality.
PATCH 3/8 Allow a kernel to not be in ring 0.
In reply to Jeremy FitzhardingeWe allow for the fact that the guest kernel may not run in ring 0. This requires some abstraction in a few places when setting %cs or checking privilege level (user vs kernel).
This is Chris' [RFC PATCH 15/33] move segment checks to subarch, except rather than using #define USER_MODE_MASK which depends on a config option, we use Zach's more flexible approach of assuming ring 3 == userspace. I also used "get_kernel_rpl()" over "get_kernel_cs()" because I think it reads better in the code...
1) Remove the hardcoded 3 and introduce #define SEGMENT_RPL_MASK 3
2) Add a get_kernel_rpl() macro, and don't assume it's zero.
--- arch/i386/kernel/entry.S | 5 +++-- arch/i386/kernel/process.c | 2 +- arch/i386/mm/extable.c | 2 +- arch/i386/mm/fault.c | 11 ++++------- include/asm-i386/ptrace.h | 5 +++-- include/asm-i386/segment.h | 10 ++++++++++ 6 files changed, 22 insertions(+), 13 deletions(-)
===================================================================
arch/i386/kernel/entry.S +3 -2
@@ -229,8 +229,9 @@ check_userspace: check_userspace: movl EFLAGS(%esp), %eax # mix EFLAGS and CS movb CS(%esp), %al - testl $(VM_MASK | 3), %eax - jz resume_kernel + andl $(VM_MASK | SEGMENT_RPL_MASK), %eax + cmpl $SEGMENT_RPL_MASK, %eax + jb resume_kernel # not returning to v8086 or userspace ENTRY(resume_userspace) cli # make sure we don't miss an interrupt # setting need_resched or sigpending
===================================================================
arch/i386/kernel/process.c +1 -1
@@ -346,7 +346,7 @@ int kernel_thread(int (*fn)(void *), voi regs.xes = __USER_DS; regs.orig_eax =-1 ; regs.eip = (unsigned long ) kernel_thread_helper; - regs.xcs = __KERNEL_CS; + regs.xcs = __KERNEL_CS |get_kernel_rpl (); regs.eflags =X86_EFLAGS_IF |X86_EFLAGS_SF |X86_EFLAGS_PF |0x2 ;/* Ok, create the new process.. */
===================================================================
arch/i386/mm/extable.c +1 -1
@@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regsconst struct exception_table_entry *fixup;#ifdef CONFIG_PNPBIOS -if (unlikely ((regs->xcs & ~15 ) == (GDT_ENTRY_PNPBIOS_BASE <<3 ))) +if (unlikely (SEGMENT_IS_PNP_CODE (regs->xcs))) {extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;extern u32 pnp_bios_is_utter_crap;
===================================================================
arch/i386/mm/fault.c +4 -7
@@ -27,6 +27,7 @@#include <asm/uaccess.h> #include <asm/desc.h> #include <asm/kdebug.h> +#include <asm/segment.h> extern void die (const char *,struct pt_regs *,long );
@@ -119,10 +120,10 @@ static inline unsigned long get_segment_ }/* The standard kernel/user address space limit. */ - *eip_limit = (seg &3 ) ?USER_DS .seg :KERNEL_DS .seg; + *eip_limit =user_mode (regs) ?USER_DS .seg :KERNEL_DS .seg;/* By far the most common cases. */ -if (likely (seg == __USER_CS || seg == __KERNEL_CS)) +if (likely (SEGMENT_IS_FLAT_CODE (seg)))return eip;/* Check the segment exists, is within the current LDT/GDT size,
@@ -436,11 +437,7 @@ good_area: write =0 ;switch (error_code &3 ) {default :/* 3: write, present */ -#ifdef TEST_VERIFY_AREA -if (regs->cs ==KERNEL_CS ) -printk ("WP fault at %08lx\n" , regs->eip); -#endif -/* fall through */ +/* fall through */ case 2 :/* write, not present */ if (!(vma->vm_flags &VM_WRITE )) goto bad_area;
===================================================================
include/asm-i386/ptrace.h +3 -2
@@ -60,6 +60,7 @@ struct pt_regs {#ifdef __KERNEL__#include <asm/vm86.h> +#include <asm/segment.h> struct task_struct ;extern void send_sigtrap (struct task_struct *tsk,struct pt_regs *regs,int error_code);
@@ -73,11 +74,11 @@ extern void send_sigtrap(struct task_str*/ static inline int user_mode (struct pt_regs *regs) { -return (regs->xcs &3 ) !=0 ; +return (regs->xcs &SEGMENT_RPL_MASK ) ==3 ; }static inline int user_mode_vm (struct pt_regs *regs) { -return ((regs->xcs &3 ) | (regs->eflags &VM_MASK )) !=0 ; +return (((regs->xcs &SEGMENT_RPL_MASK ) | (regs->eflags &VM_MASK )) >=3 ); }#define instruction_pointer (regs) ((regs)->eip)#if defined(CONFIG_SMP ) && defined(CONFIG_FRAME_POINTER )
===================================================================
include/asm-i386/segment.h +10 -0
@@ -83,6 +83,12 @@#define GDT_SIZE (GDT_ENTRIES * 8) +/* +* Some tricky tests to match code segments after a fault +*/ +#define SEGMENT_IS_FLAT_CODE (x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8) +#define SEGMENT_IS_PNP_CODE (x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) +/* Simple and small GDT entries for booting only */ #define GDT_ENTRY_BOOT_CS 2
@@ -112,4 +118,8 @@*/ #define IDT_ENTRIES 256 +/* Bottom three bits of xcs give the ring privilege level */ +#define SEGMENT_RPL_MASK 0x3 + +#define get_kernel_rpl () 0#endif
--
PATCH 4/8 Replace sensitive instructions with macros.
In reply to Jeremy FitzhardingeAbstract sensitive instructions in assembler code, replacing them with macros (which currently are #defined to the native versions). We use long names: assembler is case-insensitive, so if something goes wrong and macros do not expand, it would assemble anyway.
Resulting object files are exactly the same as before.
--- arch/i386/kernel/entry.S | 38 ++++++++++++++++++++++---------------- include/asm-i386/spinlock.h | 7 +++++-- 2 files changed, 27 insertions(+), 18 deletions(-)
===================================================================
arch/i386/kernel/entry.S +22 -16
@@ -76,8 +76,15 @@ NT_MASK = 0x00004000 NT_MASK = 0x00004000 VM_MASK = 0x00020000 +/* These are replaces for paravirtualization */ +#define DISABLE_INTERRUPTS cli +#define ENABLE_INTERRUPTS sti +#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit +#define INTERRUPT_RETURN iret +#define GET_CR0_INTO_EAX movl %cr0, %eax + #ifdef CONFIG_PREEMPT -#define preempt_stop cli; TRACE_IRQS_OFF +#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF #else #define preempt_stop #define resume_kernel restore_nocheck
@@ -233,7 +240,7 @@ check_userspace: cmpl $SEGMENT_RPL_MASK, %eax jb resume_kernel # not returning to v8086 or userspace ENTRY(resume_userspace) - cli # make sure we don't miss an interrupt + DISABLE_INTERRUPTS # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx
@@ -244,7 +251,7 @@ ENTRY(resume_userspace) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) - cli + DISABLE_INTERRUPTS cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_nocheck need_resched:
@@ -272,7 +279,7 @@ sysenter_past_esp: * No need to follow this irqs on/off section: the syscall * disabled irqs and here we enable it straight after entry: */ - sti + ENABLE_INTERRUPTS pushl $(__USER_DS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET ss, 0*/
@@ -317,7 +324,7 @@ 1: movl (%ebp),%ebp jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) - cli + DISABLE_INTERRUPTS TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx
@@ -327,8 +334,7 @@ 1: movl (%ebp),%ebp movl OLDESP(%esp), %ecx xorl %ebp,%ebp TRACE_IRQS_ON - sti - sysexit + ENABLE_INTERRUPTS_SYSEXIT CFI_ENDPROC
@@ -353,7 +359,7 @@ syscall_call: call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) # store the return value syscall_exit: - cli # make sure we don't miss an interrupt + DISABLE_INTERRUPTS # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF
@@ -378,11 +384,11 @@ restore_nocheck_notrace: RESTORE_REGS addl $4, %esp CFI_ADJUST_CFA_OFFSET -4 -1: iret +1: INTERRUPT_RETURN .section .fixup,"ax" iret_exc: TRACE_IRQS_ON - sti + ENABLE_INTERRUPTS pushl $0 # no error code pushl $do_iret_error jmp error_code
@@ -406,7 +412,7 @@ ldt_ss: * dosemu and wine happy. */ subl $8, %esp # reserve space for switch16 pointer CFI_ADJUST_CFA_OFFSET 8 - cli + DISABLE_INTERRUPTS TRACE_IRQS_OFF movl %esp, %eax /* Set up the 16bit stack frame with switch32 pointer on top,
@@ -416,7 +422,7 @@ ldt_ss: TRACE_IRQS_IRET RESTORE_REGS lss 20+4(%esp), %esp # switch to 16bit stack -1: iret +1: INTERRUPT_RETURN .section __ex_table,"a" .align 4 .long 1b,iret_exc
@@ -431,7 +437,7 @@ work_pending: jz work_notifysig work_resched: call schedule - cli # make sure we don't miss an interrupt + DISABLE_INTERRUPTS # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF
@@ -487,7 +493,7 @@ syscall_exit_work: testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl jz work_pending TRACE_IRQS_ON - sti # could let do_syscall_trace() call + ENABLE_INTERRUPTS # could let do_syscall_trace() call # schedule() instead movl %esp, %eax movl $1, %edx
@@ -666,7 +672,7 @@ ENTRY(device_not_available) pushl $-1 # mark this as an int CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL - movl %cr0, %eax + GET_CR0_INTO_EAX testl $0x4, %eax # EM (math emulation bit) jne device_not_available_emulate preempt_stop
@@ -796,7 +802,7 @@ nmi_16bit_stack: call do_nmi RESTORE_REGS lss 12+4(%esp), %esp # back to 16bit stack -1: iret +1: INTERRUPT_RETURN CFI_ENDPROC .section __ex_table,"a" .align 4
===================================================================
include/asm-i386/spinlock.h +5 -2
@@ -16,6 +16,9 @@* * (the type definitions are in asm/spinlock_types.h) */ + +#define CLI_STRING "cli" +#define STI_STRING "sti"#define __raw_spin_is_locked (x) \ (*(volatile signed char *)(&(x)->slock) <= 0)
@@ -43,12 +46,12 @@"2:\t" \"testl $0x200, %1\n\t" \"jz 4f\n\t" \ -"sti\n" \ +STI_STRING "\n" \"3:\t" \"rep;nop\n\t" \"cmpb $0, %0\n\t" \"jle 3b\n\t" \ -"cli\n\t" \ +CLI_STRING "\n\t" \"jmp 1b\n" \"4:\t" \"rep;nop\n\t" \
--
PATCH 5/8 Roll all the cpuid asm into one __cpuid call.
In reply to Jeremy FitzhardingeIt's a little neater, and also means only one place to patch for paravirtualization.
--- include/asm-i386/processor.h | 74 +++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 40 deletions(-)
===================================================================
include/asm-i386/processor.h +34 -40
@@ -143,31 +143,37 @@ static inline void detect_ht(struct cpui#define X86_EFLAGS_VIP 0x00100000/* Virtual Interrupt Pending */ #define X86_EFLAGS_ID 0x00200000/* CPUID detection flag */ -/* -* Generic CPUID function -* clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx -* resulting in stale register contents being returned. -*/ -static inline void cpuid (unsigned int op,unsigned int *eax,unsigned int *ebx,unsigned int *ecx,unsigned int *edx) -{ +static inline void __cpuid (unsigned int *eax,unsigned int *ebx, +unsigned int *ecx,unsigned int *edx) +{ +/* ecx is often an input as well as an output. */ __asm__("cpuid" :"=a" (*eax),"=b" (*ebx),"=c" (*ecx),"=d" (*edx) - :"0" (op),"c" (0 )); + :"0" (*eax),"2" (*ecx)); +} + +/* +* Generic CPUID function +* clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx +* resulting in stale register contents being returned. +*/ +static inline void cpuid (unsigned int op,unsigned int *eax,unsigned int *ebx,unsigned int *ecx,unsigned int *edx) +{ + *eax = op; + *ecx =0 ; +__cpuid (eax, ebx, ecx, edx); }/* Some CPUID calls want 'count' to be placed in ecx */ static inline void cpuid_count (int op,int count,int *eax,int *ebx,int *ecx, -int *edx) -{ - __asm__("cpuid" - :"=a" (*eax), -"=b" (*ebx), -"=c" (*ecx), -"=d" (*edx) - :"0" (op),"c" (count)); +int *edx) +{ + *eax = op; + *ecx = count; +__cpuid (eax, ebx, ecx, edx); }/*
@@ -175,42 +181,30 @@ static inline void cpuid_count(int op, i*/ static inline unsigned int cpuid_eax (unsigned int op) { -unsigned int eax; - - __asm__("cpuid" - :"=a" (eax) - :"0" (op) - :"bx" ,"cx" ,"dx" ); +unsigned int eax, ebx, ecx, edx; + +cpuid (op, &eax, &ebx, &ecx, &edx);return eax; }static inline unsigned int cpuid_ebx (unsigned int op) { -unsigned int eax, ebx; - - __asm__("cpuid" - :"=a" (eax),"=b" (ebx) - :"0" (op) - :"cx" ,"dx" ); +unsigned int eax, ebx, ecx, edx; + +cpuid (op, &eax, &ebx, &ecx, &edx);return ebx; }static inline unsigned int cpuid_ecx (unsigned int op) { -unsigned int eax, ecx; - - __asm__("cpuid" - :"=a" (eax),"=c" (ecx) - :"0" (op) - :"bx" ,"dx" ); +unsigned int eax, ebx, ecx, edx; + +cpuid (op, &eax, &ebx, &ecx, &edx);return ecx; }static inline unsigned int cpuid_edx (unsigned int op) { -unsigned int eax, edx; - - __asm__("cpuid" - :"=a" (eax),"=d" (edx) - :"0" (op) - :"bx" ,"cx" ); +unsigned int eax, ebx, ecx, edx; + +cpuid (op, &eax, &ebx, &ecx, &edx);return edx; }
--
PATCH 6/8 Make __FIXADDR_TOP variable to allow it to make space for a hypervisor.
In reply to Jeremy FitzhardingeMake __FIXADDR_TOP a variable, so that it can be set to not get in the way of address space a hypervisor may want to reserve.
Original patch by Gerd Hoffmann <[email protected]>
--- arch/i386/Kconfig | 1 + arch/i386/mm/init.c | 42 ++++++++++++++++++++++++++++++++++++++++++ arch/i386/mm/pgtable.c | 26 ++++++++++++++++++++++++++ include/asm-i386/fixmap.h | 7 ++++++- 4 files changed, 75 insertions(+), 1 deletion(-)
===================================================================
arch/i386/Kconfig +1 -0
@@ -792,6 +792,7 @@ config COMPAT_VDSO config COMPAT_VDSO bool "Compat VDSO support" default y + depends on !PARAVIRT help Map the VDSO to the predictable old-style address too. ---help---
===================================================================
arch/i386/mm/init.c +42 -0
48 lines not on this page · raw message
===================================================================
arch/i386/mm/pgtable.c +26 -0
@@ -12,6 +12,7 @@#include <linux/slab.h> #include <linux/pagemap.h> #include <linux/spinlock.h> +#include <linux/module.h> #include <asm/system.h> #include <asm/pgtable.h>
@@ -137,6 +138,12 @@ void set_pmd_pfn(unsigned long vaddr, un__flush_tlb_one (vaddr); } +static int fixmaps; +#ifndef CONFIG_COMPAT_VDSO +unsigned long __FIXADDR_TOP =0xfffff000 ; +EXPORT_SYMBOL (__FIXADDR_TOP); +#endif +void __set_fixmap (enum fixed_addresses idx,unsigned long phys,pgprot_t flags) {unsigned long address =__fix_to_virt (idx);
@@ -146,6 +153,25 @@ void __set_fixmap (enum fixed_addressesreturn ; }set_pte_pfn (address, phys >>PAGE_SHIFT , flags); + fixmaps++; +} + +/** +* reserve_top_address - reserves a hole in the top of kernel address space +* @reserve - size of hole to reserve +* +* Can be used to relocate the fixmap area and poke a hole in the top +* of kernel address space to make room for a hypervisor. +*/ +void reserve_top_address (unsigned long reserve) +{ +BUG_ON (fixmaps >0 ); +#ifdef CONFIG_COMPAT_VDSO +BUG_ON (reserve !=0 ); +#else + __FIXADDR_TOP = -reserve -PAGE_SIZE ; + __VMALLOC_RESERVE += reserve; +#endif }pte_t *pte_alloc_one_kernel (struct mm_struct *mm,unsigned long address)
===================================================================
include/asm-i386/fixmap.h +6 -1
@@ -19,7 +19,11 @@* Leave one empty page between vmalloc'ed areas and * the start of the fixmap. */ -#define __FIXADDR_TOP 0xfffff000 +#ifndef CONFIG_COMPAT_VDSO +extern unsigned long __FIXADDR_TOP; +#else +#define __FIXADDR_TOP 0xfffff000 +#endif #ifndef __ASSEMBLY__#include <linux/kernel.h>
@@ -93,6 +97,7 @@ enum fixed_addresses {extern void __set_fixmap (enum fixed_addresses idx,unsigned long phys,pgprot_t flags); +extern void reserve_top_address (unsigned long reserve);#define set_fixmap (idx, phys) \ __set_fixmap(idx, phys, PAGE_KERNEL)
--
PATCH 7/8 Add a bootparameter to reserve high linear address space.
In reply to Jeremy FitzhardingeAdd a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which might not happen until userspace is already running, and also provides a useful tool to benchmark the performance impact of reduced lowmem address space.
--- Documentation/kernel-parameters.txt | 5 +++++ arch/i386/kernel/setup.c | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+)
===================================================================
Documentation/kernel-parameters.txt +5 -0
@@ -1357,6 +1357,11 @@ running once the system is up. reserve= [KNL,BUGS] Force the kernel to ignore some iomem area + reservetop= [IA-32] + Format: nn[KMG] + Reserves a hole at the top of the kernel virtual + address space. + resume= [SWSUSP] Specify the partition device for software suspend
===================================================================
arch/i386/kernel/setup.c +19 -0
@@ -160,6 +160,12 @@ static char command_line[COMMAND_LINE_SIstatic char command_line[COMMAND_LINE_SIZE ];unsigned char __initdata boot_params[PARAM_SIZE ]; + +static int __init setup_reservetop (char *s) +{ +return 1 ; +} +__setup ("reservetop" , setup_reservetop);static struct resource data_resource = { .name ="Kernel data" ,
@@ -917,6 +923,19 @@ static void __init parse_cmdline_early (else if (!memcmp (from,"vmalloc=" ,8 )) __VMALLOC_RESERVE =memparse (from+8 , &from); +/* +* reservetop=size reserves a hole at the top of the kernel +* address space which a hypervisor can load into later. +* Needed for dynamically loaded hypervisors, so relocating +* the fixmap can be done before paging initialization. +* This hole must be a multiple of 4M. +*/ +else if (!memcmp (from,"reservetop=" ,11 )) { +unsigned long reserve =memparse (from+11 , &from); + reserve &= ~0x3fffff ; +reserve_top_address (reserve); + } + next_char: c = *(from++);if (!c)
--
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
arch/i386/kernel/setup.c static void __init parse_cmdline_early ( · line 937
Quoted 12 lines · On Wed, 02 Aug 2006 17:25:17 -0700 Jeremy Fitzhardinge <[email protected]>…
arch/i386/kernel/setup.c +12
-0+/* +* reservetop=size reserves a hole at the top of the kernel +* address space which a hypervisor can load into later. +* Needed for dynamically loaded hypervisors, so relocating +* the fixmap can be done before paging initialization. +* This hole must be a multiple of 4M. +*/ + else if (!memcmp(from, "reservetop=", 11)) { +unsigned long reserve =memparse (from+11 , &from); + reserve &= ~0x3fffff ; +reserve_top_address (reserve); + }
I assume that this argument will normally be passed in via the hypervisor rather than by human-entered information?
In which case, perhaps a panic would be a more appropriate response to a non-multiple-of-4M.
Either way, rounding the number down rather than up seems wrong...
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
Quoted 21 lines · Andrew Morton
arch/i386/kernel/setup.c static void __init parse_cmdline_early ( · line 937
Quoted 13 lines · On Wed, 02 Aug 2006 17:25:17 -0700 Jeremy Fitzhardinge <[email protected]>…
arch/i386/kernel/setup.c +12
-0+/* +* reservetop=size reserves a hole at the top of the kernel +* address space which a hypervisor can load into later. +* Needed for dynamically loaded hypervisors, so relocating +* the fixmap can be done before paging initialization. +* This hole must be a multiple of 4M. +*/ + else if (!memcmp(from, "reservetop=", 11)) { +unsigned long reserve =memparse (from+11 , &from); + reserve &= ~0x3fffff ; +reserve_top_address (reserve); + }I assume that this argument will normally be passed in via the hypervisor rather than by human-entered information?
Quoted 5 lines
In which case, perhaps a panic would be a more appropriate response to a non-multiple-of-4M.
Either way, rounding the number down rather than up seems wrong...
Agree on the rounding issue - but is a panic really correct? Perhaps we should not round at all.
The presumption is actually that this is human or script entered information. A runtime loaded hypervisor module has no way to tweak or toggle the boot parameters, as it hasn't yet been loaded. It could be that a human operator wants to make room for it. Giving the operator a panic is not the most friendly thing to do - logging the failure on module load is much nicer. And such a runtime loaded hypervisor must be fully virtualizing anyway, so even if the argument is wrong and doesn't give the hypervisor enough space to load, no damage is done - the operator just resets the parameter and reboots.
Zach
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
Quoted 26 lines · On Thu, 03 Aug 2006 00:33:10 -0700 Zachary Amsden <[email protected]> wrote:
Quoted 17 lines
arch/i386/kernel/setup.c static void __init parse_cmdline_early ( · line 937
Quoted 13 lines
arch/i386/kernel/setup.c +12
-0+/* +* reservetop=size reserves a hole at the top of the kernel +* address space which a hypervisor can load into later. +* Needed for dynamically loaded hypervisors, so relocating +* the fixmap can be done before paging initialization. +* This hole must be a multiple of 4M. +*/ + else if (!memcmp(from, "reservetop=", 11)) { +unsigned long reserve =memparse (from+11 , &from); + reserve &= ~0x3fffff ; +reserve_top_address (reserve); + }I assume that this argument will normally be passed in via the hypervisor rather than by human-entered information?
Quoted 5 lines
In which case, perhaps a panic would be a more appropriate response to a non-multiple-of-4M.
Either way, rounding the number down rather than up seems wrong...
Agree on the rounding issue - but is a panic really correct? Perhaps we should not round at all.
Quoted 9 lines
The presumption is actually that this is human or script entered information. A runtime loaded hypervisor module has no way to tweak or toggle the boot parameters, as it hasn't yet been loaded. It could be that a human operator wants to make room for it. Giving the operator a panic is not the most friendly thing to do - logging the failure on module load is much nicer. And such a runtime loaded hypervisor must be fully virtualizing anyway, so even if the argument is wrong and doesn't give the hypervisor enough space to load, no damage is done - the operator just resets the parameter and reboots.
The comment says "must". If that's true then printing a what-you-did-wrong message and halting is appropriate.
But whatever. The issue is flagged and I'm happy to leave it in Jeremy's lap.
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
Quoted 5 lines · Andrew Morton
The comment says "must". If that's true then printing a what-you-did-wrong message and halting is appropriate.
But whatever. The issue is flagged and I'm happy to leave it in Jeremy's lap.
Considering I wrote that patch, I think I should fix it -- here you go
Subject: Add a bootparameter to reserve high linear address space.
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which might not happen until userspace is already running, and also provides a useful tool to benchmark the performance impact of reduced lowmem address space.
--- Documentation/kernel-parameters.txt | 5 +++++ arch/i386/kernel/setup.c | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+)
Documentation/kernel-parameters.txt +5 -0
@@ -1357,6 +1357,11 @@ running once the system is up. reserve= [KNL,BUGS] Force the kernel to ignore some iomem area + reservetop= [IA-32] + Format: nn[KMG] + Reserves a hole at the top of the kernel virtual + address space. + resume= [SWSUSP] Specify the partition device for software suspend
arch/i386/kernel/setup.c +17 -0
@@ -160,6 +160,12 @@ static char command_line[COMMAND_LINE_SIstatic char command_line[COMMAND_LINE_SIZE ];unsigned char __initdata boot_params[PARAM_SIZE ]; + +static int __init setup_reservetop (char *s) +{ +return 1 ; +} +__setup ("reservetop" , setup_reservetop);static struct resource data_resource = { .name ="Kernel data" ,
@@ -917,6 +923,17 @@ static void __init parse_cmdline_early (else if (!memcmp (from,"vmalloc=" ,8 )) __VMALLOC_RESERVE =memparse (from+8 , &from); +/* +* reservetop=size reserves a hole at the top of the kernel +* address space which a hypervisor can load into later. +* Needed for dynamically loaded hypervisors, so relocating +* the fixmap can be done before paging initialization. +*/ +else if (!memcmp (from,"reservetop=" ,11 )) { +unsigned long reserve =memparse (from+11 , &from); +reserve_top_address (reserve); + } + next_char: c = *(from++);if (!c)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
Quoted 5 lines · On Thu, 03 Aug 2006 01:58:32 -0700 Zachary Amsden <[email protected]> wrote:
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which might not happen until userspace is already running, and also provides a useful tool to benchmark the performance impact of reduced lowmem address space.
Andi has gone and rotorooted the x86 boot parameter handling in there. This patch now looks like this:
From: Zachary Amsden <[email protected]>
Add a boot parameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which might not happen until userspace is already running, and also provides a useful tool to benchmark the performance impact of reduced lowmem address space.
---
Documentation/kernel-parameters.txt | 5 +++++ arch/i386/kernel/setup.c | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+)
arch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~x86-add-a-bootparameter-to-reserve-high-linear-address-space +24 -0
@@ -149,6 +149,12 @@ static char command_line[COMMAND_LINE_SIunsigned char __initdata boot_params[PARAM_SIZE ]; +static int __init setup_reservetop (char *s) +{ +return 1 ; +} +__setup ("reservetop" , setup_reservetop); +static struct resource data_resource = { .name ="Kernel data" , .start =0 ,
@@ -814,6 +820,24 @@ static int __init parse_vmalloc(char *arearly_param ("vmalloc" , parse_vmalloc);/* +* reservetop=size reserves a hole at the top of the kernel address space which +* a hypervisor can load into later. Needed for dynamically loaded hypervisors, +* so relocating the fixmap can be done before paging initialization. +*/ +static int __init parse_reservetop (char *arg) +{ +unsigned long address; + +if (!arg) +return -EINVAL ; + + address =memparse (arg, &arg); +reserve_top_address (address); +return 0 ; +} +early_param ("reservetop" , parse_reservetop); + +/* * Callback for efi_memory_walk. */ static int __init
Documentation/kernel-parameters.txt renamed from Documentation/kernel-parameters.txt~x86-add-a-bootparameter-to-reserve-high-linear-address-space +5 -0
@@ -1357,6 +1357,11 @@ running once the system is up. reserve= [KNL,BUGS] Force the kernel to ignore some iomem area + reservetop= [IA-32] + Format: nn[KMG] + Reserves a hole at the top of the kernel virtual + address space. + resume= [SWSUSP] Specify the partition device for software suspend
_
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
Quoted 11 lines · Andrew Morton
Quoted 6 lines · On Thu, 03 Aug 2006 01:58:32 -0700 Zachary Amsden <[email protected]> wrote:
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which might not happen until userspace is already running, and also provides a useful tool to benchmark the performance impact of reduced lowmem address space.
Quoted 3 lines
Andi has gone and rotorooted the x86 boot parameter handling in there. This patch now looks like this:
The rototilled patch looks great. Acked.
Zach
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
In reply to Andrew MortonQuoted 10 lines · Andrew Morton
Quoted 5 lines · On Thu, 03 Aug 2006 01:58:32 -0700 Zachary Amsden <[email protected]> wrote:
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which might not happen until userspace is already running, and also provides a useful tool to benchmark the performance impact of reduced lowmem address space.
Andi has gone and rotorooted the x86 boot parameter handling in there.
That was me, via Andi, but yep:
Quoted 6 lines
diff -puN
arch/i386/kernel/setup.c~x86-add-a-bootparameter-to-reserve-high-linear-address-spacearch/i386/kernel/setup.carch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~x86-add-a-bootparameter-to-reserve-high-linear-address-space +0
-0@@ -149,6 +149,12 @@ static char command_line[COMMAND_LINE_SIunsigned char __initdata boot_params[PARAM_SIZE ];
arch/i386/kernel/setup.c static char command_line[COMMAND_LINE_SI · line 160
Quoted 10 lines
arch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~x86-add-a-bootparameter-to-reserve-high-linear-address-space +6
-0+static int __init setup_reservetop (char *s) +{ +return 1 ; +} +__setup ("reservetop" , setup_reservetop); +static struct resource data_resource = { .name ="Kernel data" , .start =0 ,
Please remove this hunk: it's now junk.
Cheers,
Rusty.
Signature · 1 line
Help! Save Australia from the worst of the DMCA: http://linux.org.au/law
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
In reply to Jeremy FitzhardingeHi!
Quoted 2 lines
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which
Dynamically loaded hypervisor? Do we really want to support that?
Pavel
Signature · 1 line
Thanks for all the (sleeping) penguins.
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
In reply to Jeremy FitzhardingeHi!
Quoted 2 lines
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which
Dynamically loaded hypervisor? Do we really want to support that?
Pavel
Signature · 1 line
Thanks for all the (sleeping) penguins.
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
Quoted 6 lines · Pavel Machek
Hi!
Quoted 2 lines
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which
Dynamically loaded hypervisor? Do we really want to support that?
I hope so. IMHO letting Linux boot first and then the Hypervisor is a better design than the other way round which requires a lot of duplicated code.
-Andi
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
In reply to Pavel MachekQuoted 2 lines · Pavel Machek
Dynamically loaded hypervisor? Do we really want to support that?
(Missed this because your datestamp was 1969...)
The idea was that you could boot a guest under VMWare fully virtualized then switch it to a VMI guest by loading a module. I don't think it ever worked out - the transition was too trick to get right (especially applying all the pvops patching to a live system).
J
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
In reply to Jeremy FitzhardingeHi!
Quoted 2 lines
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which
Dynamically loaded hypervisor? Do we really want to support that?
Pavel
Signature · 1 line
Thanks for all the (sleeping) penguins.
Re: [patch 7/8] Add a bootparameter to reserve high linear address space.
In reply to Jeremy FitzhardingeHi!
Quoted 2 lines
Add a bootparameter to reserve high linear address space for hypervisors. This is necessary to allow dynamically loaded hypervisor modules, which
Dynamically loaded hypervisor? Do we really want to support that?
Pavel
Signature · 1 line
Thanks for all the (sleeping) penguins.
PATCH 8/8 Put .note.* sections into a PT_NOTE segment in vmlinux.
In reply to Jeremy FitzhardingeThis patch will pack any .note.* section into a PT_NOTE segment in the output file.
To do this, we tell ld that we need a PT_NOTE segment. This requires us to start explicitly mapping sections to segments, so we also need to explicitly create PT_LOAD segments for text and data, and map the sections to them appropriately. Fortunately, each section will default to its previous section's segment, so it doesn't take many changes to vmlinux.lds.S.
This only changes i386 for now, but I presume the corresponding changes for other architectures will be as simple.
This change also adds <linux/elfnote.h>, which defines C and Assembler macros for actually creating ELF notes.
--- arch/i386/kernel/vmlinux.lds.S | 12 ++++- include/asm-generic/vmlinux.lds.h | 3 + include/linux/elfnote.h | 88 +++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 2 deletions(-)
===================================================================
arch/i386/kernel/vmlinux.lds.S +10 -2
@@ -13,6 +13,12 @@ OUTPUT_ARCH(i386) OUTPUT_ARCH(i386) ENTRY(phys_startup_32) jiffies = jiffies_64; + +PHDRS { + text PT_LOAD FLAGS(5); /* R_E */ + data PT_LOAD FLAGS(7); /* RWE */ + note PT_NOTE FLAGS(4); /* R__ */ +} SECTIONS { . = __KERNEL_START;
@@ -26,7 +32,7 @@ SECTIONS KPROBES_TEXT *(.fixup) *(.gnu.warning) - } = 0x9090 + } :text = 0x9090 _etext = .; /* End of text section */
@@ -48,7 +54,7 @@ SECTIONS .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ *(.data) CONSTRUCTORS - } + } :data . = ALIGN(4096); __nosave_begin = .;
@@ -184,4 +190,6 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + + NOTES }
===================================================================
include/asm-generic/vmlinux.lds.h +3 -0
@@ -194,3 +194,6 @@ .stab.index 0 : { *(.stab.index) } \ .stab.indexstr 0 : { *(.stab.indexstr) } \ .comment 0 : { *(.comment) } + +#define NOTES \ + .notes : { *(.note.*) } :note
===================================================================
include/linux/elfnote.h new file +88 -0
88 lines not on this page · raw message
--