Skip to contentSkip to conversation

make page-aligned data and bss less fragile

PATCH In review Jeremy Fitzhardinge 3 participants 3 messages May 28, 2008 – May 29, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 make page-aligned data and bss less fragile

Making a variable page-aligned by using __attribute__((section(".data.page_aligned"))) is fragile because if sizeof(variable) is not also a multiple of page size, it leaves variables in the remainder of the section unaligned.

This patch introduces two new qualifiers, __page_aligned_data and __page_aligned_bss to set the section *and* the alignment of variables. This makes page-aligned variables more robust because the linker will make sure they're aligned properly. Unfortunately it requires *all* page-aligned data to use these macros...

It also updates arch/x86's use of page-aligned variables, since its the heaviest user of them in the kernel. The change to arch/x86/xen/mmu.c fixes an actual bug, but the rest are cleanups and to set a precident.

[ I don't know if this would be easier to manage by splitting the
x86 part out from the common part. Two following patches apply to powerpc and sh; they're purely decorative. ]

---

arch/x86/kernel/irq_32.c  |    7 ++-----
arch/x86/kernel/setup64.c |    5 +++--
arch/x86/mm/ioremap.c     |    3 +--
arch/x86/xen/mmu.c        |   12 +++++-------
include/linux/linkage.h   |    8 ++++++++
5 files changed, 19 insertions(+), 16 deletions(-)

===================================================================

arch/x86/kernel/irq_32.c +0 -0
@@ -83,11 +83,8 @@

static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;

-static char softirq_stack[NR_CPUS * THREAD_SIZE]
- __attribute__((__section__(".bss.page_aligned")));
-
-static char hardirq_stack[NR_CPUS * THREAD_SIZE]
- __attribute__((__section__(".bss.page_aligned")));
+static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; +static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;

static void call_on_stack(void *func, void *stack) {
===================================================================

arch/x86/kernel/setup64.c +0 -0
@@ -8,6 +8,7 @@

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
+#include <linux/linkage.h>
#include <linux/bootmem.h>
#include <linux/bitops.h>
#include <linux/module.h>
@@ -40,7 +41,7 @@

struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };

-char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); +char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;

unsigned long __supported_pte_mask __read_mostly = ~0UL; EXPORT_SYMBOL_GPL(__supported_pte_mask);
@@ -123,7 +124,7 @@
}

char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ] -__attribute__((section(".bss.page_aligned")));
+__page_aligned_bss;

extern asmlinkage void ignore_sysret(void);

===================================================================

arch/x86/mm/ioremap.c +0 -0
@@ -403,8 +403,7 @@

early_param("early_ioremap_debug", early_ioremap_debug_setup);

static __initdata int after_paging_init;
-static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)]
- __section(.bss.page_aligned);
+static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;

static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) {
===================================================================

arch/x86/xen/mmu.c +0 -0
@@ -46,6 +46,7 @@

#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
#include <asm/paravirt.h>
+#include <asm/linkage.h>

#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
@@ -60,21 +61,18 @@
#define TOP_ENTRIES (MAX_DOMAIN_PAGES / P2M_ENTRIES_PER_PAGE)

/* Placeholder for holes in the address space */
-static unsigned long p2m_missing[P2M_ENTRIES_PER_PAGE]
- __attribute__((section(".data.page_aligned"))) =
+static unsigned long p2m_missing[P2M_ENTRIES_PER_PAGE] __page_aligned_data =

		{ [ 0 ... P2M_ENTRIES_PER_PAGE-1 ] = ~0UL };

/* Array of pointers to pages containing p2m entries */
-static unsigned long *p2m_top[TOP_ENTRIES]
- __attribute__((section(".data.page_aligned"))) =
+static unsigned long *p2m_top[TOP_ENTRIES] __page_aligned_data =

		{ [ 0 ... TOP_ENTRIES - 1] = &p2m_missing[0] };

/* Arrays of p2m arrays expressed in mfns used for save/restore */ -static unsigned long p2m_top_mfn[TOP_ENTRIES]
- __attribute__((section(".bss.page_aligned")));
+static unsigned long p2m_top_mfn[TOP_ENTRIES] __page_aligned_bss;

static unsigned long p2m_top_mfn_list[TOP_ENTRIES / P2M_ENTRIES_PER_PAGE]
- __attribute__((section(".bss.page_aligned")));
+ __page_aligned_bss;

static inline unsigned p2m_top_index(unsigned long pfn) {
===================================================================

include/linux/linkage.h +0 -0
@@ -1,6 +1,7 @@

#ifndef _LINUX_LINKAGE_H
#define _LINUX_LINKAGE_H

+#include <linux/compiler.h>
#include <asm/linkage.h>

#define notrace __attribute__((no_instrument_function)) @@ -18,6 +19,13 @@
#ifndef asmregparm

# define asmregparm
#endif
+
+/*
+ * Mark a variable page aligned, and put it in an appropriate page
+ * aligned section.
+ */
+#define __page_aligned_data	__section(.data.page_aligned) __aligned(PAGE_SIZE)
+#define __page_aligned_bss	__section(.bss.page_aligned) __aligned(PAGE_SIZE)

/*
* This is used by architectures to keep arguments on the stack

#1 lore raw
Quoted 11 lines · On Wed, 28 May 2008 17:04:34 +0100 Jeremy Fitzhardinge <[email protected]> wrote:

Making a variable page-aligned by using __attribute__((section(".data.page_aligned"))) is fragile because if sizeof(variable) is not also a multiple of page size, it leaves variables in the remainder of the section unaligned.

This patch introduces two new qualifiers, __page_aligned_data and __page_aligned_bss to set the section *and* the alignment of variables. This makes page-aligned variables more robust because the linker will make sure they're aligned properly. Unfortunately it requires *all* page-aligned data to use these macros...

Quoted 8 lines

It also updates arch/x86's use of page-aligned variables, since its the heaviest user of them in the kernel. The change to arch/x86/xen/mmu.c fixes an actual bug, but the rest are cleanups and to set a precident.

[ I don't know if this would be easier to manage by splitting the
x86 part out from the common part. Two following patches apply to powerpc and sh; they're purely decorative. ]

If the arch people like these patches then we could merge this bit:

Quoted 15 lines
include/linux/linkage.h +1 -0
@@ -1,6 +1,7 @@
 #ifndef _LINUX_LINKAGE_H
 #define _LINUX_LINKAGE_H
 
+#include <linux/compiler.h>
 #include <asm/linkage.h>
 
 #define notrace __attribute__((no_instrument_function))
@@ -18,6 +19,13 @@
 #ifndef asmregparm
 # define asmregparm
 #endif

include/linux/linkage.h line 31

Quoted 10 lines
include/linux/linkage.h +7 -0
+
+/*
+ * Mark a variable page aligned, and put it in an appropriate page
+ * aligned section.
+ */
+#define __page_aligned_data	__section(.data.page_aligned) __aligned(PAGE_SIZE)
+#define __page_aligned_bss	__section(.bss.page_aligned) __aligned(PAGE_SIZE)
 
 /*
  * This is used by architectures to keep arguments on the stack

Into mainline now, so we can trickle the other three patches into the architecture trees.

Acked-by on v1 1/3
#2 lore raw
In reply to Jeremy Fitzhardinge
Quoted 16 lines · Jeremy Fitzhardinge

Making a variable page-aligned by using __attribute__((section(".data.page_aligned"))) is fragile because if sizeof(variable) is not also a multiple of page size, it leaves variables in the remainder of the section unaligned.

This patch introduces two new qualifiers, __page_aligned_data and __page_aligned_bss to set the section *and* the alignment of variables. This makes page-aligned variables more robust because the linker will make sure they're aligned properly. Unfortunately it requires *all* page-aligned data to use these macros...

It also updates arch/x86's use of page-aligned variables, since its the heaviest user of them in the kernel. The change to arch/x86/xen/mmu.c fixes an actual bug, but the rest are cleanups and to set a precident.

Quoted 7 lines

[ I don't know if this would be easier to manage by splitting the
x86 part out from the common part. Two following patches apply to powerpc and sh; they're purely decorative. ]