Index: linux/arch/x86_64/defconfig diff -u linux/arch/x86_64/defconfig:1.23 linux/arch/x86_64/defconfig:1.25 --- linux/arch/x86_64/defconfig:1.23 Thu Jul 4 00:54:02 2002 +++ linux/arch/x86_64/defconfig Tue Jul 16 09:33:45 2002 @@ -495,7 +495,7 @@ # CONFIG_AMD_RNG is not set # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set -# CONFIG_RTC is not set +CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -556,7 +556,7 @@ # CONFIG_JFFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set Index: linux/arch/x86_64/vmlinux.lds diff -u linux/arch/x86_64/vmlinux.lds:1.18 linux/arch/x86_64/vmlinux.lds:1.19 --- linux/arch/x86_64/vmlinux.lds:1.18 Thu Jun 6 16:51:21 2002 +++ linux/arch/x86_64/vmlinux.lds Tue Jul 16 09:53:38 2002 @@ -54,9 +54,9 @@ . = ALIGN(64); .vxtime_sequence : AT ((LOADADDR(.vsyscall_0) + SIZEOF(.vsyscall_0) + 63) & ~(63)) { *(.vxtime_sequence) } vxtime_sequence = LOADADDR(.vxtime_sequence); - .hpet : AT (LOADADDR(.vxtime_sequence) + 16) { *(.hpet) } + .hpet : AT (LOADADDR(.vxtime_sequence) + SIZEOF(.vxtime_sequence)) { *(.hpet) } hpet = LOADADDR(.hpet); - .wall_jiffies : AT (LOADADDR(.hpet) + 32) { *(.wall_jiffies) } + .wall_jiffies : AT (LOADADDR(.hpet) + SIZEOF(.hpet)) { *(.wall_jiffies) } wall_jiffies = LOADADDR(.wall_jiffies); .sys_tz : AT (LOADADDR(.wall_jiffies) + SIZEOF(.wall_jiffies)) { *(.sys_tz) } sys_tz = LOADADDR(.sys_tz); Index: linux/arch/x86_64/ia32/ia32_ioctl.c diff -u linux/arch/x86_64/ia32/ia32_ioctl.c:1.17 linux/arch/x86_64/ia32/ia32_ioctl.c:1.19 --- linux/arch/x86_64/ia32/ia32_ioctl.c:1.17 Wed Jul 3 09:13:19 2002 +++ linux/arch/x86_64/ia32/ia32_ioctl.c Fri Jul 5 01:59:27 2002 @@ -1,4 +1,4 @@ -/* $Id: ia32_ioctl.c,v 1.17 2002/07/03 15:13:19 ak Exp $ +/* $Id: ia32_ioctl.c,v 1.19 2002/07/05 07:59:27 ak Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -3135,6 +3136,43 @@ return err; } +struct dirent32 { + unsigned int d_ino; + __kernel_off_t32 d_off; + unsigned short d_reclen; + char d_name[256]; /* We must not include limits.h! */ +}; + +#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct dirent32 [2]) +#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct dirent32 [2]) + +static int put_dirent32(struct dirent *src, struct dirent32 *dst) +{ + int ret; + ret = put_user(src->d_ino, &dst->d_ino); + ret |= __put_user(src->d_off, &dst->d_off); + ret |= __put_user(src->d_reclen, &dst->d_reclen); + if (__copy_to_user(&dst->d_name, src->d_name, src->d_reclen)) + ret |= -EFAULT; + return ret; +} + +static int vfat_ioctl32(unsigned fd, unsigned cmd, void *ptr) +{ + int ret; + mm_segment_t oldfs = get_fs(); + struct dirent d[2]; + + set_fs(KERNEL_DS); + ret = sys_ioctl(fd,cmd,(unsigned long)&d); + set_fs(oldfs); + if (!ret) { + ret |= put_dirent32(&d[0], (struct dirent32 *)ptr); + ret |= put_dirent32(&d[1], ((struct dirent32 *)ptr) + 1); + } + return ret; +} + struct ioctl_trans { unsigned long cmd; int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); @@ -3749,7 +3787,8 @@ COMPATIBLE_IOCTL(RTC_WKALM_SET); COMPATIBLE_IOCTL(RTC_WKALM_RD); #endif -COMPATIBLE_IOCTL(REISERFS_IOC_UNPACK); +#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int) +COMPATIBLE_IOCTL(REISERFS_IOC_UNPACK32); /* serial driver */ HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl); HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl); @@ -3916,6 +3955,8 @@ HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma); HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx); #endif /* DRM */ +HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32); +HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32); IOCTL_TABLE_END #define IOCTL_HASHSIZE 256 Index: linux/arch/x86_64/kernel/mpparse.c diff -u linux/arch/x86_64/kernel/mpparse.c:1.10 linux/arch/x86_64/kernel/mpparse.c:1.11 --- linux/arch/x86_64/kernel/mpparse.c:1.10 Thu Apr 25 12:37:47 2002 +++ linux/arch/x86_64/kernel/mpparse.c Sun Jul 14 10:13:51 2002 @@ -588,11 +588,13 @@ * trustworthy, simply because the SMP table may have been * stomped on during early boot. These loaders are buggy and * should be fixed. + * + * MP1.4 SPEC states to only scan first 1K of 4K EBDA. */ address = *(unsigned short *)phys_to_virt(0x40E); address <<= 4; - smp_scan_config(address, 0x1000); + smp_scan_config(address, 0x400); if (smp_found_config) printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.kernel.org if you experience SMP problems!\n"); } Index: linux/arch/x86_64/kernel/mtrr.c diff -u linux/arch/x86_64/kernel/mtrr.c:1.15 linux/arch/x86_64/kernel/mtrr.c:1.18 --- linux/arch/x86_64/kernel/mtrr.c:1.15 Tue Jun 18 23:14:47 2002 +++ linux/arch/x86_64/kernel/mtrr.c Tue Jul 16 07:11:51 2002 @@ -25,6 +25,9 @@ v2.01 June 2002 Dave Jones Removal of redundant abstraction layer. 64-bit fixes. + v2.02 July 2002 Dave Jones + Fix gentry inconsistencies between kernel/userspace. + More casts to clean up warnings. */ #include @@ -50,6 +53,7 @@ #include #include #include +#include #include #include @@ -64,7 +68,7 @@ #include #include -#define MTRR_VERSION "2.01 (20020605)" +#define MTRR_VERSION "2.02 (20020716)" #define TRUE 1 #define FALSE 0 @@ -106,7 +110,7 @@ struct set_mtrr_context { u32 deftype_lo; u32 deftype_hi; - u64 flags; + unsigned long flags; u64 cr4val; }; @@ -596,11 +600,22 @@ if (base + size < 0x100) { printk (KERN_WARNING - "mtrr: cannot set region below 1 MiB (0x%lx000,0x%x000)\n", + "mtrr: cannot set region below 1 MiB (0x%Lx000,0x%x000)\n", base, size); return -EINVAL; } +#if defined(__x86_64__) && defined(CONFIG_AGP) + { + agp_kern_info info; + if (type != MTRR_TYPE_UNCACHABLE && agp_copy_info(&info) >= 0 && + base<= info.aper_base && + (base<= + info.aper_base+info.aper_size*1024*1024) + printk(KERN_INFO "%s[%d] setting conflicting mtrr into agp aperture\n",current->comm,current->pid); + } +#endif + /* Check upper bits of base and last are equal and lower bits are 0 for base and 1 for last */ last = base + size - 1; @@ -609,7 +624,7 @@ if (lbase != last) { printk (KERN_WARNING - "mtrr: base(0x%lx000) is not aligned on a size(0x%x000) boundary\n", + "mtrr: base(0x%Lx000) is not aligned on a size(0x%x000) boundary\n", base, size); return -EINVAL; } @@ -625,9 +640,14 @@ "mtrr: your processor doesn't support write-combining\n"); return -ENOSYS; } + + if (base & size_or_mask) { + printk (KERN_WARNING "mtrr: base exceeds the MTRR width\n"); + return -EINVAL; + } - if (base & size_or_mask || size & size_or_mask) { - printk ("mtrr: base or size exceeds the MTRR width\n"); + if (size & size_or_mask) { + printk (KERN_WARNING "mtrr: size exceeds the MTRR width\n"); return -EINVAL; } @@ -646,8 +666,8 @@ if ((base < lbase) || (base + size > lbase + lsize)) { up (&mtrr_lock); printk (KERN_WARNING - "mtrr: 0x%lx000,0x%x000 overlaps existing" - " 0x%lx000,0x%x000\n", base, size, lbase, lsize); + "mtrr: 0x%Lx000,0x%x000 overlaps existing" + " 0x%Lx000,0x%x000\n", base, size, lbase, lsize); return -EINVAL; } /* New region is enclosed by an existing region */ @@ -656,7 +676,7 @@ continue; up (&mtrr_lock); printk - ("mtrr: type mismatch for %lx000,%x000 old: %s new: %s\n", + ("mtrr: type mismatch for %Lx000,%x000 old: %s new: %s\n", base, size, attrib_to_str (ltype), attrib_to_str (type)); @@ -720,7 +740,7 @@ { if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { printk ("mtrr: size and base must be multiples of 4 kiB\n"); - printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base); + printk ("mtrr: size: 0x%x base: 0x%Lx\n", size, base); return -EINVAL; } return mtrr_add_page (base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, @@ -763,7 +783,7 @@ } if (reg < 0) { up (&mtrr_lock); - printk ("mtrr: no MTRR for %lx000,%x000 found\n", base, size); + printk ("mtrr: no MTRR for %Lx000,%x000 found\n", base, size); return -EINVAL; } } @@ -814,7 +834,7 @@ { if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { printk ("mtrr: size and base must be multiples of 4 kiB\n"); - printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base); + printk ("mtrr: size: 0x%x base: 0x%Lx\n", size, base); return -EINVAL; } return mtrr_del_page (reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); @@ -844,7 +864,7 @@ if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { printk ("mtrr: size and base must be multiples of 4 kiB\n"); - printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base); + printk ("mtrr: size: 0x%x base: 0x%Lx\n", size, base); return -EINVAL; } base >>= PAGE_SHIFT; @@ -869,7 +889,7 @@ if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { printk ("mtrr: size and base must be multiples of 4 kiB\n"); - printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base); + printk ("mtrr: size: 0x%x base: 0x%Lx\n", size, base); return -EINVAL; } base >>= PAGE_SHIFT; @@ -961,7 +981,7 @@ if ((base & 0xfff) || (size & 0xfff)) { printk ("mtrr: size and base must be multiples of 4 kiB\n"); - printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base); + printk ("mtrr: size: 0x%x base: 0x%Lx\n", size, base); return -EINVAL; } @@ -1048,7 +1068,7 @@ return -EFAULT; if (gentry.regnum >= get_num_var_ranges ()) return -EINVAL; - get_mtrr (gentry.regnum, &gentry.base, &gentry.size, &type); + get_mtrr (gentry.regnum, (u64*) &gentry.base, &gentry.size, &type); /* Hide entries that go above 4GB */ if (gentry.base + gentry.size > 0x100000 @@ -1109,7 +1129,7 @@ return -EFAULT; if (gentry.regnum >= get_num_var_ranges ()) return -EINVAL; - get_mtrr (gentry.regnum, &gentry.base, &gentry.size, &type); + get_mtrr (gentry.regnum, (u64*) &gentry.base, &gentry.size, &type); gentry.type = type; if (copy_to_user ((void *) arg, &gentry, sizeof gentry)) @@ -1182,8 +1202,8 @@ size >>= 20 - PAGE_SHIFT; } sprintf (ascii_buffer + ascii_buf_bytes, - "reg%02i: base=0x%05lx000 (%4liMB), size=%4i%cB: %s, count=%d\n", - i, base, base >> (20 - PAGE_SHIFT), size, factor, + "reg%02i: base=0x%05Lx000 (%4iMB), size=%4i%cB: %s, count=%d\n", + i, base, (u32) base >> (20 - PAGE_SHIFT), size, factor, attrib_to_str (type), usage_table[i]); ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes); } Index: linux/arch/x86_64/kernel/pci-dma.c diff -u linux/arch/x86_64/kernel/pci-dma.c:1.5 linux/arch/x86_64/kernel/pci-dma.c:1.7 --- linux/arch/x86_64/kernel/pci-dma.c:1.5 Wed Jul 3 23:16:08 2002 +++ linux/arch/x86_64/kernel/pci-dma.c Sat Jul 6 13:15:05 2002 @@ -28,25 +28,21 @@ { int i; - if (direction == PCI_DMA_NONE) - out_of_line_bug(); + BUG_ON(direction == PCI_DMA_NONE); /* * temporary 2.4 hack */ for (i = 0; i < nents; i++ ) { struct scatterlist *s = &sg[i]; - if (s->address && s->page) - out_of_line_bug(); - else if (!s->address && !s->page) - out_of_line_bug(); - - if (s->address) - s->dma_address = pci_map_single(hwdev, s->address, - s->length, 0); - else - s->dma_address = pci_map_page(hwdev, s->page, - s->offset, s->length,0); + if (s->address) { + BUG_ON(s->page || s->offset); + s->dma_address = pci_map_single(hwdev, s->address, s->length, 0); + } else if (s->page) { + s->dma_address = pci_map_page(hwdev, s->page, s->offset, + s->length,0); + } else + BUG(); } return nents; } @@ -55,16 +51,14 @@ * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -void pci_unmap_sg(struct pci_dev *dev, struct scatterlist *sg, - int nents, int dir) +void pci_unmap_sg(struct pci_dev *dev, struct scatterlist *sg, + int nents, int dir) { int i; for (i = 0; i < nents; i++) { struct scatterlist *s = &sg[i]; - if (s->address) - pci_unmap_single(dev, (dma_addr_t)virt_to_bus(s->address), - s->length, dir); - else - pci_unmap_page(dev, s->page, s->length, dir); + BUG_ON(s->address == NULL && s->page == NULL); + BUG_ON(s->dma_address == 0); + pci_unmap_single(dev, s->dma_address, s->length, dir); } } Index: linux/arch/x86_64/kernel/pci-gart.c diff -u linux/arch/x86_64/kernel/pci-gart.c:1.1 linux/arch/x86_64/kernel/pci-gart.c:1.8 --- linux/arch/x86_64/kernel/pci-gart.c:1.1 Wed Jul 3 23:16:08 2002 +++ linux/arch/x86_64/kernel/pci-gart.c Tue Jul 16 09:30:04 2002 @@ -8,24 +8,15 @@ * See Documentation/DMA-mapping.txt for the interface specification. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: pci-gart.c,v 1.1 2002/07/04 05:16:08 ak Exp $ + * $Id: pci-gart.c,v 1.8 2002/07/16 15:30:04 ak Exp $ */ /* - * TODO: + * Notebook: agpgart_be check if the simple reservation scheme is enough. -tocheck: - full flushing protocol from the spec needed? - handle machine check error for invalid GART entries properly (can be turned - on/off with a northbridge bit) - coherent memory would in theory need to flush caches on all cpus. unfortunately - that cannot be done from interrupt context. this is especially a problem with - preemptible SMP kernels. - on 2.5 need more preempt disable - possible future tuning: fast path for sg streaming mappings more intelligent flush strategy - flush only a single NB? @@ -34,6 +25,7 @@ */ #include +#include #include #include #include @@ -47,9 +39,6 @@ #include #include "pci-x86_64.h" -/* For now force the IOMMU for testing */ -#define FORCE_IOMMU 1 /* debugging */ - extern unsigned long start_pfn, end_pfn; unsigned long iommu_bus_base; /* GART remapping area (physical) */ @@ -60,6 +49,7 @@ static int no_iommu; static int no_agp; +static int force_mmu = 1; /* Allocation bitmap for the remapping area */ static spinlock_t iommu_bitmap_lock = SPIN_LOCK_UNLOCKED; @@ -82,10 +72,6 @@ #define EMERGENCY_PAGES 32 /* = 128KB */ -#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) -#error You need to fix flush_cache and write interrupt safe smp_call_function. -#endif - /* backdoor interface to AGP driver */ extern void amd_x86_64_tlbflush(void *); extern int agp_init(void); @@ -102,9 +88,9 @@ spin_lock_irqsave(&iommu_bitmap_lock, flags); - offset = find_next_zero_string(iommu_gart_bitmap, next_bit, iommu_pages, size); + offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size); if (offset == -1) - offset = find_next_zero_string(iommu_gart_bitmap, 0, next_bit, size); + offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size); if (offset != -1) { set_bit_string(iommu_gart_bitmap, offset, size); next_bit = offset+size; @@ -124,39 +110,11 @@ spin_unlock_irqrestore(&iommu_bitmap_lock, flags); } -/* - * This assumes that only the current CPU did access the single mapping. - * Should be enforceable with non preemptive kernel. - * Note this function can be called from interrupt context. - * addr is physical. - */ -static void flush_cache(unsigned long addr, int size) -{ -#if 1 - asm("wbinvd"); -#else - int i; - struct cpuinfo_x86 *cpu = &cpu_data[smp_processor_id()]; - mb(); - if (!test_bit(X86_FEATURE_CLFLSH, &cpu->x86_capability)) { - asm("wbinvd"); - return; - } - for (i = 0; i <= size; i += cpu->x86_clflush_size) - asm volatile("clflush %0" :: "m" (addr + i)); -#endif -} - static inline void flush_gart(void) { - mb(); amd_x86_64_tlbflush(NULL); } -/* - * Allocate memory that is consistent between CPU and - * All GART memory is consistent currently, but we have to flush caches as needed. - */ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) { @@ -174,20 +132,23 @@ */ order = get_order(size); memory = (void *)__get_free_pages(gfp, order); - if (memory == NULL) { - if (order == 0 || (gfp & GFP_DMA) || no_iommu) - return NULL; - /* GART can tolerate page-by-page allocation */ + if (memory == NULL) { + return NULL; } else { + int high = (unsigned long)virt_to_bus(memory) + size + >= 0xffffffff; + int mmu = high; + if (force_mmu) + mmu = 1; + if (no_iommu) { + if (high) goto error; + mmu = 0; + } memset(memory, 0, size); -#ifndef FORCE_IOMMU - if ((unsigned long)virt_to_bus(memory) + size < 0xffffffff) { + if (!mmu) { *dma_handle = virt_to_bus(memory); return memory; } -#endif - if (no_iommu) - return NULL; } iommu_page = alloc_iommu(1< 0) - atomic_inc(&virt_to_page(mem)->count); - } else { - mem = (void *)get_zeroed_page(GFP_KERNEL); - if (!mem) - goto error2; - } + void *mem = memory + i*PAGE_SIZE; + if (i > 0) + atomic_inc(&virt_to_page(mem)->count); phys_mem = virt_to_phys(mem); BUG_ON(phys_mem & ~PTE_MASK); iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem,GPTE_COHERENT); @@ -214,41 +168,29 @@ flush_gart(); *dma_handle = iommu_bus_base + (iommu_page << PAGE_SHIFT); - return __va(*dma_handle); + return memory; - error2: - while (--i >= 0) { - u64 pte = iommu_gatt_base[iommu_page+i]; - iommu_gatt_base[iommu_page+i] = 0; - free_page((unsigned long)__va(GPTE_DECODE(pte))); - } - flush_gart(); error: - if (memory) - free_pages((unsigned long)memory, order); + free_pages((unsigned long)memory, order); return NULL; } /* - * Unmap consistent memory. We must flush caches. - * This assumes that only the local CPU modified memory in the consistent area - * (XXX). The caller must ensure that the device has finished accessing the - * mapping. + * Unmap consistent memory. + * The caller must ensure that the device has finished accessing the mapping. */ void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) + void *vaddr, dma_addr_t bus) { u64 pte; int order = get_order(size); unsigned long iommu_page; - unsigned long bus = virt_to_bus(vaddr); int i; if (bus < iommu_bus_base || bus > iommu_bus_base + iommu_size) { free_pages((unsigned long)vaddr, order); return; } - flush_cache(dma_handle, size); iommu_page = (bus - iommu_bus_base) / PAGE_SIZE; for (i = 0; i < 1<dma_mask : 0xffffffff; + int high = (~mask & (unsigned long)(addr + size)) != 0; + int mmu = high; + if (force_mmu) + mmu = 1; + if (no_iommu) { + if (high) + panic("pci_map_single: high address but no IOMMU.\n"); + mmu = 0; + } + return mmu; +} + dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size,int dir) { unsigned long iommu_page; @@ -292,16 +249,10 @@ BUG_ON(dir == PCI_DMA_NONE); - if (dev != NULL) { /* assume mask==0xffffffff for dev==NULL */ -#ifndef FORCE_IOMMU - if ((~dev->dma_mask & (unsigned long)(addr + size)) == 0) - return virt_to_bus(addr); - if (no_iommu) - panic("No iommu but high physical address in pci_map_single"); -#endif - BUG_ON(~dev->dma_mask & (iommu_bus_base + iommu_size)); - } - + phys_mem = virt_to_phys(addr); + if (!need_iommu(dev, phys_mem, size)) + return phys_mem; + npages = round_up(size, PAGE_SIZE) >> PAGE_SHIFT; iommu_page = alloc_iommu(npages); @@ -310,7 +261,7 @@ return iommu_bus_base; } - phys_mem = virt_to_phys(addr) & PAGE_MASK; + phys_mem &= PAGE_MASK; for (i = 0; i < npages; i++, phys_mem += PAGE_SIZE) { BUG_ON(phys_mem & ~PTE_MASK); @@ -328,9 +279,6 @@ /* * Free a temporary PCI mapping. - * - * Assumes the CPU didn't write-allocate cachelines in the mappings. - * When it did you need to call pci_dma_sync_single to flush it. */ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) @@ -349,27 +297,8 @@ free_iommu(iommu_page, npages); } -void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, - size_t size, int direction) -{ - BUG_ON(direction == PCI_DMA_NONE); - flush_cache(dma_handle, size); -} - -void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nelems, int direction) -{ - int i; - BUG_ON(direction == PCI_DMA_NONE); - for (i = 0; i < nelems; i++) { - flush_cache(sg[i].dma_address, sg[i].length); - } -} - EXPORT_SYMBOL(pci_map_single); EXPORT_SYMBOL(pci_unmap_single); -EXPORT_SYMBOL(pci_dma_sync_single); -EXPORT_SYMBOL(pci_dma_sync_sg); static inline unsigned long check_iommu_size(unsigned long aper, unsigned long aper_size, @@ -403,6 +332,10 @@ u32 aper_size; u32 gatt_size; +#if 1 /* BIOS bug workaround for now */ + goto nommu; +#endif + aper_size = 0; for_all_nb(dev) { pci_read_config_dword(dev, 0x90, &aper_size); @@ -438,37 +371,6 @@ return -1; } -/* - * AGP part of the aperture stays uncacheable, but we use PAT for that - * now, not MTRRs. Add it to the kernel mapping if needed. - * The IOMMU part is mapped WB to avoid coherency problems with kernel - * memory. - * The BIOS MTRR is removed. - */ -static __init void fix_gart_mapping(unsigned long aper_base, unsigned long aper_size, - unsigned long iommu_start) -{ - unsigned long aper_pfn; - - mtrr_del(-1, aper_base, aper_size); - - __map_kernel_range(__va(aper_base), aper_size - iommu_size, - PAGE_KERNEL_LARGE_NOCACHE); - __map_kernel_range(__va(aper_base) + iommu_start, iommu_size, - PAGE_KERNEL_LARGE); - - /* Fix potential overlap with a normal kernel map large page */ - aper_pfn = phys_to_pfn(aper_base); - if (aper_base % LARGE_PAGE_SIZE && aper_pfn <= round_up(end_pfn, LARGE_PFN)) { - change_page_attr(pfn_to_page(round_down(aper_pfn, LARGE_PFN)), - aper_pfn - round_down(aper_pfn, LARGE_PFN) - 1, - PAGE_KERNEL); - change_page_attr(pfn_to_page(aper_pfn), - round_up(aper_pfn, LARGE_PFN) - aper_pfn - 1, - PAGE_KERNEL_NOCACHE); - } -} - void __init pci_iommu_init(void) { agp_kern_info info; @@ -506,26 +408,32 @@ iommu_size>>20); iommu_start = aper_size - iommu_size; - fix_gart_mapping(info.aper_base, info.aper_size * 1024 * 1024, iommu_start); - iommu_bus_base = info.aper_base + iommu_start; iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT); + + asm volatile("wbinvd" ::: "memory"); } -/* iommu=[size][,noagp][,off] +/* iommu=[size][,noagp][,off][,force][,noforce] noagp don't initialize the AGP driver and use full aperture. off don't use the IOMMU */ static __init int iommu_setup(char *opt) { int arg; - if (strstr(opt,"noagp")) - no_agp = 1; - if (strstr(opt,"off")) - no_iommu = 1; - - if (get_option(&opt, &arg)) - iommu_size = arg; + char *p; + while ((p = strsep(&opt, ",")) != NULL) { + if (strcmp(p,"noagp")) + no_agp = 1; + if (strcmp(p,"off")) + no_iommu = 1; + if (strcmp(p,"force")) + force_mmu = 1; + if (strcmp(p,"noforce")) + force_mmu = 0; + if (isdigit(*p) && get_option(&p, &arg)) + iommu_size = arg; + } return 1; } Index: linux/arch/x86_64/kernel/setup.c diff -u linux/arch/x86_64/kernel/setup.c:1.55 linux/arch/x86_64/kernel/setup.c:1.56 --- linux/arch/x86_64/kernel/setup.c:1.55 Wed Jul 3 09:11:50 2002 +++ linux/arch/x86_64/kernel/setup.c Sun Jul 14 09:54:10 2002 @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include Index: linux/arch/x86_64/kernel/smpboot.c diff -u linux/arch/x86_64/kernel/smpboot.c:1.15 linux/arch/x86_64/kernel/smpboot.c:1.16 --- linux/arch/x86_64/kernel/smpboot.c:1.15 Mon Jul 1 02:01:19 2002 +++ linux/arch/x86_64/kernel/smpboot.c Thu Jul 4 07:48:39 2002 @@ -422,8 +422,6 @@ int cpucount; -extern int cpu_idle(void); - /* * Activate a secondary processor. */ @@ -444,7 +442,8 @@ */ local_flush_tlb(); - return cpu_idle(); + cpu_idle(); + return 0; } /* Index: linux/arch/x86_64/kernel/traps.c diff -u linux/arch/x86_64/kernel/traps.c:1.45 linux/arch/x86_64/kernel/traps.c:1.46 --- linux/arch/x86_64/kernel/traps.c:1.45 Wed Jul 3 09:11:50 2002 +++ linux/arch/x86_64/kernel/traps.c Mon Jul 8 05:39:55 2002 @@ -7,7 +7,7 @@ * Pentium III FXSR, SSE support * Gareth Hughes , May 2000 * - * $Id: traps.c,v 1.45 2002/07/03 15:11:50 ak Exp $ + * $Id: traps.c,v 1.46 2002/07/08 11:39:55 ak Exp $ */ /* @@ -346,7 +346,7 @@ return; if (__get_user(tmp, f.filename)) f.filename = "unmapped filename"; - printk("Kernel BUG at %.50s:%d\n", f.filename, f.line); + printk(KERN_EMERG "Kernel BUG at %.50s:%d\n", f.filename, f.line); } spinlock_t die_lock = SPIN_LOCK_UNLOCKED; @@ -360,7 +360,7 @@ notifier_call_chain(&die_chain, DIE_DIE, &args); bust_spinlocks(1); handle_BUG(regs); - printk("%s: %04lx\n", str, err & 0xffff); + printk(KERN_EMERG "%s: %04lx\n", str, err & 0xffff); cpu = smp_processor_id(); /* racy, but better than risking deadlock. */ __cli(); @@ -380,7 +380,7 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) { - if (!(regs->eflags & VM_MASK) && (regs->cs == __KERNEL_CS)) + if (regs->cs == __KERNEL_CS) die(str, regs, err); } Index: linux/arch/x86_64/kernel/vsyscall.c diff -u linux/arch/x86_64/kernel/vsyscall.c:1.16 linux/arch/x86_64/kernel/vsyscall.c:1.17 --- linux/arch/x86_64/kernel/vsyscall.c:1.16 Thu Jun 6 16:51:22 2002 +++ linux/arch/x86_64/kernel/vsyscall.c Tue Jul 16 09:53:38 2002 @@ -12,7 +12,7 @@ * vsyscalls. One vsyscall can reserve more than 1 slot to avoid * jumping out of line if necessary. * - * $Id: vsyscall.c,v 1.16 2002/06/06 22:51:22 vojtech Exp $ + * $Id: vsyscall.c,v 1.17 2002/07/16 15:53:38 vojtech Exp $ */ /* @@ -47,6 +47,9 @@ #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) +/* Note: Must exist even when vsyscalls aren't used. */ +long __vxtime_sequence[2] __section_vxtime_sequence; + #define NO_VSYSCALL 1 #ifdef NO_VSYSCALL @@ -73,9 +76,6 @@ tv->tv_sec += __sec; } } - -/* warning: size hardcoded in vmlinux.lds */ -long __vxtime_sequence[2] __section_vxtime_sequence; static inline void do_vgettimeofday(struct timeval * tv) { Index: linux/arch/x86_64/kernel/x8664_ksyms.c diff -u linux/arch/x86_64/kernel/x8664_ksyms.c:1.28 linux/arch/x86_64/kernel/x8664_ksyms.c:1.31 --- linux/arch/x86_64/kernel/x8664_ksyms.c:1.28 Wed Jul 3 20:05:01 2002 +++ linux/arch/x86_64/kernel/x8664_ksyms.c Sun Jul 14 09:54:11 2002 @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -91,6 +90,9 @@ EXPORT_SYMBOL(pci_alloc_consistent); EXPORT_SYMBOL(pci_free_consistent); +EXPORT_SYMBOL(pci_map_sg); +EXPORT_SYMBOL(pci_unmap_sg); + #ifdef CONFIG_PCI EXPORT_SYMBOL(pcibios_penalize_isa_irq); EXPORT_SYMBOL(pci_mem_start); @@ -101,6 +103,8 @@ EXPORT_SYMBOL(kernel_flag_cacheline); EXPORT_SYMBOL(smp_num_cpus); EXPORT_SYMBOL(cpu_online_map); +extern void __read_lock_failed(void); +extern void __write_lock_failed(void); EXPORT_SYMBOL_NOVERS(__write_lock_failed); EXPORT_SYMBOL_NOVERS(__read_lock_failed); @@ -136,6 +140,7 @@ #undef memmove #undef strlen #undef strcpy +#undef strcmp #undef strncmp #undef strncpy #undef strchr @@ -144,6 +149,7 @@ extern void * memcpy(void *,const void *,__kernel_size_t); extern void * memset(void *,int,__kernel_size_t); extern __kernel_size_t strlen(const char *); +extern int strcmp(const char *,const char *); extern char * strcpy(char *,const char *); extern char * bcopy(const char * src, char * dest, int count); @@ -157,6 +163,7 @@ EXPORT_SYMBOL_NOVERS(strncpy); EXPORT_SYMBOL_NOVERS(strchr); EXPORT_SYMBOL_NOVERS(strcat); +EXPORT_SYMBOL_NOVERS(strcmp); EXPORT_SYMBOL_NOVERS(strncat); EXPORT_SYMBOL_NOVERS(memchr); EXPORT_SYMBOL_NOVERS(strrchr); @@ -203,3 +210,4 @@ EXPORT_SYMBOL(memcpy_toio); EXPORT_SYMBOL(ip_compute_csum); + Index: linux/arch/x86_64/lib/usercopy.c diff -u linux/arch/x86_64/lib/usercopy.c:1.15 linux/arch/x86_64/lib/usercopy.c:1.17 --- linux/arch/x86_64/lib/usercopy.c:1.15 Mon Jun 24 20:47:28 2002 +++ linux/arch/x86_64/lib/usercopy.c Tue Jul 16 06:18:37 2002 @@ -11,39 +11,49 @@ * Copy a null terminated string from userspace. */ -long __strncpy_from_user(char *dst, const char *src, long count) +#define __do_strncpy_from_user(dst,src,count,res) \ +do { \ + long __d0, __d1, __d2; \ + __asm__ __volatile__( \ + " testq %1,%1\n" \ + " jz 2f\n" \ + "0: lodsb\n" \ + " stosb\n" \ + " testb %%al,%%al\n" \ + " jz 1f\n" \ + " decq %1\n" \ + " jnz 0b\n" \ + "1: subq %1,%0\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movq %5,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .quad 0b,3b\n" \ + ".previous" \ + : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ + "=&D" (__d2) \ + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ + : "memory"); \ +} while (0) + +long +__strncpy_from_user(char *dst, const char *src, long count) { long res; - long __d0, __d1, __d2; - asm volatile( \ - " testq %1,%1\n" - " jz 2f\n" - "0: lodsb\n" - " stosb\n" - " testb %%al,%%al\n" - " loopnz 0b\n" - "1: subq %1,%0\n" - "2:\n" - ".section .fixup,\"ax\"\n" - "3: movq %5,%0\n" - " jmp 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b,3b\n" - ".previous" - : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), - "=&D" (__d2) - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) - : "memory"); + __do_strncpy_from_user(dst, src, count, res); return res; } -long strncpy_from_user(char *dst, const char *src, long count) +long +strncpy_from_user(char *dst, const char *src, long count) { + long res = -EFAULT; if (access_ok(VERIFY_READ, src, 1)) - return __strncpy_from_user(dst, src, count); - return -EFAULT; + __do_strncpy_from_user(dst, src, count, res); + return res; } /* Index: linux/arch/x86_64/mm/fault.c diff -u linux/arch/x86_64/mm/fault.c:1.29 linux/arch/x86_64/mm/fault.c:1.31 --- linux/arch/x86_64/mm/fault.c:1.29 Mon Jul 1 02:01:20 2002 +++ linux/arch/x86_64/mm/fault.c Tue Jul 16 00:25:26 2002 @@ -83,7 +83,7 @@ } int page_fault_trace; -int exception_trace = 1; +int exception_trace; /* * This routine handles page faults. It determines the address, @@ -248,6 +248,7 @@ * terminate things with extreme prejudice. */ + console_verbose(); bust_spinlocks(1); if (address < PAGE_SIZE) Index: linux/arch/x86_64/mm/init.c diff -u linux/arch/x86_64/mm/init.c:1.28 linux/arch/x86_64/mm/init.c:1.29 --- linux/arch/x86_64/mm/init.c:1.28 Mon Jul 1 02:26:40 2002 +++ linux/arch/x86_64/mm/init.c Sun Jul 7 14:59:18 2002 @@ -237,7 +237,6 @@ break; } pe = _PAGE_PSE | _KERNPG_TABLE | _PAGE_GLOBAL | paddr; - pe = (pe | _PAGE_NX) & __supported_pte_mask; set_pmd(pmd, __pmd(pe)); } unmap_low_page(map); Index: linux/include/asm-x86_64/bootsetup.h diff -u linux/include/asm-x86_64/bootsetup.h:1.2 linux/include/asm-x86_64/bootsetup.h:1.3 --- linux/include/asm-x86_64/bootsetup.h:1.2 Tue Jun 12 14:58:52 2001 +++ linux/include/asm-x86_64/bootsetup.h Sun Jul 14 09:54:11 2002 @@ -13,7 +13,6 @@ #define ALT_MEM_K (*(unsigned int *) (PARAM+0x1e0)) #define E820_MAP_NR (*(char*) (PARAM+E820NR)) #define E820_MAP ((struct e820entry *) (PARAM+E820MAP)) -#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40)) #define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80)) #define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0)) #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2)) Index: linux/include/asm-x86_64/mc146818rtc.h diff -u linux/include/asm-x86_64/mc146818rtc.h:1.1.1.1 linux/include/asm-x86_64/mc146818rtc.h:1.3 --- linux/include/asm-x86_64/mc146818rtc.h:1.1.1.1 Thu Apr 19 14:00:38 2001 +++ linux/include/asm-x86_64/mc146818rtc.h Mon Jul 15 10:06:40 2002 @@ -24,6 +24,11 @@ outb_p((val),RTC_PORT(1)); \ }) +#ifndef CONFIG_HPET_TIMER #define RTC_IRQ 8 +#else +/* Temporary workaround due to IRQ routing problem. */ +#define RTC_IRQ 0 +#endif #endif /* _ASM_MC146818RTC_H */ Index: linux/include/asm-x86_64/mtrr.h diff -u linux/include/asm-x86_64/mtrr.h:1.4 linux/include/asm-x86_64/mtrr.h:1.5 --- linux/include/asm-x86_64/mtrr.h:1.4 Fri Jun 14 14:43:37 2002 +++ linux/include/asm-x86_64/mtrr.h Tue Jul 16 03:38:41 2002 @@ -25,21 +25,20 @@ #include #include -#include #define MTRR_IOCTL_BASE 'M' struct mtrr_sentry { - __u64 base; /* Base address */ - __u32 size; /* Size of region */ + unsigned long base; /* Base address */ + unsigned int size; /* Size of region */ unsigned int type; /* Type of region */ }; struct mtrr_gentry { - __u64 base; /* Base address */ - __u32 size; /* Size of region */ + unsigned long base; /* Base address */ + unsigned int size; /* Size of region */ unsigned int regnum; /* Register number */ unsigned int type; /* Type of region */ }; @@ -80,6 +79,7 @@ #endif #ifdef __KERNEL__ +#include /* The following functions are for use by other drivers */ #ifdef CONFIG_MTRR Index: linux/include/asm-x86_64/pci.h diff -u linux/include/asm-x86_64/pci.h:1.9 linux/include/asm-x86_64/pci.h:1.10 --- linux/include/asm-x86_64/pci.h:1.9 Wed Jul 3 23:16:07 2002 +++ linux/include/asm-x86_64/pci.h Tue Jul 16 09:00:45 2002 @@ -89,16 +89,19 @@ #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ (((PTR)->LEN_NAME) = (VAL)) +static inline void pci_dma_sync_single(struct pci_dev *hwdev, + dma_addr_t dma_handle, + size_t size, int direction) +{ + BUG_ON(direction == PCI_DMA_NONE); +} -extern void pci_dma_sync_single(struct pci_dev *hwdev, - dma_addr_t dma_handle, - size_t size, int direction); - -extern void pci_dma_sync_sg(struct pci_dev *hwdev, - struct scatterlist *sg, - int nelems, int direction); - - +static inline void pci_dma_sync_sg(struct pci_dev *hwdev, + struct scatterlist *sg, + int nelems, int direction) +{ + BUG_ON(direction == PCI_DMA_NONE); +} /* The PCI address space does equal the physical memory * address space. The networking and block device layers use