Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d12418fd authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'linus' into cpus4096

parents c2d1cec1 238c6d54
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -31,7 +31,6 @@ Features which OCFS2 does not support yet:
	- quotas
	- quotas
	- Directory change notification (F_NOTIFY)
	- Directory change notification (F_NOTIFY)
	- Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
	- Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
	- POSIX ACLs


Mount options
Mount options
=============
=============
@@ -79,3 +78,5 @@ inode64 Indicates that Ocfs2 is allowed to create inodes at
			bits of significance.
			bits of significance.
user_xattr	(*)	Enables Extended User Attributes.
user_xattr	(*)	Enables Extended User Attributes.
nouser_xattr		Disables Extended User Attributes.
nouser_xattr		Disables Extended User Attributes.
acl			Enables POSIX Access Control Lists support.
noacl		(*)	Disables POSIX Access Control Lists support.
+5 −10
Original line number Original line Diff line number Diff line
@@ -4015,10 +4015,12 @@ L: alsa-devel@alsa-project.org (subscribers-only)
W:	http://alsa-project.org/main/index.php/ASoC
W:	http://alsa-project.org/main/index.php/ASoC
S:	Supported
S:	Supported


SPARC (sparc32)
SPARC + UltraSPARC (sparc/sparc64)
P:	William L. Irwin
P:	David S. Miller
M:	wli@holomorphy.com
M:	davem@davemloft.net
L:	sparclinux@vger.kernel.org
L:	sparclinux@vger.kernel.org
T:	git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git
T:	git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
S:	Maintained
S:	Maintained


SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
@@ -4302,13 +4304,6 @@ M: dushistov@mail.ru
L:	linux-kernel@vger.kernel.org
L:	linux-kernel@vger.kernel.org
S:	Maintained
S:	Maintained


UltraSPARC (sparc64)
P:	David S. Miller
M:	davem@davemloft.net
L:	sparclinux@vger.kernel.org
T:	git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git
S:	Maintained

ULTRA-WIDEBAND (UWB) SUBSYSTEM:
ULTRA-WIDEBAND (UWB) SUBSYSTEM:
P:	David Vrabel
P:	David Vrabel
M:	david.vrabel@csr.com
M:	david.vrabel@csr.com
+2 −2
Original line number Original line Diff line number Diff line
@@ -2321,7 +2321,7 @@ static struct clk i2c2_fck = {
};
};


static struct clk i2chs2_fck = {
static struct clk i2chs2_fck = {
	.name		= "i2chs_fck",
	.name		= "i2c_fck",
	.id		= 2,
	.id		= 2,
	.parent		= &func_96m_ck,
	.parent		= &func_96m_ck,
	.flags		= CLOCK_IN_OMAP243X,
	.flags		= CLOCK_IN_OMAP243X,
@@ -2354,7 +2354,7 @@ static struct clk i2c1_fck = {
};
};


static struct clk i2chs1_fck = {
static struct clk i2chs1_fck = {
	.name		= "i2chs_fck",
	.name		= "i2c_fck",
	.id		= 1,
	.id		= 1,
	.parent		= &func_96m_ck,
	.parent		= &func_96m_ck,
	.flags		= CLOCK_IN_OMAP243X,
	.flags		= CLOCK_IN_OMAP243X,
+4 −2
Original line number Original line Diff line number Diff line
@@ -23,8 +23,10 @@ struct mod_arch_specific
{
{
	unsigned long got_offset, got_count, got_max;
	unsigned long got_offset, got_count, got_max;
	unsigned long fdesc_offset, fdesc_count, fdesc_max;
	unsigned long fdesc_offset, fdesc_count, fdesc_max;
	unsigned long stub_offset, stub_count, stub_max;
	struct {
	unsigned long init_stub_offset, init_stub_count, init_stub_max;
		unsigned long stub_offset;
		unsigned int stub_entries;
		} *section;
	int unwind_section;
	int unwind_section;
	struct unwind_table *unwind;
	struct unwind_table *unwind;
};
};
+135 −81
Original line number Original line Diff line number Diff line
@@ -6,6 +6,7 @@
 *
 *
 *    Linux/PA-RISC Project (http://www.parisc-linux.org/)
 *    Linux/PA-RISC Project (http://www.parisc-linux.org/)
 *    Copyright (C) 2003 Randolph Chung <tausq at debian . org>
 *    Copyright (C) 2003 Randolph Chung <tausq at debian . org>
 *    Copyright (C) 2008 Helge Deller <deller@gmx.de>
 *
 *
 *
 *
 *    This program is free software; you can redistribute it and/or modify
 *    This program is free software; you can redistribute it and/or modify
@@ -24,6 +25,19 @@
 *
 *
 *
 *
 *    Notes:
 *    Notes:
 *    - PLT stub handling
 *      On 32bit (and sometimes 64bit) and with big kernel modules like xfs or
 *      ipv6 the relocation types R_PARISC_PCREL17F and R_PARISC_PCREL22F may
 *      fail to reach their PLT stub if we only create one big stub array for
 *      all sections at the beginning of the core or init section.
 *      Instead we now insert individual PLT stub entries directly in front of
 *      of the code sections where the stubs are actually called.
 *      This reduces the distance between the PCREL location and the stub entry
 *      so that the relocations can be fulfilled.
 *      While calculating the final layout of the kernel module in memory, the
 *      kernel module loader calls arch_mod_section_prepend() to request the
 *      to be reserved amount of memory in front of each individual section.
 *
 *    - SEGREL32 handling
 *    - SEGREL32 handling
 *      We are not doing SEGREL32 handling correctly. According to the ABI, we
 *      We are not doing SEGREL32 handling correctly. According to the ABI, we
 *      should do a value offset, like this:
 *      should do a value offset, like this:
@@ -58,9 +72,13 @@
#define DEBUGP(fmt...)
#define DEBUGP(fmt...)
#endif
#endif


#define RELOC_REACHABLE(val, bits) \
	(( ( !((val) & (1<<((bits)-1))) && ((val)>>(bits)) != 0 )  ||	\
	     ( ((val) & (1<<((bits)-1))) && ((val)>>(bits)) != (((__typeof__(val))(~0))>>((bits)+2)))) ? \
	0 : 1)

#define CHECK_RELOC(val, bits) \
#define CHECK_RELOC(val, bits) \
	if ( ( !((val) & (1<<((bits)-1))) && ((val)>>(bits)) != 0 )  ||	\
	if (!RELOC_REACHABLE(val, bits)) { \
	     ( ((val) & (1<<((bits)-1))) && ((val)>>(bits)) != (((__typeof__(val))(~0))>>((bits)+2)))) { \
		printk(KERN_ERR "module %s relocation of symbol %s is out of range (0x%lx in %d bits)\n", \
		printk(KERN_ERR "module %s relocation of symbol %s is out of range (0x%lx in %d bits)\n", \
		me->name, strtab + sym->st_name, (unsigned long)val, bits); \
		me->name, strtab + sym->st_name, (unsigned long)val, bits); \
		return -ENOEXEC;			\
		return -ENOEXEC;			\
@@ -92,13 +110,6 @@ static inline int in_local(struct module *me, void *loc)
	return in_init(me, loc) || in_core(me, loc);
	return in_init(me, loc) || in_core(me, loc);
}
}


static inline int in_local_section(struct module *me, void *loc, void *dot)
{
	return (in_init(me, loc) && in_init(me, dot)) ||
		(in_core(me, loc) && in_core(me, dot));
}


#ifndef CONFIG_64BIT
#ifndef CONFIG_64BIT
struct got_entry {
struct got_entry {
	Elf32_Addr addr;
	Elf32_Addr addr;
@@ -258,23 +269,42 @@ static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
/* Free memory returned from module_alloc */
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
void module_free(struct module *mod, void *module_region)
{
{
	kfree(mod->arch.section);
	mod->arch.section = NULL;

	vfree(module_region);
	vfree(module_region);
	/* FIXME: If module_region == mod->init_region, trim exception
	/* FIXME: If module_region == mod->init_region, trim exception
           table entries. */
           table entries. */
}
}


/* Additional bytes needed in front of individual sections */
unsigned int arch_mod_section_prepend(struct module *mod,
				      unsigned int section)
{
	/* size needed for all stubs of this section (including
	 * one additional for correct alignment of the stubs) */
	return (mod->arch.section[section].stub_entries + 1)
		* sizeof(struct stub_entry);
}

#define CONST 
#define CONST 
int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
			      CONST Elf_Shdr *sechdrs,
			      CONST Elf_Shdr *sechdrs,
			      CONST char *secstrings,
			      CONST char *secstrings,
			      struct module *me)
			      struct module *me)
{
{
	unsigned long gots = 0, fdescs = 0, stubs = 0, init_stubs = 0;
	unsigned long gots = 0, fdescs = 0, len;
	unsigned int i;
	unsigned int i;


	len = hdr->e_shnum * sizeof(me->arch.section[0]);
	me->arch.section = kzalloc(len, GFP_KERNEL);
	if (!me->arch.section)
		return -ENOMEM;

	for (i = 1; i < hdr->e_shnum; i++) {
	for (i = 1; i < hdr->e_shnum; i++) {
		const Elf_Rela *rels = (void *)hdr + sechdrs[i].sh_offset;
		const Elf_Rela *rels = (void *)sechdrs[i].sh_addr;
		unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels);
		unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels);
		unsigned int count, s;


		if (strncmp(secstrings + sechdrs[i].sh_name,
		if (strncmp(secstrings + sechdrs[i].sh_name,
			    ".PARISC.unwind", 14) == 0)
			    ".PARISC.unwind", 14) == 0)
@@ -290,11 +320,23 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
		 */
		 */
		gots += count_gots(rels, nrels);
		gots += count_gots(rels, nrels);
		fdescs += count_fdescs(rels, nrels);
		fdescs += count_fdescs(rels, nrels);
		if(strncmp(secstrings + sechdrs[i].sh_name,

			   ".rela.init", 10) == 0)
		/* XXX: By sorting the relocs and finding duplicate entries
			init_stubs += count_stubs(rels, nrels);
		 *  we could reduce the number of necessary stubs and save
		else
		 *  some memory. */
			stubs += count_stubs(rels, nrels);
		count = count_stubs(rels, nrels);
		if (!count)
			continue;

		/* so we need relocation stubs. reserve necessary memory. */
		/* sh_info gives the section for which we need to add stubs. */
		s = sechdrs[i].sh_info;

		/* each code section should only have one relocation section */
		WARN_ON(me->arch.section[s].stub_entries);

		/* store number of stubs we need for this section */
		me->arch.section[s].stub_entries += count;
	}
	}


	/* align things a bit */
	/* align things a bit */
@@ -306,18 +348,8 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
	me->arch.fdesc_offset = me->core_size;
	me->arch.fdesc_offset = me->core_size;
	me->core_size += fdescs * sizeof(Elf_Fdesc);
	me->core_size += fdescs * sizeof(Elf_Fdesc);


	me->core_size = ALIGN(me->core_size, 16);
	me->arch.stub_offset = me->core_size;
	me->core_size += stubs * sizeof(struct stub_entry);

	me->init_size = ALIGN(me->init_size, 16);
	me->arch.init_stub_offset = me->init_size;
	me->init_size += init_stubs * sizeof(struct stub_entry);

	me->arch.got_max = gots;
	me->arch.got_max = gots;
	me->arch.fdesc_max = fdescs;
	me->arch.fdesc_max = fdescs;
	me->arch.stub_max = stubs;
	me->arch.init_stub_max = init_stubs;


	return 0;
	return 0;
}
}
@@ -380,23 +412,27 @@ enum elf_stub_type {
};
};


static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
	enum elf_stub_type stub_type, int init_section)
	enum elf_stub_type stub_type, Elf_Addr loc0, unsigned int targetsec)
{
{
	unsigned long i;
	struct stub_entry *stub;
	struct stub_entry *stub;


	if(init_section) {
	/* initialize stub_offset to point in front of the section */
		i = me->arch.init_stub_count++;
	if (!me->arch.section[targetsec].stub_offset) {
		BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
		loc0 -= (me->arch.section[targetsec].stub_entries + 1) *
		stub = me->module_init + me->arch.init_stub_offset + 
				sizeof(struct stub_entry);
			i * sizeof(struct stub_entry);
		/* get correct alignment for the stubs */
	} else {
		loc0 = ALIGN(loc0, sizeof(struct stub_entry));
		i = me->arch.stub_count++;
		me->arch.section[targetsec].stub_offset = loc0;
		BUG_ON(me->arch.stub_count > me->arch.stub_max);
		stub = me->module_core + me->arch.stub_offset + 
			i * sizeof(struct stub_entry);
	}
	}


	/* get address of stub entry */
	stub = (void *) me->arch.section[targetsec].stub_offset;
	me->arch.section[targetsec].stub_offset += sizeof(struct stub_entry);

	/* do not write outside available stub area */
	BUG_ON(0 == me->arch.section[targetsec].stub_entries--);


#ifndef CONFIG_64BIT
#ifndef CONFIG_64BIT
/* for 32-bit the stub looks like this:
/* for 32-bit the stub looks like this:
 * 	ldil L'XXX,%r1
 * 	ldil L'XXX,%r1
@@ -489,15 +525,19 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
	Elf32_Addr val;
	Elf32_Addr val;
	Elf32_Sword addend;
	Elf32_Sword addend;
	Elf32_Addr dot;
	Elf32_Addr dot;
	Elf_Addr loc0;
	unsigned int targetsec = sechdrs[relsec].sh_info;
	//unsigned long dp = (unsigned long)$global$;
	//unsigned long dp = (unsigned long)$global$;
	register unsigned long dp asm ("r27");
	register unsigned long dp asm ("r27");


	DEBUGP("Applying relocate section %u to %u\n", relsec,
	DEBUGP("Applying relocate section %u to %u\n", relsec,
	       sechdrs[relsec].sh_info);
	       targetsec);
	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
		/* This is where to make the change */
		/* This is where to make the change */
		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
		loc = (void *)sechdrs[targetsec].sh_addr
		      + rel[i].r_offset;
		      + rel[i].r_offset;
		/* This is the start of the target section */
		loc0 = sechdrs[targetsec].sh_addr;
		/* This is the symbol it is referring to */
		/* This is the symbol it is referring to */
		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
			+ ELF32_R_SYM(rel[i].r_info);
			+ ELF32_R_SYM(rel[i].r_info);
@@ -569,19 +609,32 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
			break;
			break;
		case R_PARISC_PCREL17F:
		case R_PARISC_PCREL17F:
			/* 17-bit PC relative address */
			/* 17-bit PC relative address */
			val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc));
			/* calculate direct call offset */
			val += addend;
			val = (val - dot - 8)/4;
			val = (val - dot - 8)/4;
			CHECK_RELOC(val, 17)
			if (!RELOC_REACHABLE(val, 17)) {
				/* direct distance too far, create
				 * stub entry instead */
				val = get_stub(me, sym->st_value, addend,
					ELF_STUB_DIRECT, loc0, targetsec);
				val = (val - dot - 8)/4;
				CHECK_RELOC(val, 17);
			}
			*loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
			*loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
			break;
			break;
		case R_PARISC_PCREL22F:
		case R_PARISC_PCREL22F:
			/* 22-bit PC relative address; only defined for pa20 */
			/* 22-bit PC relative address; only defined for pa20 */
			val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc));
			/* calculate direct call offset */
			DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", 
			val += addend;
			       strtab + sym->st_name, (unsigned long)loc, addend, 
			val = (val - dot - 8)/4;
			       val)
			if (!RELOC_REACHABLE(val, 22)) {
				/* direct distance too far, create
				 * stub entry instead */
				val = get_stub(me, sym->st_value, addend,
					ELF_STUB_DIRECT, loc0, targetsec);
				val = (val - dot - 8)/4;
				val = (val - dot - 8)/4;
				CHECK_RELOC(val, 22);
				CHECK_RELOC(val, 22);
			}
			*loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
			*loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
			break;
			break;


@@ -610,13 +663,17 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
	Elf64_Addr val;
	Elf64_Addr val;
	Elf64_Sxword addend;
	Elf64_Sxword addend;
	Elf64_Addr dot;
	Elf64_Addr dot;
	Elf_Addr loc0;
	unsigned int targetsec = sechdrs[relsec].sh_info;


	DEBUGP("Applying relocate section %u to %u\n", relsec,
	DEBUGP("Applying relocate section %u to %u\n", relsec,
	       sechdrs[relsec].sh_info);
	       targetsec);
	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
		/* This is where to make the change */
		/* This is where to make the change */
		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
		loc = (void *)sechdrs[targetsec].sh_addr
		      + rel[i].r_offset;
		      + rel[i].r_offset;
		/* This is the start of the target section */
		loc0 = sechdrs[targetsec].sh_addr;
		/* This is the symbol it is referring to */
		/* This is the symbol it is referring to */
		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
			+ ELF64_R_SYM(rel[i].r_info);
			+ ELF64_R_SYM(rel[i].r_info);
@@ -672,42 +729,40 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
			DEBUGP("PCREL22F Symbol %s loc %p val %lx\n",
			DEBUGP("PCREL22F Symbol %s loc %p val %lx\n",
			       strtab + sym->st_name,
			       strtab + sym->st_name,
			       loc, val);
			       loc, val);
			val += addend;
			/* can we reach it locally? */
			/* can we reach it locally? */
			if(!in_local_section(me, (void *)val, (void *)dot)) {
			if (in_local(me, (void *)val)) {

				/* this is the case where the symbol is local
				if (in_local(me, (void *)val))
				 * to the module, but in a different section,
					/* this is the case where the
				 * so stub the jump in case it's more than 22
					 * symbol is local to the
					 * module, but in a different
					 * section, so stub the jump
					 * in case it's more than 22
				 * bits away */
				 * bits away */
					val = get_stub(me, val, addend, ELF_STUB_DIRECT,
				val = (val - dot - 8)/4;
						       in_init(me, loc));
				if (!RELOC_REACHABLE(val, 22)) {
				else if (strncmp(strtab + sym->st_name, "$$", 2)
					/* direct distance too far, create
					 * stub entry instead */
					val = get_stub(me, sym->st_value,
						addend, ELF_STUB_DIRECT,
						loc0, targetsec);
				} else {
					/* Ok, we can reach it directly. */
					val = sym->st_value;
					val += addend;
				}
			} else {
				val = sym->st_value;
				if (strncmp(strtab + sym->st_name, "$$", 2)
				    == 0)
				    == 0)
					val = get_stub(me, val, addend, ELF_STUB_MILLI,
					val = get_stub(me, val, addend, ELF_STUB_MILLI,
						       in_init(me, loc));
						       loc0, targetsec);
				else
				else
					val = get_stub(me, val, addend, ELF_STUB_GOT,
					val = get_stub(me, val, addend, ELF_STUB_GOT,
						       in_init(me, loc));
						       loc0, targetsec);
			}
			}
			DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", 
			DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", 
			       strtab + sym->st_name, loc, sym->st_value,
			       strtab + sym->st_name, loc, sym->st_value,
			       addend, val);
			       addend, val);
			/* FIXME: local symbols work as long as the
			 * core and init pieces aren't separated too
			 * far.  If this is ever broken, you will trip
			 * the check below.  The way to fix it would
			 * be to generate local stubs to go between init
			 * and core */
			if((Elf64_Sxword)(val - dot - 8) > 0x800000 -1 ||
			   (Elf64_Sxword)(val - dot - 8) < -0x800000) {
				printk(KERN_ERR "Module %s, symbol %s is out of range for PCREL22F relocation\n",
				       me->name, strtab + sym->st_name);
				return -ENOEXEC;
			}
			val = (val - dot - 8)/4;
			val = (val - dot - 8)/4;
			CHECK_RELOC(val, 22);
			*loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
			*loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
			break;
			break;
		case R_PARISC_DIR64:
		case R_PARISC_DIR64:
@@ -794,12 +849,8 @@ int module_finalize(const Elf_Ehdr *hdr,
	addr = (u32 *)entry->addr;
	addr = (u32 *)entry->addr;
	printk("INSNS: %x %x %x %x\n",
	printk("INSNS: %x %x %x %x\n",
	       addr[0], addr[1], addr[2], addr[3]);
	       addr[0], addr[1], addr[2], addr[3]);
	printk("stubs used %ld, stubs max %ld\n"
	printk("got entries used %ld, gots max %ld\n"
	       "init_stubs used %ld, init stubs max %ld\n"
	       "got entries used %ld, gots max %ld\n"
	       "fdescs used %ld, fdescs max %ld\n",
	       "fdescs used %ld, fdescs max %ld\n",
	       me->arch.stub_count, me->arch.stub_max,
	       me->arch.init_stub_count, me->arch.init_stub_max,
	       me->arch.got_count, me->arch.got_max,
	       me->arch.got_count, me->arch.got_max,
	       me->arch.fdesc_count, me->arch.fdesc_max);
	       me->arch.fdesc_count, me->arch.fdesc_max);
#endif
#endif
@@ -830,6 +881,9 @@ int module_finalize(const Elf_Ehdr *hdr,
		return -EINVAL;
		return -EINVAL;
	}
	}


	kfree(me->arch.section);
	me->arch.section = NULL;

	/* no symbol table */
	/* no symbol table */
	if(symhdr == NULL)
	if(symhdr == NULL)
		return 0;
		return 0;
Loading