summaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/setup.h
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2009-03-12 16:09:49 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-03-14 17:23:47 -0700
commit796216a57fe45c04adc35bda1f0782efec78a713 (patch)
tree7f94407dfa2ccc2ab7a8e2b3e09cee04290f0ca1 /arch/x86/include/asm/setup.h
parent7543c1de84ed93c6769c9f20dced08a522af8912 (diff)
downloadblackbird-op-linux-796216a57fe45c04adc35bda1f0782efec78a713.tar.gz
blackbird-op-linux-796216a57fe45c04adc35bda1f0782efec78a713.zip
x86: allow extend_brk users to reserve brk space
Impact: new interface; remove hard-coded limit Add RESERVE_BRK(name, size) macro to reserve space in the brk area. This should be a conservative (ie, larger) estimate of how much space might possibly be required from the brk area. Any unused space will be freed, so there's no real downside on making the reservation too large (within limits). The name should be unique within a given file, and somewhat descriptive. The C definition of RESERVE_BRK() ends up being more complex than one would expect to work around a cluster of gcc infelicities: The first attempt was to simply try putting __section(.brk_reservation) on a variable. This doesn't work because it ends up making it a @progbits section, which gets actual space allocated in the vmlinux executable. The second attempt was to emit the space into a section using asm, but gcc doesn't allow arguments to be passed to file-level asm() statements, making it hard to pass in the size. The final attempt is to wrap the asm() in a function to allow it to have arguments, and put the function itself into the .discard section, which vmlinux*.lds drops entirely from the emitted vmlinux. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/include/asm/setup.h')
-rw-r--r--arch/x86/include/asm/setup.h30
1 files changed, 30 insertions, 0 deletions
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 366d36639940..61b126b97885 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -104,6 +104,29 @@ extern struct boot_params boot_params;
extern unsigned long _brk_end;
void *extend_brk(size_t size, size_t align);
+/*
+ * Reserve space in the brk section. The name must be unique within
+ * the file, and somewhat descriptive. The size is in bytes. Must be
+ * used at file scope.
+ *
+ * (This uses a temp function to wrap the asm so we can pass it the
+ * size parameter; otherwise we wouldn't be able to. We can't use a
+ * "section" attribute on a normal variable because it always ends up
+ * being @progbits, which ends up allocating space in the vmlinux
+ * executable.)
+ */
+#define RESERVE_BRK(name,sz) \
+ static void __section(.discard) __used \
+ __brk_reservation_fn_##name##__(void) { \
+ asm volatile ( \
+ ".pushsection .brk_reservation,\"aw\",@nobits;" \
+ "__brk_reservation_" #name "__:" \
+ " 1:.skip %c0;" \
+ " .size __brk_reservation_" #name "__, . - 1b;" \
+ " .popsection" \
+ : : "i" (sz)); \
+ }
+
#ifdef __i386__
void __init i386_start_kernel(void);
@@ -115,6 +138,13 @@ void __init x86_64_start_reservations(char *real_mode_data);
#endif /* __i386__ */
#endif /* _SETUP */
+#else
+#define RESERVE_BRK(name,sz) \
+ .pushsection .brk_reservation,"aw",@nobits; \
+__brk_reservation_##name##__: \
+1: .skip sz; \
+ .size __brk_reservation_##name##__,.-1b; \
+ .popsection
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
OpenPOWER on IntegriCloud