diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/boot/pm.c | 6 | ||||
-rw-r--r-- | arch/i386/boot/video-vesa.c | 34 | ||||
-rw-r--r-- | arch/i386/kernel/alternative.c | 6 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/intel_cacheinfo.c | 4 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/perfctr-watchdog.c | 28 | ||||
-rw-r--r-- | arch/i386/kernel/nmi.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/ptrace.c | 1 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 33 | ||||
-rw-r--r-- | arch/i386/mach-generic/Makefile | 2 | ||||
-rw-r--r-- | arch/i386/mach-voyager/Makefile | 2 | ||||
-rw-r--r-- | arch/i386/mm/highmem.c | 7 | ||||
-rw-r--r-- | arch/i386/mm/hugetlbpage.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/irq.c | 1 | ||||
-rw-r--r-- | arch/i386/pci/pcbios.c | 2 |
14 files changed, 83 insertions, 47 deletions
diff --git a/arch/i386/boot/pm.c b/arch/i386/boot/pm.c index 6be9ca811d1..09fb342cc62 100644 --- a/arch/i386/boot/pm.c +++ b/arch/i386/boot/pm.c @@ -122,7 +122,11 @@ static void setup_gdt(void) /* DS: data, read/write, 4 GB, base 0 */ [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), }; - struct gdt_ptr gdt; + /* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead + of the gdt_ptr contents. Thus, make it static so it will + stay in memory, at least long enough that we switch to the + proper kernel GDT. */ + static struct gdt_ptr gdt; gdt.len = sizeof(boot_gdt)-1; gdt.ptr = (u32)&boot_gdt + (ds() << 4); diff --git a/arch/i386/boot/video-vesa.c b/arch/i386/boot/video-vesa.c index f1bc71e948c..19219071071 100644 --- a/arch/i386/boot/video-vesa.c +++ b/arch/i386/boot/video-vesa.c @@ -29,7 +29,7 @@ static void vesa_store_mode_params_graphics(void); static int vesa_probe(void) { #if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID) - u16 ax; + u16 ax, cx, di; u16 mode; addr_t mode_ptr; struct mode_info *mi; @@ -39,9 +39,11 @@ static int vesa_probe(void) vginfo.signature = VBE2_MAGIC; - /* Optimistically assume a VESA BIOS is register-clean... */ ax = 0x4f00; - asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo)); + di = (size_t)&vginfo; + asm(INT10 + : "+a" (ax), "+D" (di), "=m" (vginfo) + : : "ebx", "ecx", "edx", "esi"); if (ax != 0x004f || vginfo.signature != VESA_MAGIC || @@ -64,9 +66,11 @@ static int vesa_probe(void) memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ ax = 0x4f01; - asm("int $0x10" - : "+a" (ax), "=m" (vminfo) - : "c" (mode), "D" (&vminfo)); + cx = mode; + di = (size_t)&vminfo; + asm(INT10 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) + : : "ebx", "edx", "esi"); if (ax != 0x004f) continue; @@ -102,16 +106,18 @@ static int vesa_probe(void) static int vesa_set_mode(struct mode_info *mode) { - u16 ax; + u16 ax, bx, cx, di; int is_graphic; u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA; memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ ax = 0x4f01; - asm("int $0x10" - : "+a" (ax), "=m" (vminfo) - : "c" (vesa_mode), "D" (&vminfo)); + cx = vesa_mode; + di = (size_t)&vminfo; + asm(INT10 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) + : : "ebx", "edx", "esi"); if (ax != 0x004f) return -1; @@ -129,9 +135,11 @@ static int vesa_set_mode(struct mode_info *mode) ax = 0x4f02; - asm volatile("int $0x10" - : "+a" (ax) - : "b" (vesa_mode), "D" (0)); + bx = vesa_mode; + di = 0; + asm volatile(INT10 + : "+a" (ax), "+b" (bx), "+D" (di) + : : "ecx", "edx", "esi"); if (ax != 0x004f) return -1; diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 9f4ac8b02de..bd72d94e713 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -445,8 +445,6 @@ void __kprobes text_poke(void *addr, unsigned char *opcode, int len) { memcpy(addr, opcode, len); sync_core(); - /* Not strictly needed, but can speed CPU recovery up. Ignore cross cacheline - case. */ - if (cpu_has_clflush) - asm("clflush (%0) " :: "r" (addr) : "memory"); + /* Could also do a CLFLUSH here to speed up CPU recovery; but + that causes hangs on some VIA CPUs. */ } diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index d5a456d27d8..db6c25aa577 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -515,7 +515,7 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) cpuid4_info[cpu] = kzalloc( sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); - if (unlikely(cpuid4_info[cpu] == NULL)) + if (cpuid4_info[cpu] == NULL) return -ENOMEM; oldmask = current->cpus_allowed; @@ -748,6 +748,8 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev) unsigned int cpu = sys_dev->id; unsigned long i; + if (cpuid4_info[cpu] == NULL) + return; for (i = 0; i < num_cache_leaves; i++) { cache_remove_shared_cpu_map(cpu, i); kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); diff --git a/arch/i386/kernel/cpu/perfctr-watchdog.c b/arch/i386/kernel/cpu/perfctr-watchdog.c index 4be488e73be..93fecd4b03d 100644 --- a/arch/i386/kernel/cpu/perfctr-watchdog.c +++ b/arch/i386/kernel/cpu/perfctr-watchdog.c @@ -263,8 +263,8 @@ static int setup_k7_watchdog(unsigned nmi_hz) unsigned int evntsel; struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - perfctr_msr = MSR_K7_PERFCTR0; - evntsel_msr = MSR_K7_EVNTSEL0; + perfctr_msr = wd_ops->perfctr; + evntsel_msr = wd_ops->evntsel; wrmsrl(perfctr_msr, 0UL); @@ -343,8 +343,8 @@ static int setup_p6_watchdog(unsigned nmi_hz) unsigned int evntsel; struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - perfctr_msr = MSR_P6_PERFCTR0; - evntsel_msr = MSR_P6_EVNTSEL0; + perfctr_msr = wd_ops->perfctr; + evntsel_msr = wd_ops->evntsel; /* KVM doesn't implement this MSR */ if (wrmsr_safe(perfctr_msr, 0, 0) < 0) @@ -569,8 +569,8 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz) (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) return 0; - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR1; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL1; + perfctr_msr = wd_ops->perfctr; + evntsel_msr = wd_ops->evntsel; wrmsrl(perfctr_msr, 0UL); @@ -605,6 +605,16 @@ static struct wd_ops intel_arch_wd_ops = { .evntsel = MSR_ARCH_PERFMON_EVENTSEL1, }; +static struct wd_ops coreduo_wd_ops = { + .reserve = single_msr_reserve, + .unreserve = single_msr_unreserve, + .setup = setup_intel_arch_watchdog, + .rearm = p6_rearm, + .stop = single_msr_stop_watchdog, + .perfctr = MSR_ARCH_PERFMON_PERFCTR0, + .evntsel = MSR_ARCH_PERFMON_EVENTSEL0, +}; + static void probe_nmi_watchdog(void) { switch (boot_cpu_data.x86_vendor) { @@ -615,6 +625,12 @@ static void probe_nmi_watchdog(void) wd_ops = &k7_wd_ops; break; case X86_VENDOR_INTEL: + /* Work around Core Duo (Yonah) errata AE49 where perfctr1 + doesn't have a working enable bit. */ + if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 14) { + wd_ops = &coreduo_wd_ops; + break; + } if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { wd_ops = &intel_arch_wd_ops; break; diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 8c1c965eb2a..c7227e2180f 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -115,12 +115,12 @@ static int __init check_nmi_watchdog(void) atomic_dec(&nmi_active); } } + endflag = 1; if (!atomic_read(&nmi_active)) { kfree(prev_nmi_count); atomic_set(&nmi_active, -1); return -1; } - endflag = 1; printk("OK.\n"); /* now that we know it works we can reduce NMI frequency to diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 0c8f00e69c4..7c1b92522e9 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -274,7 +274,6 @@ static void clear_singlestep(struct task_struct *child) void ptrace_disable(struct task_struct *child) { clear_singlestep(child); - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); } diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index cfffe3dd9e8..47b0bef335b 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -100,36 +100,45 @@ asmlinkage void machine_check(void); int kstack_depth_to_print = 24; static unsigned int code_bytes = 64; -static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) +static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size) { return p > (void *)tinfo && - p < (void *)tinfo + THREAD_SIZE - 3; + p <= (void *)tinfo + THREAD_SIZE - size; } +/* The form of the top of the frame on the stack */ +struct stack_frame { + struct stack_frame *next_frame; + unsigned long return_address; +}; + static inline unsigned long print_context_stack(struct thread_info *tinfo, unsigned long *stack, unsigned long ebp, struct stacktrace_ops *ops, void *data) { - unsigned long addr; - #ifdef CONFIG_FRAME_POINTER - while (valid_stack_ptr(tinfo, (void *)ebp)) { - unsigned long new_ebp; - addr = *(unsigned long *)(ebp + 4); + struct stack_frame *frame = (struct stack_frame *)ebp; + while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) { + struct stack_frame *next; + unsigned long addr; + + addr = frame->return_address; ops->address(data, addr); /* * break out of recursive entries (such as * end_of_stack_stop_unwind_function). Also, * we can never allow a frame pointer to * move downwards! - */ - new_ebp = *(unsigned long *)ebp; - if (new_ebp <= ebp) + */ + next = frame->next_frame; + if (next <= frame) break; - ebp = new_ebp; + frame = next; } #else - while (valid_stack_ptr(tinfo, stack)) { + while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) { + unsigned long addr; + addr = *stack++; if (__kernel_text_address(addr)) ops->address(data, addr); diff --git a/arch/i386/mach-generic/Makefile b/arch/i386/mach-generic/Makefile index 77fbc9f64fb..6914485c0d8 100644 --- a/arch/i386/mach-generic/Makefile +++ b/arch/i386/mach-generic/Makefile @@ -2,6 +2,6 @@ # Makefile for the generic architecture # -EXTRA_CFLAGS += -I../kernel +EXTRA_CFLAGS := -Iarch/i386/kernel obj-y := probe.o summit.o bigsmp.o es7000.o default.o ../mach-es7000/ diff --git a/arch/i386/mach-voyager/Makefile b/arch/i386/mach-voyager/Makefile index f24d2965131..33b74cf0dd2 100644 --- a/arch/i386/mach-voyager/Makefile +++ b/arch/i386/mach-voyager/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -EXTRA_CFLAGS += -I../kernel +EXTRA_CFLAGS := -Iarch/i386/kernel obj-y := setup.o voyager_basic.o voyager_thread.o obj-$(CONFIG_SMP) += voyager_smp.o voyager_cat.o diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index ad8d86cc683..1c3bf95f735 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c @@ -34,17 +34,16 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ pagefault_disable(); - idx = type + KM_TYPE_NR*smp_processor_id(); - BUG_ON(!pte_none(*(kmap_pte-idx))); - if (!PageHighMem(page)) return page_address(page); + idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + BUG_ON(!pte_none(*(kmap_pte-idx))); set_pte(kmap_pte-idx, mk_pte(page, prot)); arch_flush_lazy_mmu_mode(); - return (void*) vaddr; + return (void *)vaddr; } void *kmap_atomic(struct page *page, enum km_type type) diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index efdf95ac803..6c06d9c0488 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c @@ -367,7 +367,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, return -ENOMEM; if (flags & MAP_FIXED) { - if (prepare_hugepage_range(addr, len, pgoff)) + if (prepare_hugepage_range(addr, len)) return -EINVAL; return addr; } diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 665db063a40..8434f2323b8 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -550,6 +550,7 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH9_3: case PCI_DEVICE_ID_INTEL_ICH9_4: case PCI_DEVICE_ID_INTEL_ICH9_5: + case PCI_DEVICE_ID_INTEL_TOLAPAI_0: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c index 5f5193401be..10ac8c316c4 100644 --- a/arch/i386/pci/pcbios.c +++ b/arch/i386/pci/pcbios.c @@ -412,7 +412,7 @@ struct irq_routing_options { u16 segment; } __attribute__((packed)); -struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void) +struct irq_routing_table * pcibios_get_irq_routing_table(void) { struct irq_routing_options opt; struct irq_routing_table *rt = NULL; |