aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-02-28 13:59:18 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-02-28 13:59:18 -0500
commitc7e15899d07c9813c1aa96b21699d2d9c8314c4b (patch)
tree16e9b4dceddf1b4d1dad05588d700c70cf8fcb88 /arch/x86/kernel/apic
parentf6a0b5cd34d6e922cc7258c5429fb0f17508ceb6 (diff)
parent78c06176466cbd1b3f0f67709d3023c40dbebcbd (diff)
Merge branch 'x86-pci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-pci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86: Enable NMI on all cpus on UV vgaarb: Add user selectability of the number of GPUS in a system vgaarb: Fix VGA arbiter to accept PCI domains other than 0 x86, uv: Update UV arch to target Legacy VGA I/O correctly. pci: Update pci_set_vga_state() to call arch functions
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 21db3cbea7dc..4b8dbb256147 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -20,6 +20,8 @@
20#include <linux/cpu.h> 20#include <linux/cpu.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/pci.h>
24#include <linux/kdebug.h>
23 25
24#include <asm/uv/uv_mmrs.h> 26#include <asm/uv/uv_mmrs.h>
25#include <asm/uv/uv_hub.h> 27#include <asm/uv/uv_hub.h>
@@ -34,10 +36,13 @@
34 36
35DEFINE_PER_CPU(int, x2apic_extra_bits); 37DEFINE_PER_CPU(int, x2apic_extra_bits);
36 38
39#define PR_DEVEL(fmt, args...) pr_devel("%s: " fmt, __func__, args)
40
37static enum uv_system_type uv_system_type; 41static enum uv_system_type uv_system_type;
38static u64 gru_start_paddr, gru_end_paddr; 42static u64 gru_start_paddr, gru_end_paddr;
39int uv_min_hub_revision_id; 43int uv_min_hub_revision_id;
40EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); 44EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
45static DEFINE_SPINLOCK(uv_nmi_lock);
41 46
42static inline bool is_GRU_range(u64 start, u64 end) 47static inline bool is_GRU_range(u64 start, u64 end)
43{ 48{
@@ -71,6 +76,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
71 if (!strcmp(oem_id, "SGI")) { 76 if (!strcmp(oem_id, "SGI")) {
72 nodeid = early_get_nodeid(); 77 nodeid = early_get_nodeid();
73 x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; 78 x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
79 x86_platform.nmi_init = uv_nmi_init;
74 if (!strcmp(oem_table_id, "UVL")) 80 if (!strcmp(oem_table_id, "UVL"))
75 uv_system_type = UV_LEGACY_APIC; 81 uv_system_type = UV_LEGACY_APIC;
76 else if (!strcmp(oem_table_id, "UVX")) 82 else if (!strcmp(oem_table_id, "UVX"))
@@ -553,6 +559,30 @@ late_initcall(uv_init_heartbeat);
553 559
554#endif /* !CONFIG_HOTPLUG_CPU */ 560#endif /* !CONFIG_HOTPLUG_CPU */
555 561
562/* Direct Legacy VGA I/O traffic to designated IOH */
563int uv_set_vga_state(struct pci_dev *pdev, bool decode,
564 unsigned int command_bits, bool change_bridge)
565{
566 int domain, bus, rc;
567
568 PR_DEVEL("devfn %x decode %d cmd %x chg_brdg %d\n",
569 pdev->devfn, decode, command_bits, change_bridge);
570
571 if (!change_bridge)
572 return 0;
573
574 if ((command_bits & PCI_COMMAND_IO) == 0)
575 return 0;
576
577 domain = pci_domain_nr(pdev->bus);
578 bus = pdev->bus->number;
579
580 rc = uv_bios_set_legacy_vga_target(decode, domain, bus);
581 PR_DEVEL("vga decode %d %x:%x, rc: %d\n", decode, domain, bus, rc);
582
583 return rc;
584}
585
556/* 586/*
557 * Called on each cpu to initialize the per_cpu UV data area. 587 * Called on each cpu to initialize the per_cpu UV data area.
558 * FIXME: hotplug not supported yet 588 * FIXME: hotplug not supported yet
@@ -569,6 +599,46 @@ void __cpuinit uv_cpu_init(void)
569 set_x2apic_extra_bits(uv_hub_info->pnode); 599 set_x2apic_extra_bits(uv_hub_info->pnode);
570} 600}
571 601
602/*
603 * When NMI is received, print a stack trace.
604 */
605int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data)
606{
607 if (reason != DIE_NMI_IPI)
608 return NOTIFY_OK;
609 /*
610 * Use a lock so only one cpu prints at a time
611 * to prevent intermixed output.
612 */
613 spin_lock(&uv_nmi_lock);
614 pr_info("NMI stack dump cpu %u:\n", smp_processor_id());
615 dump_stack();
616 spin_unlock(&uv_nmi_lock);
617
618 return NOTIFY_STOP;
619}
620
621static struct notifier_block uv_dump_stack_nmi_nb = {
622 .notifier_call = uv_handle_nmi
623};
624
625void uv_register_nmi_notifier(void)
626{
627 if (register_die_notifier(&uv_dump_stack_nmi_nb))
628 printk(KERN_WARNING "UV NMI handler failed to register\n");
629}
630
631void uv_nmi_init(void)
632{
633 unsigned int value;
634
635 /*
636 * Unmask NMI on all cpus
637 */
638 value = apic_read(APIC_LVT1) | APIC_DM_NMI;
639 value &= ~APIC_LVT_MASKED;
640 apic_write(APIC_LVT1, value);
641}
572 642
573void __init uv_system_init(void) 643void __init uv_system_init(void)
574{ 644{
@@ -690,5 +760,9 @@ void __init uv_system_init(void)
690 760
691 uv_cpu_init(); 761 uv_cpu_init();
692 uv_scir_register_cpu_notifier(); 762 uv_scir_register_cpu_notifier();
763 uv_register_nmi_notifier();
693 proc_mkdir("sgi_uv", NULL); 764 proc_mkdir("sgi_uv", NULL);
765
766 /* register Legacy VGA I/O redirection handler */
767 pci_register_set_vga_state(uv_set_vga_state);
694} 768}