diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-04 17:42:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-04 17:42:58 -0400 |
commit | 3a143125ddc4e2e0ca1e67fb4bedd45c36e59cc7 (patch) | |
tree | 0e5bc6fcc66b4cbfef909646b8a6b8f7f9d08956 /arch | |
parent | a1aa758d0019f2ac4ea558b3987a07c12fa19f61 (diff) | |
parent | 5761d64b277c287a7520b868c32d656ef03374b4 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86:
x86: revert assign IRQs to hpet timer
x86: tsc prevent time going backwards
xen: Clear PG_pinned in release_{pt,pd}()
xen: Do not pin/unpin PMD pages
xen: refactor xen_{alloc,release}_{pt,pd}()
x86, agpgart: scary messages are fortunately obsolete
xen: fix grant table bug
x86: fix breakage of vSMP irq operations
x86: print message if nmi_watchdog=2 cannot be enabled
x86: fix nmi_watchdog=2 on Pentium-D CPUs
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/perfctr-watchdog.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/hpet.c | 9 | ||||
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/tsc_32.c | 15 | ||||
-rw-r--r-- | arch/x86/kernel/tsc_64.c | 23 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 29 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 7 | ||||
-rw-r--r-- | arch/x86/xen/mmu.h | 7 |
8 files changed, 76 insertions, 31 deletions
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index 9b838324b818..b943e10ad814 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c | |||
@@ -652,9 +652,6 @@ static void probe_nmi_watchdog(void) | |||
652 | wd_ops = &p6_wd_ops; | 652 | wd_ops = &p6_wd_ops; |
653 | break; | 653 | break; |
654 | case 15: | 654 | case 15: |
655 | if (boot_cpu_data.x86_model > 0x4) | ||
656 | return; | ||
657 | |||
658 | wd_ops = &p4_wd_ops; | 655 | wd_ops = &p4_wd_ops; |
659 | break; | 656 | break; |
660 | default: | 657 | default: |
@@ -670,8 +667,10 @@ int lapic_watchdog_init(unsigned nmi_hz) | |||
670 | { | 667 | { |
671 | if (!wd_ops) { | 668 | if (!wd_ops) { |
672 | probe_nmi_watchdog(); | 669 | probe_nmi_watchdog(); |
673 | if (!wd_ops) | 670 | if (!wd_ops) { |
671 | printk(KERN_INFO "NMI watchdog: CPU not supported\n"); | ||
674 | return -1; | 672 | return -1; |
673 | } | ||
675 | 674 | ||
676 | if (!wd_ops->reserve()) { | 675 | if (!wd_ops->reserve()) { |
677 | printk(KERN_ERR | 676 | printk(KERN_ERR |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 235fd6c77504..36652ea1a265 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -133,13 +133,16 @@ static void hpet_reserve_platform_timers(unsigned long id) | |||
133 | #ifdef CONFIG_HPET_EMULATE_RTC | 133 | #ifdef CONFIG_HPET_EMULATE_RTC |
134 | hpet_reserve_timer(&hd, 1); | 134 | hpet_reserve_timer(&hd, 1); |
135 | #endif | 135 | #endif |
136 | |||
136 | hd.hd_irq[0] = HPET_LEGACY_8254; | 137 | hd.hd_irq[0] = HPET_LEGACY_8254; |
137 | hd.hd_irq[1] = HPET_LEGACY_RTC; | 138 | hd.hd_irq[1] = HPET_LEGACY_RTC; |
138 | 139 | ||
139 | for (i = 2; i < nrtimers; timer++, i++) | 140 | for (i = 2; i < nrtimers; timer++, i++) |
140 | hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >> | 141 | hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >> |
141 | Tn_INT_ROUTE_CNF_SHIFT; | 142 | Tn_INT_ROUTE_CNF_SHIFT; |
143 | |||
142 | hpet_alloc(&hd); | 144 | hpet_alloc(&hd); |
145 | |||
143 | } | 146 | } |
144 | #else | 147 | #else |
145 | static void hpet_reserve_platform_timers(unsigned long id) { } | 148 | static void hpet_reserve_platform_timers(unsigned long id) { } |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index faf3229f8fb3..700e4647dd30 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -615,8 +615,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | |||
615 | 615 | ||
616 | nommu: | 616 | nommu: |
617 | /* Should not happen anymore */ | 617 | /* Should not happen anymore */ |
618 | printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n" | 618 | printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n" |
619 | KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction.\n"); | 619 | KERN_WARNING "falling back to iommu=soft.\n"); |
620 | return -1; | 620 | return -1; |
621 | } | 621 | } |
622 | 622 | ||
@@ -692,9 +692,9 @@ void __init gart_iommu_init(void) | |||
692 | !gart_iommu_aperture || | 692 | !gart_iommu_aperture || |
693 | (no_agp && init_k8_gatt(&info) < 0)) { | 693 | (no_agp && init_k8_gatt(&info) < 0)) { |
694 | if (end_pfn > MAX_DMA32_PFN) { | 694 | if (end_pfn > MAX_DMA32_PFN) { |
695 | printk(KERN_ERR "WARNING more than 4GB of memory " | 695 | printk(KERN_WARNING "More than 4GB of memory " |
696 | "but GART IOMMU not available.\n" | 696 | "but GART IOMMU not available.\n" |
697 | KERN_ERR "WARNING 32bit PCI may malfunction.\n"); | 697 | KERN_WARNING "falling back to iommu=soft.\n"); |
698 | } | 698 | } |
699 | return; | 699 | return; |
700 | } | 700 | } |
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index f14cfd9d1f94..d7498b34c8e9 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c | |||
@@ -287,14 +287,27 @@ core_initcall(cpufreq_tsc); | |||
287 | /* clock source code */ | 287 | /* clock source code */ |
288 | 288 | ||
289 | static unsigned long current_tsc_khz = 0; | 289 | static unsigned long current_tsc_khz = 0; |
290 | static struct clocksource clocksource_tsc; | ||
290 | 291 | ||
292 | /* | ||
293 | * We compare the TSC to the cycle_last value in the clocksource | ||
294 | * structure to avoid a nasty time-warp issue. This can be observed in | ||
295 | * a very small window right after one CPU updated cycle_last under | ||
296 | * xtime lock and the other CPU reads a TSC value which is smaller | ||
297 | * than the cycle_last reference value due to a TSC which is slighty | ||
298 | * behind. This delta is nowhere else observable, but in that case it | ||
299 | * results in a forward time jump in the range of hours due to the | ||
300 | * unsigned delta calculation of the time keeping core code, which is | ||
301 | * necessary to support wrapping clocksources like pm timer. | ||
302 | */ | ||
291 | static cycle_t read_tsc(void) | 303 | static cycle_t read_tsc(void) |
292 | { | 304 | { |
293 | cycle_t ret; | 305 | cycle_t ret; |
294 | 306 | ||
295 | rdtscll(ret); | 307 | rdtscll(ret); |
296 | 308 | ||
297 | return ret; | 309 | return ret >= clocksource_tsc.cycle_last ? |
310 | ret : clocksource_tsc.cycle_last; | ||
298 | } | 311 | } |
299 | 312 | ||
300 | static struct clocksource clocksource_tsc = { | 313 | static struct clocksource clocksource_tsc = { |
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c index 947554ddabb6..01fc9f0c39e2 100644 --- a/arch/x86/kernel/tsc_64.c +++ b/arch/x86/kernel/tsc_64.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <asm/hpet.h> | 11 | #include <asm/hpet.h> |
12 | #include <asm/timex.h> | 12 | #include <asm/timex.h> |
13 | #include <asm/timer.h> | 13 | #include <asm/timer.h> |
14 | #include <asm/vgtod.h> | ||
14 | 15 | ||
15 | static int notsc __initdata = 0; | 16 | static int notsc __initdata = 0; |
16 | 17 | ||
@@ -290,18 +291,34 @@ int __init notsc_setup(char *s) | |||
290 | 291 | ||
291 | __setup("notsc", notsc_setup); | 292 | __setup("notsc", notsc_setup); |
292 | 293 | ||
294 | static struct clocksource clocksource_tsc; | ||
293 | 295 | ||
294 | /* clock source code: */ | 296 | /* |
297 | * We compare the TSC to the cycle_last value in the clocksource | ||
298 | * structure to avoid a nasty time-warp. This can be observed in a | ||
299 | * very small window right after one CPU updated cycle_last under | ||
300 | * xtime/vsyscall_gtod lock and the other CPU reads a TSC value which | ||
301 | * is smaller than the cycle_last reference value due to a TSC which | ||
302 | * is slighty behind. This delta is nowhere else observable, but in | ||
303 | * that case it results in a forward time jump in the range of hours | ||
304 | * due to the unsigned delta calculation of the time keeping core | ||
305 | * code, which is necessary to support wrapping clocksources like pm | ||
306 | * timer. | ||
307 | */ | ||
295 | static cycle_t read_tsc(void) | 308 | static cycle_t read_tsc(void) |
296 | { | 309 | { |
297 | cycle_t ret = (cycle_t)get_cycles(); | 310 | cycle_t ret = (cycle_t)get_cycles(); |
298 | return ret; | 311 | |
312 | return ret >= clocksource_tsc.cycle_last ? | ||
313 | ret : clocksource_tsc.cycle_last; | ||
299 | } | 314 | } |
300 | 315 | ||
301 | static cycle_t __vsyscall_fn vread_tsc(void) | 316 | static cycle_t __vsyscall_fn vread_tsc(void) |
302 | { | 317 | { |
303 | cycle_t ret = (cycle_t)vget_cycles(); | 318 | cycle_t ret = (cycle_t)vget_cycles(); |
304 | return ret; | 319 | |
320 | return ret >= __vsyscall_gtod_data.clock.cycle_last ? | ||
321 | ret : __vsyscall_gtod_data.clock.cycle_last; | ||
305 | } | 322 | } |
306 | 323 | ||
307 | static struct clocksource clocksource_tsc = { | 324 | static struct clocksource clocksource_tsc = { |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index de4e6f05840b..27ee26aedf94 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -667,10 +667,10 @@ static void xen_release_pt_init(u32 pfn) | |||
667 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); | 667 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); |
668 | } | 668 | } |
669 | 669 | ||
670 | static void pin_pagetable_pfn(unsigned level, unsigned long pfn) | 670 | static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) |
671 | { | 671 | { |
672 | struct mmuext_op op; | 672 | struct mmuext_op op; |
673 | op.cmd = level; | 673 | op.cmd = cmd; |
674 | op.arg1.mfn = pfn_to_mfn(pfn); | 674 | op.arg1.mfn = pfn_to_mfn(pfn); |
675 | if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) | 675 | if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) |
676 | BUG(); | 676 | BUG(); |
@@ -687,7 +687,8 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level) | |||
687 | 687 | ||
688 | if (!PageHighMem(page)) { | 688 | if (!PageHighMem(page)) { |
689 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); | 689 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); |
690 | pin_pagetable_pfn(level, pfn); | 690 | if (level == PT_PTE) |
691 | pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); | ||
691 | } else | 692 | } else |
692 | /* make sure there are no stray mappings of | 693 | /* make sure there are no stray mappings of |
693 | this page */ | 694 | this page */ |
@@ -697,27 +698,39 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level) | |||
697 | 698 | ||
698 | static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) | 699 | static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) |
699 | { | 700 | { |
700 | xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L1_TABLE); | 701 | xen_alloc_ptpage(mm, pfn, PT_PTE); |
701 | } | 702 | } |
702 | 703 | ||
703 | static void xen_alloc_pd(struct mm_struct *mm, u32 pfn) | 704 | static void xen_alloc_pd(struct mm_struct *mm, u32 pfn) |
704 | { | 705 | { |
705 | xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L2_TABLE); | 706 | xen_alloc_ptpage(mm, pfn, PT_PMD); |
706 | } | 707 | } |
707 | 708 | ||
708 | /* This should never happen until we're OK to use struct page */ | 709 | /* This should never happen until we're OK to use struct page */ |
709 | static void xen_release_pt(u32 pfn) | 710 | static void xen_release_ptpage(u32 pfn, unsigned level) |
710 | { | 711 | { |
711 | struct page *page = pfn_to_page(pfn); | 712 | struct page *page = pfn_to_page(pfn); |
712 | 713 | ||
713 | if (PagePinned(page)) { | 714 | if (PagePinned(page)) { |
714 | if (!PageHighMem(page)) { | 715 | if (!PageHighMem(page)) { |
715 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); | 716 | if (level == PT_PTE) |
717 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); | ||
716 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); | 718 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); |
717 | } | 719 | } |
720 | ClearPagePinned(page); | ||
718 | } | 721 | } |
719 | } | 722 | } |
720 | 723 | ||
724 | static void xen_release_pt(u32 pfn) | ||
725 | { | ||
726 | xen_release_ptpage(pfn, PT_PTE); | ||
727 | } | ||
728 | |||
729 | static void xen_release_pd(u32 pfn) | ||
730 | { | ||
731 | xen_release_ptpage(pfn, PT_PMD); | ||
732 | } | ||
733 | |||
721 | #ifdef CONFIG_HIGHPTE | 734 | #ifdef CONFIG_HIGHPTE |
722 | static void *xen_kmap_atomic_pte(struct page *page, enum km_type type) | 735 | static void *xen_kmap_atomic_pte(struct page *page, enum km_type type) |
723 | { | 736 | { |
@@ -838,7 +851,7 @@ static __init void xen_pagetable_setup_done(pgd_t *base) | |||
838 | pv_mmu_ops.alloc_pt = xen_alloc_pt; | 851 | pv_mmu_ops.alloc_pt = xen_alloc_pt; |
839 | pv_mmu_ops.alloc_pd = xen_alloc_pd; | 852 | pv_mmu_ops.alloc_pd = xen_alloc_pd; |
840 | pv_mmu_ops.release_pt = xen_release_pt; | 853 | pv_mmu_ops.release_pt = xen_release_pt; |
841 | pv_mmu_ops.release_pd = xen_release_pt; | 854 | pv_mmu_ops.release_pd = xen_release_pd; |
842 | pv_mmu_ops.set_pte = xen_set_pte; | 855 | pv_mmu_ops.set_pte = xen_set_pte; |
843 | 856 | ||
844 | setup_shared_info(); | 857 | setup_shared_info(); |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 0144395448ae..2a054ef2a3da 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -310,13 +310,6 @@ pgd_t xen_make_pgd(unsigned long pgd) | |||
310 | } | 310 | } |
311 | #endif /* CONFIG_X86_PAE */ | 311 | #endif /* CONFIG_X86_PAE */ |
312 | 312 | ||
313 | enum pt_level { | ||
314 | PT_PGD, | ||
315 | PT_PUD, | ||
316 | PT_PMD, | ||
317 | PT_PTE | ||
318 | }; | ||
319 | |||
320 | /* | 313 | /* |
321 | (Yet another) pagetable walker. This one is intended for pinning a | 314 | (Yet another) pagetable walker. This one is intended for pinning a |
322 | pagetable. This means that it walks a pagetable and calls the | 315 | pagetable. This means that it walks a pagetable and calls the |
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h index c9ff27f3ac3a..b5e189b1519d 100644 --- a/arch/x86/xen/mmu.h +++ b/arch/x86/xen/mmu.h | |||
@@ -3,6 +3,13 @@ | |||
3 | #include <linux/linkage.h> | 3 | #include <linux/linkage.h> |
4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
5 | 5 | ||
6 | enum pt_level { | ||
7 | PT_PGD, | ||
8 | PT_PUD, | ||
9 | PT_PMD, | ||
10 | PT_PTE | ||
11 | }; | ||
12 | |||
6 | /* | 13 | /* |
7 | * Page-directory addresses above 4GB do not fit into architectural %cr3. | 14 | * Page-directory addresses above 4GB do not fit into architectural %cr3. |
8 | * When accessing %cr3, or equivalent field in vcpu_guest_context, guests | 15 | * When accessing %cr3, or equivalent field in vcpu_guest_context, guests |