Commit c029b55a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, asm: Use a lower case name for the end macro in atomic64_386_32.S
  x86, asm: Refactor atomic64_386_32.S to support old binutils and be cleaner
  x86: Document __phys_reloc_hide() usage in __pa_symbol()
  x86, apic: Map the local apic when parsing the MP table.
parents 96054569 417484d4
...@@ -37,6 +37,13 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, ...@@ -37,6 +37,13 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
#define __pa_nodebug(x) __phys_addr_nodebug((unsigned long)(x)) #define __pa_nodebug(x) __phys_addr_nodebug((unsigned long)(x))
/* __pa_symbol should be used for C visible symbols. /* __pa_symbol should be used for C visible symbols.
This seems to be the official gcc blessed way to do such arithmetic. */ This seems to be the official gcc blessed way to do such arithmetic. */
/*
* We need __phys_reloc_hide() here because gcc may assume that there is no
* overflow during __pa() calculation and can optimize it unexpectedly.
* Newer versions of gcc provide -fno-strict-overflow switch to handle this
* case properly. Once all supported versions of gcc understand it, we can
* remove this Voodoo magic stuff. (i.e. once gcc3.x is deprecated)
*/
#define __pa_symbol(x) __pa(__phys_reloc_hide((unsigned long)(x))) #define __pa_symbol(x) __pa(__phys_reloc_hide((unsigned long)(x)))
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
......
...@@ -1606,7 +1606,7 @@ void __init init_apic_mappings(void) ...@@ -1606,7 +1606,7 @@ void __init init_apic_mappings(void)
* acpi lapic path already maps that address in * acpi lapic path already maps that address in
* acpi_register_lapic_address() * acpi_register_lapic_address()
*/ */
if (!acpi_lapic) if (!acpi_lapic && !smp_found_config)
set_fixmap_nocache(FIX_APIC_BASE, apic_phys); set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n", apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
......
...@@ -274,6 +274,18 @@ static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt) ...@@ -274,6 +274,18 @@ static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { } void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { }
static void __init smp_register_lapic_address(unsigned long address)
{
mp_lapic_addr = address;
set_fixmap_nocache(FIX_APIC_BASE, address);
if (boot_cpu_physical_apicid == -1U) {
boot_cpu_physical_apicid = read_apic_id();
apic_version[boot_cpu_physical_apicid] =
GET_APIC_VERSION(apic_read(APIC_LVR));
}
}
static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
{ {
char str[16]; char str[16];
...@@ -295,6 +307,10 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) ...@@ -295,6 +307,10 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
if (early) if (early)
return 1; return 1;
/* Initialize the lapic mapping */
if (!acpi_lapic)
smp_register_lapic_address(mpc->lapic);
if (mpc->oemptr) if (mpc->oemptr)
x86_init.mpparse.smp_read_mpc_oem(mpc); x86_init.mpparse.smp_read_mpc_oem(mpc);
......
...@@ -25,150 +25,172 @@ ...@@ -25,150 +25,172 @@
CFI_ADJUST_CFA_OFFSET -4 CFI_ADJUST_CFA_OFFSET -4
.endm .endm
.macro BEGIN func reg #define BEGIN(op) \
$v = \reg .macro endp; \
CFI_ENDPROC; \
ENTRY(atomic64_\func\()_386) ENDPROC(atomic64_##op##_386); \
CFI_STARTPROC .purgem endp; \
LOCK $v .endm; \
ENTRY(atomic64_##op##_386); \
.macro RETURN CFI_STARTPROC; \
UNLOCK $v LOCK v;
#define ENDP endp
#define RET \
UNLOCK v; \
ret ret
.endm
.macro END_
CFI_ENDPROC
ENDPROC(atomic64_\func\()_386)
.purgem RETURN
.purgem END_
.purgem END
.endm
.macro END
RETURN
END_
.endm
.endm
BEGIN read %ecx #define RET_ENDP \
movl ($v), %eax RET; \
movl 4($v), %edx ENDP
END
#define v %ecx
BEGIN set %esi BEGIN(read)
movl %ebx, ($v) movl (v), %eax
movl %ecx, 4($v) movl 4(v), %edx
END RET_ENDP
#undef v
BEGIN xchg %esi
movl ($v), %eax #define v %esi
movl 4($v), %edx BEGIN(set)
movl %ebx, ($v) movl %ebx, (v)
movl %ecx, 4($v) movl %ecx, 4(v)
END RET_ENDP
#undef v
BEGIN add %ecx
addl %eax, ($v) #define v %esi
adcl %edx, 4($v) BEGIN(xchg)
END movl (v), %eax
movl 4(v), %edx
BEGIN add_return %ecx movl %ebx, (v)
addl ($v), %eax movl %ecx, 4(v)
adcl 4($v), %edx RET_ENDP
movl %eax, ($v) #undef v
movl %edx, 4($v)
END #define v %ecx
BEGIN(add)
BEGIN sub %ecx addl %eax, (v)
subl %eax, ($v) adcl %edx, 4(v)
sbbl %edx, 4($v) RET_ENDP
END #undef v
BEGIN sub_return %ecx #define v %ecx
BEGIN(add_return)
addl (v), %eax
adcl 4(v), %edx
movl %eax, (v)
movl %edx, 4(v)
RET_ENDP
#undef v
#define v %ecx
BEGIN(sub)
subl %eax, (v)
sbbl %edx, 4(v)
RET_ENDP
#undef v
#define v %ecx
BEGIN(sub_return)
negl %edx negl %edx
negl %eax negl %eax
sbbl $0, %edx sbbl $0, %edx
addl ($v), %eax addl (v), %eax
adcl 4($v), %edx adcl 4(v), %edx
movl %eax, ($v) movl %eax, (v)
movl %edx, 4($v) movl %edx, 4(v)
END RET_ENDP
#undef v
BEGIN inc %esi
addl $1, ($v) #define v %esi
adcl $0, 4($v) BEGIN(inc)
END addl $1, (v)
adcl $0, 4(v)
BEGIN inc_return %esi RET_ENDP
movl ($v), %eax #undef v
movl 4($v), %edx
#define v %esi
BEGIN(inc_return)
movl (v), %eax
movl 4(v), %edx
addl $1, %eax addl $1, %eax
adcl $0, %edx adcl $0, %edx
movl %eax, ($v) movl %eax, (v)
movl %edx, 4($v) movl %edx, 4(v)
END RET_ENDP
#undef v
BEGIN dec %esi
subl $1, ($v) #define v %esi
sbbl $0, 4($v) BEGIN(dec)
END subl $1, (v)
sbbl $0, 4(v)
BEGIN dec_return %esi RET_ENDP
movl ($v), %eax #undef v
movl 4($v), %edx
#define v %esi
BEGIN(dec_return)
movl (v), %eax
movl 4(v), %edx
subl $1, %eax subl $1, %eax
sbbl $0, %edx sbbl $0, %edx
movl %eax, ($v) movl %eax, (v)
movl %edx, 4($v) movl %edx, 4(v)
END RET_ENDP
#undef v
BEGIN add_unless %ecx #define v %ecx
BEGIN(add_unless)
addl %eax, %esi addl %eax, %esi
adcl %edx, %edi adcl %edx, %edi
addl ($v), %eax addl (v), %eax
adcl 4($v), %edx adcl 4(v), %edx
cmpl %eax, %esi cmpl %eax, %esi
je 3f je 3f
1: 1:
movl %eax, ($v) movl %eax, (v)
movl %edx, 4($v) movl %edx, 4(v)
movl $1, %eax movl $1, %eax
2: 2:
RETURN RET
3: 3:
cmpl %edx, %edi cmpl %edx, %edi
jne 1b jne 1b
xorl %eax, %eax xorl %eax, %eax
jmp 2b jmp 2b
END_ ENDP
#undef v
BEGIN inc_not_zero %esi #define v %esi
movl ($v), %eax BEGIN(inc_not_zero)
movl 4($v), %edx movl (v), %eax
movl 4(v), %edx
testl %eax, %eax testl %eax, %eax
je 3f je 3f
1: 1:
addl $1, %eax addl $1, %eax
adcl $0, %edx adcl $0, %edx
movl %eax, ($v) movl %eax, (v)
movl %edx, 4($v) movl %edx, 4(v)
movl $1, %eax movl $1, %eax
2: 2:
RETURN RET
3: 3:
testl %edx, %edx testl %edx, %edx
jne 1b jne 1b
jmp 2b jmp 2b
END_ ENDP
#undef v
BEGIN dec_if_positive %esi #define v %esi
movl ($v), %eax BEGIN(dec_if_positive)
movl 4($v), %edx movl (v), %eax
movl 4(v), %edx
subl $1, %eax subl $1, %eax
sbbl $0, %edx sbbl $0, %edx
js 1f js 1f
movl %eax, ($v) movl %eax, (v)
movl %edx, 4($v) movl %edx, 4(v)
1: 1:
END RET_ENDP
#undef v
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment