diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2015-01-15 16:22:26 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2015-01-22 09:10:55 -0500 |
commit | 659006bf3ae37a08706907ce1a36ddf57c9131d2 (patch) | |
tree | 750a08e8d94d010d0c2ef275d54574551913b4ad /arch/x86/kernel | |
parent | 44e25ff9e6912347a1a54c757fc75681d0dc42d0 (diff) |
x86/x2apic: Split enable and setup function
enable_x2apic() is a convoluted unreadable mess because it is used for
both enablement in early boot and for setup in cpu_init().
Split the code into x2apic_enable() for enablement and x2apic_setup()
for setup of (secondary cpus). Make use of the new state tracking to
simplify the logic.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Link: http://lkml.kernel.org/r/20150115211703.129287153@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 63 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 2 |
2 files changed, 39 insertions, 26 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 90b8ac5df250..0ee96b9fe4e6 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -1488,6 +1488,9 @@ static inline void __x2apic_disable(void) | |||
1488 | { | 1488 | { |
1489 | u64 msr; | 1489 | u64 msr; |
1490 | 1490 | ||
1491 | if (cpu_has_apic) | ||
1492 | return; | ||
1493 | |||
1491 | rdmsrl(MSR_IA32_APICBASE, msr); | 1494 | rdmsrl(MSR_IA32_APICBASE, msr); |
1492 | if (!(msr & X2APIC_ENABLE)) | 1495 | if (!(msr & X2APIC_ENABLE)) |
1493 | return; | 1496 | return; |
@@ -1497,6 +1500,17 @@ static inline void __x2apic_disable(void) | |||
1497 | printk_once(KERN_INFO "x2apic disabled\n"); | 1500 | printk_once(KERN_INFO "x2apic disabled\n"); |
1498 | } | 1501 | } |
1499 | 1502 | ||
1503 | static inline void __x2apic_enable(void) | ||
1504 | { | ||
1505 | u64 msr; | ||
1506 | |||
1507 | rdmsrl(MSR_IA32_APICBASE, msr); | ||
1508 | if (msr & X2APIC_ENABLE) | ||
1509 | return; | ||
1510 | wrmsrl(MSR_IA32_APICBASE, msr | X2APIC_ENABLE); | ||
1511 | printk_once(KERN_INFO "x2apic enabled\n"); | ||
1512 | } | ||
1513 | |||
1500 | static int __init setup_nox2apic(char *str) | 1514 | static int __init setup_nox2apic(char *str) |
1501 | { | 1515 | { |
1502 | if (x2apic_enabled()) { | 1516 | if (x2apic_enabled()) { |
@@ -1517,6 +1531,20 @@ static int __init setup_nox2apic(char *str) | |||
1517 | } | 1531 | } |
1518 | early_param("nox2apic", setup_nox2apic); | 1532 | early_param("nox2apic", setup_nox2apic); |
1519 | 1533 | ||
1534 | /* Called from cpu_init() to enable x2apic on (secondary) cpus */ | ||
1535 | void x2apic_setup(void) | ||
1536 | { | ||
1537 | /* | ||
1538 | * If x2apic is not in ON state, disable it if already enabled | ||
1539 | * from BIOS. | ||
1540 | */ | ||
1541 | if (x2apic_state != X2APIC_ON) { | ||
1542 | __x2apic_disable(); | ||
1543 | return; | ||
1544 | } | ||
1545 | __x2apic_enable(); | ||
1546 | } | ||
1547 | |||
1520 | static __init void x2apic_disable(void) | 1548 | static __init void x2apic_disable(void) |
1521 | { | 1549 | { |
1522 | u64 msr; | 1550 | u64 msr; |
@@ -1541,30 +1569,19 @@ static __init void x2apic_disable(void) | |||
1541 | x2apic_state = X2APIC_DISABLED; | 1569 | x2apic_state = X2APIC_DISABLED; |
1542 | } | 1570 | } |
1543 | 1571 | ||
1544 | void enable_x2apic(void) | 1572 | static __init void x2apic_enable(void) |
1545 | { | 1573 | { |
1546 | u64 msr; | 1574 | if (x2apic_state != X2APIC_OFF) |
1547 | |||
1548 | if (x2apic_state == X2APIC_DISABLED) { | ||
1549 | __x2apic_disable(); | ||
1550 | x2apic_mode = 0; | ||
1551 | return; | ||
1552 | } | ||
1553 | |||
1554 | if (!x2apic_mode) | ||
1555 | return; | 1575 | return; |
1556 | 1576 | ||
1557 | rdmsrl(MSR_IA32_APICBASE, msr); | 1577 | x2apic_mode = 1; |
1558 | if (!(msr & X2APIC_ENABLE)) { | ||
1559 | printk_once(KERN_INFO "Enabling x2apic\n"); | ||
1560 | wrmsrl(MSR_IA32_APICBASE, msr | X2APIC_ENABLE); | ||
1561 | } | ||
1562 | x2apic_state = X2APIC_ON; | 1578 | x2apic_state = X2APIC_ON; |
1579 | __x2apic_enable(); | ||
1563 | } | 1580 | } |
1564 | 1581 | ||
1565 | static __init void try_to_enable_x2apic(int remap_mode) | 1582 | static __init void try_to_enable_x2apic(int remap_mode) |
1566 | { | 1583 | { |
1567 | if (!x2apic_supported()) | 1584 | if (x2apic_state == X2APIC_DISABLED) |
1568 | return; | 1585 | return; |
1569 | 1586 | ||
1570 | if (remap_mode != IRQ_REMAP_X2APIC_MODE) { | 1587 | if (remap_mode != IRQ_REMAP_X2APIC_MODE) { |
@@ -1585,12 +1602,7 @@ static __init void try_to_enable_x2apic(int remap_mode) | |||
1585 | */ | 1602 | */ |
1586 | x2apic_phys = 1; | 1603 | x2apic_phys = 1; |
1587 | } | 1604 | } |
1588 | 1605 | x2apic_enable(); | |
1589 | if (!x2apic_mode) { | ||
1590 | x2apic_mode = 1; | ||
1591 | enable_x2apic(); | ||
1592 | pr_info("Enabled x2apic\n"); | ||
1593 | } | ||
1594 | } | 1606 | } |
1595 | 1607 | ||
1596 | void __init check_x2apic(void) | 1608 | void __init check_x2apic(void) |
@@ -1616,6 +1628,7 @@ static int __init validate_x2apic(void) | |||
1616 | early_initcall(validate_x2apic); | 1628 | early_initcall(validate_x2apic); |
1617 | 1629 | ||
1618 | static inline void try_to_enable_x2apic(int remap_mode) { } | 1630 | static inline void try_to_enable_x2apic(int remap_mode) { } |
1631 | static inline void __x2apic_enable(void) { } | ||
1619 | #endif /* !CONFIG_X86_X2APIC */ | 1632 | #endif /* !CONFIG_X86_X2APIC */ |
1620 | 1633 | ||
1621 | static int __init try_to_enable_IR(void) | 1634 | static int __init try_to_enable_IR(void) |
@@ -2357,9 +2370,9 @@ static void lapic_resume(void) | |||
2357 | mask_ioapic_entries(); | 2370 | mask_ioapic_entries(); |
2358 | legacy_pic->mask_all(); | 2371 | legacy_pic->mask_all(); |
2359 | 2372 | ||
2360 | if (x2apic_mode) | 2373 | if (x2apic_mode) { |
2361 | enable_x2apic(); | 2374 | __x2apic_enable(); |
2362 | else { | 2375 | } else { |
2363 | /* | 2376 | /* |
2364 | * Make sure the APICBASE points to the right address | 2377 | * Make sure the APICBASE points to the right address |
2365 | * | 2378 | * |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c6049650c093..cb5692551b98 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1332,7 +1332,7 @@ void cpu_init(void) | |||
1332 | barrier(); | 1332 | barrier(); |
1333 | 1333 | ||
1334 | x86_configure_nx(); | 1334 | x86_configure_nx(); |
1335 | enable_x2apic(); | 1335 | x2apic_setup(); |
1336 | 1336 | ||
1337 | /* | 1337 | /* |
1338 | * set up and load the per-CPU TSS | 1338 | * set up and load the per-CPU TSS |