aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/uv/bios.h4
-rw-r--r--arch/x86/include/asm/uv/uv.h1
-rw-r--r--arch/x86/include/asm/x86_init.h2
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c74
-rw-r--r--arch/x86/kernel/bios_uv.c19
-rw-r--r--arch/x86/kernel/smpboot.c1
-rw-r--r--arch/x86/kernel/x86_init.c3
-rw-r--r--drivers/gpu/vga/Kconfig8
-rw-r--r--drivers/gpu/vga/vgaarb.c27
-rw-r--r--drivers/pci/pci.c25
-rw-r--r--include/linux/pci.h5
11 files changed, 161 insertions, 8 deletions
diff --git a/arch/x86/include/asm/uv/bios.h b/arch/x86/include/asm/uv/bios.h
index 2751f3075d8b..163427597d03 100644
--- a/arch/x86/include/asm/uv/bios.h
+++ b/arch/x86/include/asm/uv/bios.h
@@ -36,7 +36,8 @@ enum uv_bios_cmd {
36 UV_BIOS_WATCHLIST_ALLOC, 36 UV_BIOS_WATCHLIST_ALLOC,
37 UV_BIOS_WATCHLIST_FREE, 37 UV_BIOS_WATCHLIST_FREE,
38 UV_BIOS_MEMPROTECT, 38 UV_BIOS_MEMPROTECT,
39 UV_BIOS_GET_PARTITION_ADDR 39 UV_BIOS_GET_PARTITION_ADDR,
40 UV_BIOS_SET_LEGACY_VGA_TARGET
40}; 41};
41 42
42/* 43/*
@@ -96,6 +97,7 @@ extern int uv_bios_mq_watchlist_alloc(unsigned long, unsigned int,
96extern int uv_bios_mq_watchlist_free(int, int); 97extern int uv_bios_mq_watchlist_free(int, int);
97extern s64 uv_bios_change_memprotect(u64, u64, enum uv_memprotect); 98extern s64 uv_bios_change_memprotect(u64, u64, enum uv_memprotect);
98extern s64 uv_bios_reserved_page_pa(u64, u64 *, u64 *, u64 *); 99extern s64 uv_bios_reserved_page_pa(u64, u64 *, u64 *, u64 *);
100extern int uv_bios_set_legacy_vga_target(bool decode, int domain, int bus);
99 101
100extern void uv_bios_init(void); 102extern void uv_bios_init(void);
101 103
diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h
index c0a01b5d985b..3bb9491b7659 100644
--- a/arch/x86/include/asm/uv/uv.h
+++ b/arch/x86/include/asm/uv/uv.h
@@ -11,6 +11,7 @@ struct mm_struct;
11extern enum uv_system_type get_uv_system_type(void); 11extern enum uv_system_type get_uv_system_type(void);
12extern int is_uv_system(void); 12extern int is_uv_system(void);
13extern void uv_cpu_init(void); 13extern void uv_cpu_init(void);
14extern void uv_nmi_init(void);
14extern void uv_system_init(void); 15extern void uv_system_init(void);
15extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, 16extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
16 struct mm_struct *mm, 17 struct mm_struct *mm,
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index ea0e8ea15e15..60cc35269083 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -126,6 +126,7 @@ struct x86_cpuinit_ops {
126 * @get_wallclock: get time from HW clock like RTC etc. 126 * @get_wallclock: get time from HW clock like RTC etc.
127 * @set_wallclock: set time back to HW clock 127 * @set_wallclock: set time back to HW clock
128 * @is_untracked_pat_range exclude from PAT logic 128 * @is_untracked_pat_range exclude from PAT logic
129 * @nmi_init enable NMI on cpus
129 */ 130 */
130struct x86_platform_ops { 131struct x86_platform_ops {
131 unsigned long (*calibrate_tsc)(void); 132 unsigned long (*calibrate_tsc)(void);
@@ -133,6 +134,7 @@ struct x86_platform_ops {
133 int (*set_wallclock)(unsigned long nowtime); 134 int (*set_wallclock)(unsigned long nowtime);
134 void (*iommu_shutdown)(void); 135 void (*iommu_shutdown)(void);
135 bool (*is_untracked_pat_range)(u64 start, u64 end); 136 bool (*is_untracked_pat_range)(u64 start, u64 end);
137 void (*nmi_init)(void);
136}; 138};
137 139
138extern struct x86_init_ops x86_init; 140extern struct x86_init_ops x86_init;
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}
diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/kernel/bios_uv.c
index b0206a211b09..575127a6e352 100644
--- a/arch/x86/kernel/bios_uv.c
+++ b/arch/x86/kernel/bios_uv.c
@@ -154,6 +154,25 @@ s64 uv_bios_freq_base(u64 clock_type, u64 *ticks_per_second)
154} 154}
155EXPORT_SYMBOL_GPL(uv_bios_freq_base); 155EXPORT_SYMBOL_GPL(uv_bios_freq_base);
156 156
157/*
158 * uv_bios_set_legacy_vga_target - Set Legacy VGA I/O Target
159 * @decode: true to enable target, false to disable target
160 * @domain: PCI domain number
161 * @bus: PCI bus number
162 *
163 * Returns:
164 * 0: Success
165 * -EINVAL: Invalid domain or bus number
166 * -ENOSYS: Capability not available
167 * -EBUSY: Legacy VGA I/O cannot be retargeted at this time
168 */
169int uv_bios_set_legacy_vga_target(bool decode, int domain, int bus)
170{
171 return uv_bios_call(UV_BIOS_SET_LEGACY_VGA_TARGET,
172 (u64)decode, (u64)domain, (u64)bus, 0, 0);
173}
174EXPORT_SYMBOL_GPL(uv_bios_set_legacy_vga_target);
175
157 176
158#ifdef CONFIG_EFI 177#ifdef CONFIG_EFI
159void uv_bios_init(void) 178void uv_bios_init(void)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index b4e870cbdc60..9b4401115ea1 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -320,6 +320,7 @@ notrace static void __cpuinit start_secondary(void *unused)
320 unlock_vector_lock(); 320 unlock_vector_lock();
321 ipi_call_unlock(); 321 ipi_call_unlock();
322 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; 322 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
323 x86_platform.nmi_init();
323 324
324 /* enable local interrupts */ 325 /* enable local interrupts */
325 local_irq_enable(); 326 local_irq_enable();
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index ccd179dec36e..ee5746c94628 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -76,10 +76,13 @@ struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
76 .setup_percpu_clockev = setup_secondary_APIC_clock, 76 .setup_percpu_clockev = setup_secondary_APIC_clock,
77}; 77};
78 78
79static void default_nmi_init(void) { };
80
79struct x86_platform_ops x86_platform = { 81struct x86_platform_ops x86_platform = {
80 .calibrate_tsc = native_calibrate_tsc, 82 .calibrate_tsc = native_calibrate_tsc,
81 .get_wallclock = mach_get_cmos_time, 83 .get_wallclock = mach_get_cmos_time,
82 .set_wallclock = mach_set_rtc_mmss, 84 .set_wallclock = mach_set_rtc_mmss,
83 .iommu_shutdown = iommu_shutdown_noop, 85 .iommu_shutdown = iommu_shutdown_noop,
84 .is_untracked_pat_range = is_ISA_range, 86 .is_untracked_pat_range = is_ISA_range,
87 .nmi_init = default_nmi_init
85}; 88};
diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig
index 790e675b13eb..0920492cea0a 100644
--- a/drivers/gpu/vga/Kconfig
+++ b/drivers/gpu/vga/Kconfig
@@ -8,3 +8,11 @@ config VGA_ARB
8 are accessed at same time they need some kind of coordination. Please 8 are accessed at same time they need some kind of coordination. Please
9 see Documentation/vgaarbiter.txt for more details. Select this to 9 see Documentation/vgaarbiter.txt for more details. Select this to
10 enable VGA arbiter. 10 enable VGA arbiter.
11
12config VGA_ARB_MAX_GPUS
13 int "Maximum number of GPUs"
14 default 16
15 depends on VGA_ARB
16 help
17 Reserves space in the kernel to maintain resource locking for
18 multiple GPUS. The overhead for each GPU is very small.
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 2f6cf69ecb39..8827814d0735 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -688,7 +688,7 @@ EXPORT_SYMBOL(vga_client_register);
688 * the arbiter. 688 * the arbiter.
689 */ 689 */
690 690
691#define MAX_USER_CARDS 16 691#define MAX_USER_CARDS CONFIG_VGA_ARB_MAX_GPUS
692#define PCI_INVALID_CARD ((struct pci_dev *)-1UL) 692#define PCI_INVALID_CARD ((struct pci_dev *)-1UL)
693 693
694/* 694/*
@@ -954,6 +954,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
954 } 954 }
955 955
956 } else if (strncmp(curr_pos, "target ", 7) == 0) { 956 } else if (strncmp(curr_pos, "target ", 7) == 0) {
957 struct pci_bus *pbus;
957 unsigned int domain, bus, devfn; 958 unsigned int domain, bus, devfn;
958 struct vga_device *vgadev; 959 struct vga_device *vgadev;
959 960
@@ -969,18 +970,31 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
969 ret_val = -EPROTO; 970 ret_val = -EPROTO;
970 goto done; 971 goto done;
971 } 972 }
972 973 pr_devel("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos,
973 pdev = pci_get_bus_and_slot(bus, devfn); 974 domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
975
976 pbus = pci_find_bus(domain, bus);
977 pr_devel("vgaarb: pbus %p\n", pbus);
978 if (pbus == NULL) {
979 pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n",
980 domain, bus);
981 ret_val = -ENODEV;
982 goto done;
983 }
984 pdev = pci_get_slot(pbus, devfn);
985 pr_devel("vgaarb: pdev %p\n", pdev);
974 if (!pdev) { 986 if (!pdev) {
975 pr_info("vgaarb: invalid PCI address!\n"); 987 pr_err("vgaarb: invalid PCI address %x:%x\n",
988 bus, devfn);
976 ret_val = -ENODEV; 989 ret_val = -ENODEV;
977 goto done; 990 goto done;
978 } 991 }
979 } 992 }
980 993
981 vgadev = vgadev_find(pdev); 994 vgadev = vgadev_find(pdev);
995 pr_devel("vgaarb: vgadev %p\n", vgadev);
982 if (vgadev == NULL) { 996 if (vgadev == NULL) {
983 pr_info("vgaarb: this pci device is not a vga device\n"); 997 pr_err("vgaarb: this pci device is not a vga device\n");
984 pci_dev_put(pdev); 998 pci_dev_put(pdev);
985 ret_val = -ENODEV; 999 ret_val = -ENODEV;
986 goto done; 1000 goto done;
@@ -998,7 +1012,8 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
998 } 1012 }
999 } 1013 }
1000 if (i == MAX_USER_CARDS) { 1014 if (i == MAX_USER_CARDS) {
1001 pr_err("vgaarb: maximum user cards number reached!\n"); 1015 pr_err("vgaarb: maximum user cards (%d) number reached!\n",
1016 MAX_USER_CARDS);
1002 pci_dev_put(pdev); 1017 pci_dev_put(pdev);
1003 /* XXX: which value to return? */ 1018 /* XXX: which value to return? */
1004 ret_val = -ENOMEM; 1019 ret_val = -ENOMEM;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 2b9ac9e594af..5b548aee9cbc 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2754,6 +2754,23 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
2754 return 0; 2754 return 0;
2755} 2755}
2756 2756
2757/* Some architectures require additional programming to enable VGA */
2758static arch_set_vga_state_t arch_set_vga_state;
2759
2760void __init pci_register_set_vga_state(arch_set_vga_state_t func)
2761{
2762 arch_set_vga_state = func; /* NULL disables */
2763}
2764
2765static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode,
2766 unsigned int command_bits, bool change_bridge)
2767{
2768 if (arch_set_vga_state)
2769 return arch_set_vga_state(dev, decode, command_bits,
2770 change_bridge);
2771 return 0;
2772}
2773
2757/** 2774/**
2758 * pci_set_vga_state - set VGA decode state on device and parents if requested 2775 * pci_set_vga_state - set VGA decode state on device and parents if requested
2759 * @dev: the PCI device 2776 * @dev: the PCI device
@@ -2767,9 +2784,15 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode,
2767 struct pci_bus *bus; 2784 struct pci_bus *bus;
2768 struct pci_dev *bridge; 2785 struct pci_dev *bridge;
2769 u16 cmd; 2786 u16 cmd;
2787 int rc;
2770 2788
2771 WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); 2789 WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
2772 2790
2791 /* ARCH specific VGA enables */
2792 rc = pci_set_vga_state_arch(dev, decode, command_bits, change_bridge);
2793 if (rc)
2794 return rc;
2795
2773 pci_read_config_word(dev, PCI_COMMAND, &cmd); 2796 pci_read_config_word(dev, PCI_COMMAND, &cmd);
2774 if (decode == true) 2797 if (decode == true)
2775 cmd |= command_bits; 2798 cmd |= command_bits;
@@ -2984,6 +3007,7 @@ EXPORT_SYMBOL(pcim_pin_device);
2984EXPORT_SYMBOL(pci_disable_device); 3007EXPORT_SYMBOL(pci_disable_device);
2985EXPORT_SYMBOL(pci_find_capability); 3008EXPORT_SYMBOL(pci_find_capability);
2986EXPORT_SYMBOL(pci_bus_find_capability); 3009EXPORT_SYMBOL(pci_bus_find_capability);
3010EXPORT_SYMBOL(pci_register_set_vga_state);
2987EXPORT_SYMBOL(pci_release_regions); 3011EXPORT_SYMBOL(pci_release_regions);
2988EXPORT_SYMBOL(pci_request_regions); 3012EXPORT_SYMBOL(pci_request_regions);
2989EXPORT_SYMBOL(pci_request_regions_exclusive); 3013EXPORT_SYMBOL(pci_request_regions_exclusive);
@@ -3015,4 +3039,3 @@ EXPORT_SYMBOL(pci_target_state);
3015EXPORT_SYMBOL(pci_prepare_to_sleep); 3039EXPORT_SYMBOL(pci_prepare_to_sleep);
3016EXPORT_SYMBOL(pci_back_from_sleep); 3040EXPORT_SYMBOL(pci_back_from_sleep);
3017EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); 3041EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state);
3018
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e19a69613d8f..25813738c71a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1023,6 +1023,11 @@ static inline int pci_proc_domain(struct pci_bus *bus)
1023} 1023}
1024#endif /* CONFIG_PCI_DOMAINS */ 1024#endif /* CONFIG_PCI_DOMAINS */
1025 1025
1026/* some architectures require additional setup to direct VGA traffic */
1027typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
1028 unsigned int command_bits, bool change_bridge);
1029extern void pci_register_set_vga_state(arch_set_vga_state_t func);
1030
1026#else /* CONFIG_PCI is not enabled */ 1031#else /* CONFIG_PCI is not enabled */
1027 1032
1028/* 1033/*