- updated uml patches.
[opensuse:kernel-source.git] / patches.arch / x86_64-2.6.0test2-2
1 diff -burpN -X ../KDIFX linux/Documentation/x86_64/boot-options.txt linux-2.6.0test2-amd64/Documentation/x86_64/boot-options.txt
2 --- linux/Documentation/x86_64/boot-options.txt 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.0test2-amd64/Documentation/x86_64/boot-options.txt        2003-07-11 13:34:20.000000000 +0200
4 @@ -0,0 +1,152 @@
5 +AMD64 specific boot options
6 +
7 +There are many others (usually documented in driver documentation), but 
8 +only the AMD64 specific ones are listed here.
9 +
10 +Machine check
11 +
12 +(see the Opteron BIOS&Kernel manual for more details on the banks etc.)
13 +
14 +   mce=off disable machine check
15 +   mce=nok8 disable k8 specific features
16 +   mce=disable<NUMBER> disable bank NUMBER
17 +   mce=enable<NUMBER> enable bank number
18 +   mce=device  Enable more machine check options in Northbridge. 
19 +               Can be useful for device driver debugging.
20 +   mce=NUMBER mcheck timer interval number seconds. 
21 +   Can be also comma separated in a single mce=
22 +
23 +   nomce (for compatibility with i386): same as mce=off
24 +
25 +APICs
26 +
27 +   nolocalapic   Don't use a local or IO-APIC. This should only
28 +                be needed if you have a buggy BIOS. The newer
29 +                kernels already turn it off by default if the
30 +                BIOS didn't enable the local APIC, so it will
31 +                be hopefully not needed.
32 +                Note this code path is not very well tested, you are on
33 +                your own.
34 +               
35 +   apic                 Use IO-APIC. Default
36 +
37 +   noapic       Don't use the IO-APIC. 
38 +                Also only lightly tested. 
39 +
40 +   pirq=...     See Documentation/i386/IO-APIC.txt              
41 +    
42 +Early Console
43 +
44 +   syntax: earlyprintk=vga
45 +           earlyprintk=serial[,ttySn[,baudrate]] 
46 +
47 +   The early console is useful when the kernel crashes before the
48 +   normal console is initialized. It is not enabled by 
49 +   default because it has some cosmetic problems.         
50 +   Append ,keep to not disable it when the real console takes over.
51 +   Only vga or serial at a time, not both.
52 +   Currently only ttyS0 and ttyS1 are supported. 
53 +   Interaction with the standard serial driver is not very good. 
54 +   The VGA output is eventually overwritten by the real console.                
55 +
56 +Timing
57 +
58 +  notsc
59 +  Don't use the CPU time stamp counter to read the wall time. 
60 +  This can be used to work around timing problems on multiprocessor systems 
61 +  with not properly synchronized CPUs. Only useful with a SMP kernel
62 +
63 +  report_lost_ticks
64 +  Report when timer interrupts are lost because some code turned off
65 +  interrupts for too long. 
66 +
67 +  nmi_watchdog=NUMBER
68 +  NUMBER can be: 
69 +  0 don't use an NMI watchdog
70 +  1 use the IO-APIC timer for the NMI watchdog
71 +  2 use the local APIC for the NMI watchdog using a performance counter. Note
72 +  This will use one performance counter and the local APIC's performance
73 +  vector.
74 +
75 +Idle loop
76 +
77 +  idle=poll
78 +  Don't do power saving in the idle loop using HLT, but poll for rescheduling 
79 +  event. This will make the CPUs eat a lot more power, but may be useful 
80 +  to get slightly better performance in multiprocessor benchmarks. It also
81 +  makes some profiling using performance counters more accurate.
82 +
83 +Rebooting
84 +
85 +   reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
86 +   bios          Use the CPU reboto vector for warm reset
87 +   warm   Don't set the cold reboot flag
88 +   cold   Set the cold reboto flag
89 +   triple Force a triple fault (init)
90 +   kbd    Use the keyboard controller. cold reset (default)
91 +
92 +   Using warm reset will be much faster especially on big memory
93 +   systems because the BIOS will not go through the memory check.
94 +   Disadvantage is that not all hardware will be completely reinitialized
95 +   on reboot so there may be boot problems on some systems.
96 +   
97 +Non Executable Mappings
98 +
99 +  noexec=on|off
100 +
101 +  on      Enable
102 +  off     Disable
103 +  noforce (default) Don't enable by default for heap/stack/data,
104 +          but allow PROT_EXEC to be effective
105 +
106 +  noexec32=opt{,opt} 
107 +
108 +  Control the no exec default for 32bit processes. 
109 +  Requires noexec=on or noexec=noforce to be effective.
110 +
111 +  Valid options: 
112 +     all,on    Heap,stack,data is non executable.      
113 +     off       (default) Heap,stack,data is executable
114 +     stack     Stack is non executable, heap/data is.
115 +     force     Don't imply PROT_EXEC for PROT_READ 
116 +     compat    (default) Imply PROT_EXEC for PROT_READ
117
118 +SMP 
119 +
120 +  nosmp        Only use a single CPU
121 +
122 +  maxcpus=NUMBER only use upto NUMBER CPUs
123 +
124 +  cpumask=MASK   only use cpus with bits set in mask
125 +
126 +NUMA
127 +
128 +  numa=off     Only set up a single NUMA node spanning all memory.
129 +
130 +
131 +ACPI 
132 +
133 +  acpi=off     Don't enable ACPI
134 +  
135 +PCI
136 +
137 +  pci=off      Don't use PCI
138 +  pci=conf1    Use conf1 access.
139 +  pci=conf2    Use conf2 access.
140 +  pci=rom      Assign ROMs.
141 +  pci=assign-busses    Assign busses
142 +  pci=irqmask=MASK            Set PCI interrupt mask to MASK
143 +  pci=lastbus=NUMBER          Scan upto NUMBER busses, no matter what the mptable says.
144 +
145 +IOMMU
146 +
147 +  iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
148 +   size  set size of iommu (in bytes) 
149 +   noagp don't initialize the AGP driver and use full aperture.
150 +   off   don't use the IOMMU
151 +   leak  turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on)
152 +   memaper[=order] allocate an own aperture over RAM with size 32MB^order.
153 +   noforce don't force IOMMU usage. Default.
154 +   force  Force IOMMU
155 +
156 +
157 diff -burpN -X ../KDIFX linux/arch/x86_64/defconfig linux-2.6.0test2-amd64/arch/x86_64/defconfig
158 --- linux/arch/x86_64/defconfig 2003-07-18 02:39:52.000000000 +0200
159 +++ linux-2.6.0test2-amd64/arch/x86_64/defconfig        2003-07-29 01:07:28.000000000 +0200
160 @@ -24,8 +24,11 @@ CONFIG_SYSVIPC=y
161  CONFIG_SYSCTL=y
162  CONFIG_LOG_BUF_SHIFT=16
163  # CONFIG_EMBEDDED is not set
164 +CONFIG_KALLSYMS=y
165  CONFIG_FUTEX=y
166  CONFIG_EPOLL=y
167 +CONFIG_IOSCHED_AS=y
168 +CONFIG_IOSCHED_DEADLINE=y
169  
170  #
171  # Loadable module support
172 @@ -135,6 +138,7 @@ CONFIG_BLK_DEV_FD=y
173  # CONFIG_BLK_DEV_DAC960 is not set
174  # CONFIG_BLK_DEV_UMEM is not set
175  CONFIG_BLK_DEV_LOOP=y
176 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
177  # CONFIG_BLK_DEV_NBD is not set
178  CONFIG_BLK_DEV_RAM=y
179  CONFIG_BLK_DEV_RAM_SIZE=4096
180 @@ -163,6 +167,7 @@ CONFIG_BLK_DEV_IDECD=y
181  # CONFIG_BLK_DEV_IDEFLOPPY is not set
182  # CONFIG_BLK_DEV_IDESCSI is not set
183  # CONFIG_IDE_TASK_IOCTL is not set
184 +# CONFIG_IDE_TASKFILE_IO is not set
185  
186  #
187  # IDE chipset support/bugfixes
188 @@ -379,7 +384,6 @@ CONFIG_NET_PCI=y
189  CONFIG_AMD8111_ETH=y
190  # CONFIG_ADAPTEC_STARFIRE is not set
191  # CONFIG_B44 is not set
192 -# CONFIG_TC35815 is not set
193  # CONFIG_DGRS is not set
194  # CONFIG_EEPRO100 is not set
195  # CONFIG_E100 is not set
196 @@ -727,6 +731,9 @@ CONFIG_SOUND_ICH=y
197  # CONFIG_SOUND_MSNDPIN is not set
198  # CONFIG_SOUND_VIA82CXXX is not set
199  # CONFIG_SOUND_OSS is not set
200 +# CONFIG_SOUND_ALI5455 is not set
201 +# CONFIG_SOUND_FORTE is not set
202 +# CONFIG_SOUND_AD1980 is not set
203  
204  #
205  # USB support
206 @@ -753,7 +760,6 @@ CONFIG_DEBUG_KERNEL=y
207  CONFIG_MAGIC_SYSRQ=y
208  # CONFIG_DEBUG_SPINLOCK is not set
209  # CONFIG_INIT_DEBUG is not set
210 -CONFIG_KALLSYMS=y
211  # CONFIG_FRAME_POINTER is not set
212  CONFIG_IOMMU_DEBUG=y
213  CONFIG_IOMMU_LEAK=y
214 diff -burpN -X ../KDIFX linux/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.0test2-amd64/arch/x86_64/ia32/ia32_binfmt.c
215 --- linux/arch/x86_64/ia32/ia32_binfmt.c        2003-07-18 02:40:03.000000000 +0200
216 +++ linux-2.6.0test2-amd64/arch/x86_64/ia32/ia32_binfmt.c       2003-07-29 01:53:21.000000000 +0200
217 @@ -32,12 +32,14 @@
218  #define AT_SYSINFO 32
219  #define AT_SYSINFO_EHDR                33
220  
221 -#if 0 /* disabled for now because the code has still problems */
222 +int sysctl_vsyscall32;
223 +
224  #define ARCH_DLINFO do {  \
225 +       if (sysctl_vsyscall32) { \
226         NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
227         NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE);    \
228 +       }       \
229  } while(0)
230 -#endif
231  
232  struct file;
233  struct elf_phdr; 
234 @@ -202,7 +204,7 @@ static inline int elf_core_copy_task_reg
235  }
236  
237  static inline int 
238 -elf_core_copy_task_fpregs(struct task_struct *tsk, elf_fpregset_t *fpu)
239 +elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
240  {
241         struct _fpstate_ia32 *fpstate = (void*)fpu; 
242         struct pt_regs *regs = (struct pt_regs *)(tsk->thread.rsp0); 
243 diff -burpN -X ../KDIFX linux/arch/x86_64/ia32/ia32_ioctl.c linux-2.6.0test2-amd64/arch/x86_64/ia32/ia32_ioctl.c
244 --- linux/arch/x86_64/ia32/ia32_ioctl.c 2003-07-18 02:39:52.000000000 +0200
245 +++ linux-2.6.0test2-amd64/arch/x86_64/ia32/ia32_ioctl.c        2003-07-11 14:14:13.000000000 +0200
246 @@ -726,6 +726,7 @@ COMPATIBLE_IOCTL(BNEPCONNADD)
247  COMPATIBLE_IOCTL(BNEPCONNDEL)
248  COMPATIBLE_IOCTL(BNEPGETCONNLIST)
249  COMPATIBLE_IOCTL(BNEPGETCONNINFO)
250 +COMPATIBLE_IOCTL(FIOQSIZE)
251  
252  /* And these ioctls need translation */
253  HANDLE_IOCTL(TIOCGDEV, tiocgdev)
254 diff -burpN -X ../KDIFX linux/arch/x86_64/ia32/ia32entry.S linux-2.6.0test2-amd64/arch/x86_64/ia32/ia32entry.S
255 --- linux/arch/x86_64/ia32/ia32entry.S  2003-07-18 02:39:52.000000000 +0200
256 +++ linux-2.6.0test2-amd64/arch/x86_64/ia32/ia32entry.S 2003-07-14 00:14:25.000000000 +0200
257 @@ -462,11 +462,21 @@ ia32_sys_call_table:
258         .quad sys_epoll_wait
259         .quad sys_remap_file_pages
260         .quad sys_set_tid_address
261 -       
262 +       .quad sys32_timer_create
263 +       .quad compat_timer_settime
264 +       .quad compat_timer_gettime
265 +       .quad sys_timer_getoverrun
266 +       .quad sys_timer_delete
267 +       .quad compat_clock_settime
268 +       .quad compat_clock_gettime
269 +       .quad compat_clock_getres
270 +       .quad compat_clock_nanosleep
271 +       .quad compat_statfs64   /* statfs64 */
272 +       .quad compat_fstatfs64  /* fstatfs64 */
273 +       .quad sys_tgkill
274 +       .quad compat_sys_utimes
275         /* don't forget to change IA32_NR_syscalls */
276  ia32_syscall_end:              
277         .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
278                 .quad ni_syscall
279         .endr
280 -
281 -       
282 diff -burpN -X ../KDIFX linux/arch/x86_64/ia32/ipc32.c linux-2.6.0test2-amd64/arch/x86_64/ia32/ipc32.c
283 --- linux/arch/x86_64/ia32/ipc32.c      2003-07-18 02:42:38.000000000 +0200
284 +++ linux-2.6.0test2-amd64/arch/x86_64/ia32/ipc32.c     2003-07-11 14:10:21.000000000 +0200
285 @@ -687,9 +687,7 @@ sys32_ipc (u32 call, int first, int seco
286                 return sys_shmget(first, second, third);
287               case SHMCTL:
288                 return shmctl32(first, second, (void *)AA(ptr));
289 -             default:
290 -               return -EINVAL;
291         }
292 -       return -EINVAL;
293 +       return -ENOSYS;
294  }
295  
296 diff -burpN -X ../KDIFX linux/arch/x86_64/ia32/sys_ia32.c linux-2.6.0test2-amd64/arch/x86_64/ia32/sys_ia32.c
297 --- linux/arch/x86_64/ia32/sys_ia32.c   2003-07-18 02:39:52.000000000 +0200
298 +++ linux-2.6.0test2-amd64/arch/x86_64/ia32/sys_ia32.c  2003-07-14 13:19:39.000000000 +0200
299 @@ -1993,6 +1993,41 @@ asmlinkage long sys32_open(const char * 
300         return fd;
301  }
302  
303 +struct sigevent32 { 
304 +       u32 sigev_value;
305 +       u32 sigev_signo; 
306 +       u32 sigev_notify; 
307 +       u32 payload[(64 / 4) - 3]; 
308 +}; 
309 +
310 +extern asmlinkage long
311 +sys_timer_create(clockid_t which_clock,
312 +                struct sigevent __user *timer_event_spec,
313 +                timer_t __user * created_timer_id);
314 +
315 +long
316 +sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id)
317 +{
318 +       struct sigevent se;
319 +       if (se32) { 
320 +               memset(&se, 0, sizeof(struct sigevent)); 
321 +               if (get_user(se.sigev_value.sival_int,  &se32->sigev_value) ||
322 +                   __get_user(se.sigev_signo, &se32->sigev_signo) ||
323 +                   __get_user(se.sigev_notify, &se32->sigev_notify) ||
324 +                   __copy_from_user(&se._sigev_un._pad, &se32->payload, 
325 +                                    sizeof(se32->payload)))
326 +                       return -EFAULT;
327 +       } 
328 +       if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
329 +               return -EFAULT;
330 +
331 +       mm_segment_t oldfs = get_fs();
332 +       set_fs(KERNEL_DS);
333 +       long err = sys_timer_create(clock, se32 ? &se : NULL, timer_id);
334 +       set_fs(oldfs); 
335 +       
336 +       return err; 
337 +} 
338  
339  long sys32_vm86_warning(void)
340  { 
341 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/Makefile linux-2.6.0test2-amd64/arch/x86_64/kernel/Makefile
342 --- linux/arch/x86_64/kernel/Makefile   2003-07-18 02:39:30.000000000 +0200
343 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/Makefile  2003-07-29 01:42:02.000000000 +0200
344 @@ -6,7 +6,7 @@ extra-y         := head.o head64.o init_task.o
345  EXTRA_AFLAGS   := -traditional
346  obj-y  := process.o semaphore.o signal.o entry.o traps.o irq.o \
347                 ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
348 -               pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
349 +               x8664_ksyms.o i387.o syscall.o vsyscall.o \
350                 setup64.o bluesmoke.o bootflag.o e820.o reboot.o warmreboot.o
351  
352  obj-$(CONFIG_MTRR)     += mtrr/
353 @@ -19,7 +19,8 @@ obj-$(CONFIG_X86_IO_APIC)     += io_apic.o m
354  obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o suspend_asm.o
355  obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
356  obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
357 -obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o
358 +obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o
359 +
360  obj-$(CONFIG_MODULES) += module.o
361  
362  $(obj)/bootflag.c: 
363 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/aperture.c linux-2.6.0test2-amd64/arch/x86_64/kernel/aperture.c
364 --- linux/arch/x86_64/kernel/aperture.c 2003-07-18 02:39:30.000000000 +0200
365 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/aperture.c        2003-07-11 19:20:32.000000000 +0200
366 @@ -1,14 +1,14 @@
367  /* 
368   * Firmware replacement code.
369   * 
370 - * Work around broken BIOSes that don't set an aperture. 
371 - * The IOMMU code needs an aperture even who no AGP is present in the system.
372 - * Map the aperture over some low memory.  This is cheaper than doing bounce 
373 - * buffering. The memory is lost. This is done at early boot because only
374 - * the bootmem allocator can allocate 32+MB. 
375 + * Work around broken BIOSes that don't set an aperture or only set the
376 + * aperture in the AGP bridge. 
377 + * If all fails map the aperture over some low memory.  This is cheaper than 
378 + * doing bounce buffering. The memory is lost. This is done at early boot 
379 + * because only the bootmem allocator can allocate 32+MB. 
380   * 
381   * Copyright 2002 Andi Kleen, SuSE Labs.
382 - * $Id: aperture.c,v 1.2 2002/09/19 19:25:32 ak Exp $
383 + * $Id: aperture.c,v 1.5 2003/07/11 12:30:09 ak Exp $
384   */
385  #include <linux/config.h>
386  #include <linux/kernel.h>
387 @@ -17,6 +17,8 @@
388  #include <linux/bootmem.h>
389  #include <linux/mmzone.h>
390  #include <linux/pci_ids.h>
391 +#include <linux/pci.h>
392 +#include <linux/bitops.h>
393  #include <asm/e820.h>
394  #include <asm/io.h>
395  #include <asm/proto.h>
396 @@ -45,10 +47,9 @@ static u32 __init allocate_aperture(void
397         aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
398  
399         /* 
400 -         * Aperture has to be naturally aligned it seems. This means an
401 -        * 2GB aperture won't have much changes to succeed in the lower 4GB of 
402 -        * memory. Unfortunately we cannot move it up because that would make
403 -        * the IOMMU useless.
404 +         * Aperture has to be naturally aligned. This means an 2GB aperture won't 
405 +         * have much chances to find a place in the lower 4GB of memory. Unfortunately 
406 +         * we cannot move it up because that would make the IOMMU useless.
407          */
408         p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
409         if (!p || __pa(p)+aper_size > 0xffffffff) {
410 @@ -63,17 +64,123 @@ static u32 __init allocate_aperture(void
411         return (u32)__pa(p); 
412  }
413  
414 +static int __init aperture_valid(u64 aper_base, u32 aper_size) 
415 +{ 
416 +       if (!aper_base)
417 +               return 0; 
418 +       if (aper_size < 64*1024*1024) { 
419 +               printk("Aperture too small (%d MB)\n", aper_size>>20); 
420 +               return 0;
421 +       }
422 +       if (aper_base + aper_size >= 0xffffffff) { 
423 +               printk("Aperture beyond 4GB. Ignoring.\n");
424 +               return 0; 
425 +       }
426 +       if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {  
427 +               printk("Aperture pointing to e820 RAM. Ignoring.\n");
428 +               return 0; 
429 +       } 
430 +       return 1;
431 +} 
432 +
433 +/* Find a PCI capability */ 
434 +static __u32 __init find_cap(int num, int slot, int func, int cap) 
435 +{ 
436 +       if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
437 +               return 0;
438 +       u8 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
439 +       int bytes;
440 +       for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { 
441 +               pos &= ~3; 
442 +               u8 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID); 
443 +               if (id == 0xff)
444 +                       break;
445 +               if (id == cap) 
446 +                       return pos; 
447 +               pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT); 
448 +       } 
449 +       return 0;
450 +} 
451 +
452 +/* Read a standard AGPv3 bridge header */
453 +static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
454 +{ 
455 +       printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func); 
456 +
457 +       u32 apsize = read_pci_config_16(num,slot,func, cap + 0x14);
458 +       if (apsize == 0xffffffff) {
459 +               printk("APSIZE in AGP bridge unreadable\n");
460 +               return 0;
461 +       }
462 +
463 +       apsize &= 0xfff;
464 +       int nbits = hweight16(apsize);
465 +       *order = 7 - nbits;
466 +       
467 +       u32 aper_low = read_pci_config(num,slot,func, 0x10); 
468 +       u32 aper_hi = read_pci_config(num,slot,func,0x14); 
469 +       u64 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); 
470 +
471 +       printk("Aperture from AGP @ %Lx size %u MB\n", aper, 32 << *order);
472 +
473 +       if (!aperture_valid(aper, (32*1024*1024) << *order))
474 +           return 0;
475 +       return (u32)aper; 
476 +} 
477 +
478 +/* Look for an AGP bridge. Windows only expects the aperture in the
479 +   AGP bridge and some BIOS forget to initialize the Northbridge too.
480 +   Work around this here. 
481 +
482 +   Do an PCI bus scan by hand because we're running before the PCI
483 +   subsystem. 
484 +
485 +   All K8 AGP bridges are AGPv3 compliant, so we can do this scan
486 +   generically. It's probably overkill to always scan all slots because
487 +   the AGP bridges should be always an own bus on the HT hierarchy, 
488 +   but do it here for future safety. */
489 +static __u32 __init search_agp_bridge(u32 *order)
490 +{
491 +       int num, slot, func;
492 +
493 +       /* Poor man's PCI discovery */
494 +       for (num = 0; num < 32; num++) { 
495 +               for (slot = 0; slot < 32; slot++) { 
496 +                       for (func = 0; func < 8; func++) { 
497 +                               u32 class, cap;
498 +                               class = read_pci_config(num,slot,func,
499 +                                                       PCI_CLASS_REVISION);
500 +                               if (class == 0xffffffff)
501 +                                       break; 
502 +                               
503 +                               switch (class >> 16) { 
504 +                               case PCI_CLASS_BRIDGE_HOST:
505 +                               case PCI_CLASS_BRIDGE_OTHER: /* needed? */
506 +                                       /* AGP bridge? */
507 +                                       cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
508 +                                       if (!cap)
509 +                                               break;
510 +                                       return read_agp(num,slot,func,cap,order);
511 +                               } 
512 +                               
513 +                               /* No multi-function device? */
514 +                               u8 type = read_pci_config_byte(num,slot,func,
515 +                                                              PCI_HEADER_TYPE);
516 +                               if (!(type & 0x80))
517 +                                       break;
518 +                       } 
519 +               } 
520 +       }
521 +       printk("No AGP bridge found\n"); 
522 +       return 0;
523 +}
524 +
525  void __init iommu_hole_init(void) 
526  { 
527         int fix, num; 
528 -       u32 aper_size, aper_alloc, aper_order;
529 +       u32 aper_size, aper_alloc = 0, aper_order;
530         u64 aper_base; 
531  
532 -       if (no_iommu)
533 -               return;
534 -       if (end_pfn < (0xffffffff>>PAGE_SHIFT) && !force_mmu) 
535 -               return;
536 -
537         printk("Checking aperture...\n"); 
538  
539         fix = 0;
540 @@ -86,15 +193,10 @@ void __init iommu_hole_init(void) 
541                 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
542                 aper_base <<= 25; 
543  
544 -               printk("CPU %d: aperture @ %Lx size %u KB\n", num-24, 
545 -                      aper_base, aper_size>>10);
546 -               if (!aper_base || aper_base + aper_size >= 0xffffffff) {
547 -                       fix = 1; 
548 -                       break; 
549 -               } 
550 +               printk("CPU %d: aperture @ %Lx size %u MB\n", num-24, 
551 +                      aper_base, aper_size>>20);
552                 
553 -               if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {  
554 -                       printk("Aperture pointing to e820 RAM. Ignoring.\n");
555 +               if (!aperture_valid(aper_base, aper_size)) { 
556                         fix = 1; 
557                         break; 
558                 } 
559 @@ -103,12 +205,27 @@ void __init iommu_hole_init(void) 
560         if (!fix && !fallback_aper_force) 
561                 return; 
562  
563 +       if (!fallback_aper_force)
564 +               aper_alloc = search_agp_bridge(&aper_order); 
565 +               
566 +       if (aper_alloc) { 
567 +               /* All ok - got the aperture from the AGP bridge */
568 +       } else if ((no_iommu || 
569 +                     (end_pfn < 0xffffffff>>PAGE_SHIFT && !force_iommu))
570 +                          && !fallback_aper_force) { 
571 +               return; 
572 +       } else {
573         printk("Your BIOS doesn't leave a aperture memory hole\n");
574         printk("Please enable the IOMMU option in the BIOS setup\n"); 
575 +               printk("This costs you %d MB of RAM\n", 32 << fallback_aper_order); 
576
577 +               aper_order = fallback_aper_order;
578         aper_alloc = allocate_aperture(); 
579         if (!aper_alloc) 
580                 return; 
581 +       }
582  
583 +       /* Fix up the north bridges */
584         for (num = 24; num < 32; num++) {               
585                 if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) 
586                         continue;       
587 @@ -116,7 +233,7 @@ void __init iommu_hole_init(void) 
588                 /* Don't enable translation yet. That is done later. 
589                    Assume this BIOS didn't initialise the GART so 
590                    just overwrite all previous bits */ 
591 -               write_pci_config(0, num, 3, 0x90, fallback_aper_order<<1); 
592 +               write_pci_config(0, num, 3, 0x90, aper_order<<1); 
593                 write_pci_config(0, num, 3, 0x94, aper_alloc>>25); 
594         } 
595  } 
596 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/apic.c linux-2.6.0test2-amd64/arch/x86_64/kernel/apic.c
597 --- linux/arch/x86_64/kernel/apic.c     2003-07-18 02:39:30.000000000 +0200
598 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/apic.c    2003-07-11 13:34:21.000000000 +0200
599 @@ -441,9 +441,6 @@ void __init setup_local_APIC (void)
600  
601  #ifdef CONFIG_PM
602  
603 -#include <linux/device.h>
604 -#include <linux/module.h>
605 -
606  static struct {
607         /* 'active' is true if the local APIC was enabled by us and
608            not the BIOS; this signifies that we are also responsible
609 @@ -540,7 +537,6 @@ static struct sysdev_class lapic_sysclas
610         .suspend        = lapic_suspend,
611  };
612  
613 -/* not static, needed by child devices */
614  static struct sys_device device_lapic = {
615         .id             = 0,
616         .cls            = &lapic_sysclass,
617 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/bluesmoke.c linux-2.6.0test2-amd64/arch/x86_64/kernel/bluesmoke.c
618 --- linux/arch/x86_64/kernel/bluesmoke.c        2003-07-18 02:39:30.000000000 +0200
619 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/bluesmoke.c       2003-07-11 13:34:21.000000000 +0200
620 @@ -127,9 +127,8 @@ static struct pci_dev *find_k8_nb(void)
621  { 
622         struct pci_dev *dev = NULL;
623         int cpu = smp_processor_id(); 
624 -       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
625 -               if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
626 -                   PCI_SLOT(dev->devfn) == (24U+cpu))
627 +       while ((dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, dev)) != NULL) {
628 +               if (dev->bus->number==0 && PCI_SLOT(dev->devfn) == (24U+cpu))
629                         return dev;
630         }
631         return NULL;
632 @@ -198,7 +197,7 @@ static char *highbits[32] = { 
633         [0] = "err cpu1",
634  };
635  
636 -static void check_k8_nb(void)
637 +static void check_k8_nb(int header)
638  {
639         struct pci_dev *nb;
640         nb = find_k8_nb(); 
641 @@ -210,6 +209,9 @@ static void check_k8_nb(void)
642         pci_read_config_dword(nb, 0x4c, &statushigh);
643         if (!(statushigh & (1<<31)))
644                 return;
645 +       if (header)
646 +               printk(KERN_ERR "CPU %d: Silent Northbridge MCE\n", smp_processor_id());
647 +
648         printk(KERN_ERR "Northbridge status %08x%08x\n",
649                statushigh,statuslow); 
650  
651 @@ -271,9 +273,12 @@ static void k8_machine_check(struct pt_r
652         rdmsrl(MSR_IA32_MCG_STATUS, status); 
653         if ((status & (1<<2)) == 0) { 
654                 if (!regs) 
655 -                       check_k8_nb();
656 +                       check_k8_nb(1);
657                 return; 
658                 }
659 +
660 +       printk(KERN_EMERG "CPU %d: Machine Check Exception: %016Lx\n", smp_processor_id(), status);
661 +
662         if (status & 1)
663                 printk(KERN_EMERG "MCG_STATUS: unrecoverable\n"); 
664  
665 @@ -291,7 +296,7 @@ static void k8_machine_check(struct pt_r
666         if (nbstatus & (1UL<57))
667                 printk(KERN_EMERG "Unrecoverable condition\n"); 
668                 
669 -       check_k8_nb();
670 +       check_k8_nb(0);
671  
672         if (nbstatus & (1UL<<58)) { 
673                 u64 adr;
674 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/head.S linux-2.6.0test2-amd64/arch/x86_64/kernel/head.S
675 --- linux/arch/x86_64/kernel/head.S     2003-05-27 03:00:42.000000000 +0200
676 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/head.S    2003-07-11 14:24:57.000000000 +0200
677 @@ -307,7 +307,8 @@ ENTRY(empty_bad_pmd_table)
678  ENTRY(level3_physmem_pgt)
679         .quad   0x0000000000105007              /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
680  
681 -.org 0xb000
682 +       .org 0xb000
683 +#ifdef CONFIG_ACPI_SLEEP
684  ENTRY(wakeup_level4_pgt)
685         .quad   0x0000000000102007              /* -> level3_ident_pgt */
686         .fill   255,8,0
687 @@ -315,9 +316,9 @@ ENTRY(wakeup_level4_pgt)
688         .fill   254,8,0
689         /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
690         .quad   0x0000000000103007              /* -> level3_kernel_pgt */
691 +#endif
692  
693 -.org 0xc000
694 -.data
695 +       .data
696  
697         .align 16
698         .globl cpu_gdt_descr
699 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/io_apic.c linux-2.6.0test2-amd64/arch/x86_64/kernel/io_apic.c
700 --- linux/arch/x86_64/kernel/io_apic.c  2003-07-18 02:39:52.000000000 +0200
701 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/io_apic.c 2003-07-28 20:01:58.000000000 +0200
702 @@ -63,7 +63,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
703   */
704  
705  static struct irq_pin_list {
706 -       int apic, pin, next;
707 +       short apic, pin, next;
708  } irq_2_pin[PIN_MAP_SIZE];
709  
710  /*
711 @@ -1781,3 +1781,21 @@ int io_apic_set_pci_routing (int ioapic,
712  }
713  
714  #endif /*CONFIG_ACPI_BOOT*/
715 +
716 +#ifndef CONFIG_SMP
717 +void send_IPI_self(int vector)
718 +{
719 +       unsigned int cfg;
720 +       
721 +       /*
722 +        * Wait for idle.
723 +        */
724 +       apic_wait_icr_idle();
725 +       cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
726 +
727 +       /*
728 +        * Send the IPI. The write to APIC_ICR fires this off.
729 +        */
730 +       apic_write_around(APIC_ICR, cfg);
731 +}
732 +#endif
733 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/ioport.c linux-2.6.0test2-amd64/arch/x86_64/kernel/ioport.c
734 --- linux/arch/x86_64/kernel/ioport.c   2003-05-27 03:00:26.000000000 +0200
735 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/ioport.c  2003-07-29 01:28:09.000000000 +0200
736 @@ -51,42 +51,50 @@ static void set_bitmap(unsigned long *bi
737         }
738  }
739  
740 +
741  /*
742   * this changes the io permissions bitmap in the current task.
743   */
744  asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
745  {
746         struct thread_struct * t = &current->thread;
747 -       struct tss_struct * tss;
748 -       int ret = 0;
749 +       int cpu = get_cpu(); 
750  
751         if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
752                 return -EINVAL;
753         if (turn_on && !capable(CAP_SYS_RAWIO))
754                 return -EPERM;
755  
756 +       struct tss_struct * tss = init_tss + cpu; 
757 +
758 +       /*
759 +        * If it's the first ioperm() call in this thread's lifetime, set the
760 +        * IO bitmap up. ioperm() is much less timing critical than clone(),
761 +        * this is why we delay this operation until now:
762 +        */
763         if (!t->io_bitmap_ptr) { 
764 -               t->io_bitmap_ptr = kmalloc((IO_BITMAP_SIZE+1)*4, GFP_KERNEL);
765 +               t->io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
766                 if (!t->io_bitmap_ptr) { 
767 -                       ret = -ENOMEM;
768 -                       goto out;
769 -               }
770 -               memset(t->io_bitmap_ptr,0xff,(IO_BITMAP_SIZE+1)*4);
771 -               tss  = init_tss + get_cpu();
772 -               tss->io_map_base = IO_BITMAP_OFFSET;
773                 put_cpu(); 
774 +                       return -ENOMEM; 
775 +               }
776 +
777 +               memset(t->io_bitmap_ptr,0xff,IO_BITMAP_BYTES);
778         }
779 -       tss = init_tss + get_cpu();
780  
781         /*
782          * do it in the per-thread copy and in the TSS ...
783          */
784         set_bitmap((unsigned long *) t->io_bitmap_ptr, from, num, !turn_on);
785 +       if (tss->io_map_base != IO_BITMAP_OFFSET) { 
786 +               memcpy(tss->io_bitmap, t->io_bitmap_ptr, sizeof(tss->io_bitmap));
787 +               tss->io_map_base = IO_BITMAP_OFFSET;
788 +       } else { 
789         set_bitmap((unsigned long *) tss->io_bitmap, from, num, !turn_on);
790 +       }
791  
792 - out:
793         put_cpu();
794 -       return ret;
795 +       return 0;
796  }
797  
798  /*
799 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/mpparse.c linux-2.6.0test2-amd64/arch/x86_64/kernel/mpparse.c
800 --- linux/arch/x86_64/kernel/mpparse.c  2003-05-27 03:00:28.000000000 +0200
801 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/mpparse.c 2003-07-18 02:07:00.000000000 +0200
802 @@ -41,8 +41,10 @@ int acpi_found_madt;
803   * MP-table.
804   */
805  int apic_version [MAX_APICS];
806 -int mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
807 +unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
808  int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
809 +unsigned long mp_bus_to_cpumask [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1UL };
810 +
811  int mp_current_pci_id = 0;
812  /* I/O APIC entries */
813  struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
814 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/nmi.c linux-2.6.0test2-amd64/arch/x86_64/kernel/nmi.c
815 --- linux/arch/x86_64/kernel/nmi.c      2003-07-18 02:39:52.000000000 +0200
816 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/nmi.c     2003-07-11 13:34:21.000000000 +0200
817 @@ -141,14 +141,14 @@ void disable_lapic_nmi_watchdog(void)
818         /* tell do_nmi() and others that we're not active any more */
819         nmi_watchdog = 0;
820  }
821 +
822  void enable_lapic_nmi_watchdog(void)
823 -  {
824 +{
825         if (nmi_active < 0) {
826                 nmi_watchdog = NMI_LOCAL_APIC;
827                 setup_apic_nmi_watchdog();
828         }
829 -  }
830 -
831 +}
832  
833  void disable_timer_nmi_watchdog(void)
834  {
835 @@ -173,8 +173,6 @@ void enable_timer_nmi_watchdog(void)
836  
837  #ifdef CONFIG_PM
838  
839 -#include <linux/device.h>
840 -
841  static int nmi_pm_active; /* nmi_active before suspend */
842  
843  static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
844 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/pci-dma.c linux-2.6.0test2-amd64/arch/x86_64/kernel/pci-dma.c
845 --- linux/arch/x86_64/kernel/pci-dma.c  2003-05-27 03:00:58.000000000 +0200
846 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/pci-dma.c 2003-07-13 21:56:27.000000000 +0200
847 @@ -9,8 +9,6 @@
848  #include <linux/module.h>
849  #include <asm/io.h>
850  
851 -dma_addr_t bad_dma_address = -1UL; 
852 -
853  /* Map a set of buffers described by scatterlist in streaming
854   * mode for DMA.  This is the scatter-gather version of the
855   * above pci_map_single interface.  Here the scatter gather list
856 @@ -34,16 +32,9 @@ int pci_map_sg(struct pci_dev *hwdev, st
857         BUG_ON(direction == PCI_DMA_NONE);
858         for (i = 0; i < nents; i++ ) {
859                 struct scatterlist *s = &sg[i];
860 -
861                 BUG_ON(!s->page); 
862 -
863                         s->dma_address = pci_map_page(hwdev, s->page, s->offset, 
864                                                       s->length, direction); 
865 -
866 -               if (unlikely(s->dma_address == bad_dma_address)) {
867 -       pci_unmap_sg(hwdev, sg, i, direction); 
868 -       return 0; 
869 -               }
870         }
871         return nents;
872  }
873 @@ -67,3 +58,4 @@ void pci_unmap_sg(struct pci_dev *dev, s
874  }
875  
876  EXPORT_SYMBOL(pci_unmap_sg);
877 +
878 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/pci-gart.c linux-2.6.0test2-amd64/arch/x86_64/kernel/pci-gart.c
879 --- linux/arch/x86_64/kernel/pci-gart.c 2003-07-18 02:39:52.000000000 +0200
880 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/pci-gart.c        2003-07-18 02:35:34.000000000 +0200
881 @@ -8,20 +8,8 @@
882   * See Documentation/DMA-mapping.txt for the interface specification.
883   * 
884   * Copyright 2002 Andi Kleen, SuSE Labs.
885 - * $Id: pci-gart.c,v 1.20 2003/03/12 08:23:29 ak Exp $
886   */
887  
888 -/* 
889 - * Notebook:
890 -
891 -possible future tuning: 
892 - fast path for sg streaming mappings - only take the locks once.
893 - more intelligent flush strategy - flush only the NB of the CPU directly
894 - connected to the device?
895 - move boundary between IOMMU and AGP in GART dynamically
896 -  
897 -*/ 
898 -
899  #include <linux/config.h>
900  #include <linux/types.h>
901  #include <linux/ctype.h>
902 @@ -32,6 +20,7 @@ possible future tuning: 
903  #include <linux/spinlock.h>
904  #include <linux/pci.h>
905  #include <linux/module.h>
906 +#include <linux/topology.h>
907  #include <asm/io.h>
908  #include <asm/mtrr.h>
909  #include <asm/bitops.h>
910 @@ -41,6 +30,8 @@ possible future tuning: 
911  #include <asm/kdebug.h>
912  #include <asm/proto.h>
913  
914 +dma_addr_t bad_dma_address;
915 +
916  unsigned long iommu_bus_base;  /* GART remapping area (physical) */
917  static unsigned long iommu_size;       /* size of remapping area bytes */
918  static unsigned long iommu_pages;      /* .. and in pages */
919 @@ -50,9 +41,9 @@ u32 *iommu_gatt_base;                 /* Remapping tab
920  int no_iommu; 
921  static int no_agp; 
922  #ifdef CONFIG_IOMMU_DEBUG
923 -int force_mmu = 1;
924 +int force_iommu = 1;
925  #else
926 -int force_mmu = 0;
927 +int force_iommu = 0;
928  #endif
929  
930  /* Allocation bitmap for the remapping area */ 
931 @@ -65,12 +56,18 @@ static unsigned long *iommu_gart_bitmap;
932         (((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
933  #define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))
934  
935 +#define to_pages(addr,size) \
936 +       (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT)
937 +
938  #define for_all_nb(dev) \
939 -       dev=NULL; \
940 -       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) \
941 -               if (dev->bus->number == 0 && PCI_FUNC(dev->devfn) == 3 && \
942 +       dev = NULL;     \
943 +       while ((dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, dev))!=NULL)\
944 +            if (dev->bus->number == 0 &&                                    \
945                     (PCI_SLOT(dev->devfn) >= 24) && (PCI_SLOT(dev->devfn) <= 31))
946  
947 +static struct pci_dev *northbridges[NR_CPUS + 1];
948 +static u32 northbridge_flush_word[NR_CPUS + 1];
949 +
950  #define EMERGENCY_PAGES 32 /* = 128KB */ 
951  
952  #ifdef CONFIG_AGP
953 @@ -110,32 +107,44 @@ static unsigned long alloc_iommu(int siz
954  
955  static void free_iommu(unsigned long offset, int size)
956  { 
957 +       if (size == 1) { 
958 +               clear_bit(offset, iommu_gart_bitmap); 
959 +               return;
960 +       }
961         unsigned long flags;
962         spin_lock_irqsave(&iommu_bitmap_lock, flags);
963 -       clear_bit_string(iommu_gart_bitmap, offset, size);
964 +       __clear_bit_string(iommu_gart_bitmap, offset, size);
965         spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
966  } 
967  
968 -static inline void flush_gart(void) 
969 +/* 
970 + * Only flush the aperture on the CPU the PCI bridge is connected to.
971 + */
972 +static void flush_gart(int bus) 
973  { 
974 -       struct pci_dev *nb; 
975 -       for_all_nb(nb) { 
976 -               u32 flag; 
977 -               pci_read_config_dword(nb, 0x9c, &flag); /* could cache this */ 
978 -               /* could complain for PTE walk errors here (bit 1 of flag) */ 
979 -               flag |= 1; 
980 -               pci_write_config_dword(nb, 0x9c, flag); 
981 +       int flushed = 0;
982 +       int i;
983 +       for (i = 0; northbridges[i]; i++) { 
984 +               if (bus >= 0 && !(pcibus_to_cpumask(bus) & (1UL << i))) 
985 +                       continue;
986 +               pci_write_config_dword(northbridges[i], 0x9c, 
987 +                                      northbridge_flush_word[i] | 1); 
988 +               flushed++;
989         } 
990 +       if (!flushed) 
991 +               printk("nothing to flush? %d\n", bus);
992  } 
993  
994 +/* 
995 + * Allocate memory for a consistent mapping.
996 + * All mappings are consistent here, so this is just a wrapper around
997 + * pci_map_single.
998 + */
999  void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
1000                            dma_addr_t *dma_handle)
1001  {
1002         void *memory;
1003         int gfp = GFP_ATOMIC;
1004 -       int i;
1005 -       int flush = 0;
1006 -       unsigned long iommu_page;
1007         unsigned long dma_mask;
1008  
1009         if (hwdev == NULL) {
1010 @@ -149,20 +158,14 @@ void *pci_alloc_consistent(struct pci_de
1011         if (dma_mask < 0xffffffff || no_iommu)
1012                 gfp |= GFP_DMA;
1013  
1014 -       /* 
1015 -        * First try to allocate continuous and use directly if already 
1016 -        * in lowmem. 
1017 -        */ 
1018 -       size = round_up(size, PAGE_SIZE); 
1019         memory = (void *)__get_free_pages(gfp, get_order(size));
1020         if (memory == NULL) {
1021                 return NULL; 
1022         } else {
1023 -               int high = 0, mmu;
1024 -               if (((unsigned long)virt_to_bus(memory) + size) > dma_mask)
1025 -                       high = 1;
1026 -               mmu = 1;
1027 -               if (force_mmu && !(gfp & GFP_DMA)) 
1028 +               int high, mmu;
1029 +               high = ((unsigned long)virt_to_bus(memory) + size) >= dma_mask;
1030 +               mmu = high;
1031 +               if (force_iommu && !(gfp & GFP_DMA)) 
1032                         mmu = 1;
1033                 if (no_iommu) { 
1034                         if (high) goto error;
1035 @@ -175,27 +178,13 @@ void *pci_alloc_consistent(struct pci_de
1036                 }
1037         } 
1038  
1039 -       size >>= PAGE_SHIFT;
1040 -
1041 -       iommu_page = alloc_iommu(size, &flush);
1042 -       if (iommu_page == -1)
1043 +       *dma_handle = pci_map_single(hwdev, memory, size, 0);
1044 +       if (*dma_handle == bad_dma_address)
1045                 goto error; 
1046  
1047 -       /* Fill in the GATT */
1048 -       for (i = 0; i < size; i++) { 
1049 -               unsigned long phys_mem; 
1050 -               void *mem = memory + i*PAGE_SIZE;
1051 -               phys_mem = virt_to_phys(mem); 
1052 -               BUG_ON(phys_mem & ~PHYSICAL_PAGE_MASK); 
1053 -               iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); 
1054 -       } 
1055 -
1056 -       if (flush) 
1057 -       flush_gart();
1058 -       *dma_handle = iommu_bus_base + (iommu_page << PAGE_SHIFT);
1059         return memory; 
1060         
1061 - error:
1062 +error:
1063         free_pages((unsigned long)memory, get_order(size)); 
1064         return NULL; 
1065  }
1066 @@ -207,25 +196,17 @@ void *pci_alloc_consistent(struct pci_de
1067  void pci_free_consistent(struct pci_dev *hwdev, size_t size,
1068                          void *vaddr, dma_addr_t bus)
1069  {
1070 -       unsigned long iommu_page;
1071 -
1072 -       size = round_up(size, PAGE_SIZE); 
1073 -       if (bus >= iommu_bus_base && bus <= iommu_bus_base + iommu_size) { 
1074 -               unsigned pages = size >> PAGE_SHIFT;
1075 -               int i;
1076 -               iommu_page = (bus - iommu_bus_base) >> PAGE_SHIFT;
1077 -               vaddr = __va(GPTE_DECODE(iommu_gatt_base[iommu_page]));
1078 -               for (i = 0; i < pages; i++) {
1079 -                       u64 pte = iommu_gatt_base[iommu_page + i];
1080 -               BUG_ON((pte & GPTE_VALID) == 0); 
1081 -               iommu_gatt_base[iommu_page + i] = 0;            
1082 -       } 
1083 -               free_iommu(iommu_page, pages);
1084 -       }
1085 +       pci_unmap_single(hwdev, bus, size, 0);
1086         free_pages((unsigned long)vaddr, get_order(size));              
1087  }
1088  
1089  #ifdef CONFIG_IOMMU_LEAK
1090 +
1091 +#define SET_LEAK(x) if (iommu_leak_tab) \
1092 +                       iommu_leak_tab[x] = __builtin_return_address(0);
1093 +#define CLEAR_LEAK(x) if (iommu_leak_tab) \
1094 +                       iommu_leak_tab[x] = 0;
1095 +
1096  /* Debugging aid for drivers that don't free their IOMMU tables */
1097  static void **iommu_leak_tab; 
1098  static int leak_trace;
1099 @@ -246,9 +227,12 @@ void dump_leak(void)
1100         } 
1101         printk("\n");
1102  }
1103 +#else
1104 +#define SET_LEAK(x)
1105 +#define CLEAR_LEAK(x)
1106  #endif
1107  
1108 -static void iommu_full(struct pci_dev *dev, void *addr, size_t size, int dir)
1109 +static void iommu_full(struct pci_dev *dev, size_t size, int dir)
1110  {
1111         /* 
1112          * Ran out of IOMMU space for this operation. This is very bad.
1113 @@ -261,8 +245,8 @@ static void iommu_full(struct pci_dev *d
1114          */ 
1115         
1116         printk(KERN_ERR 
1117 -  "PCI-DMA: Out of IOMMU space for %p size %lu at device %s[%s]\n",
1118 -              addr,size, dev ? dev->dev.name : "?", dev ? dev->slot_name : "?");
1119 +  "PCI-DMA: Out of IOMMU space for %lu bytes at device %s[%s]\n",
1120 +              size, dev ? dev->dev.name : "?", dev ? dev->slot_name : "?");
1121  
1122         if (size > PAGE_SIZE*EMERGENCY_PAGES) {
1123                 if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
1124 @@ -279,23 +263,60 @@ static void iommu_full(struct pci_dev *d
1125  static inline int need_iommu(struct pci_dev *dev, unsigned long addr, size_t size)
1126  { 
1127         u64 mask = dev ? dev->dma_mask : 0xffffffff;
1128 -       int high = (~mask & (unsigned long)(addr + size)) != 0;
1129 +       int high = addr + size >= mask;
1130         int mmu = high;
1131 -       if (force_mmu) 
1132 +       if (force_iommu) 
1133                 mmu = 1; 
1134         if (no_iommu) { 
1135                 if (high) 
1136 -                       panic("pci_map_single: high address but no IOMMU.\n"); 
1137 +                       panic("PCI-DMA: high address but no IOMMU.\n"); 
1138                 mmu = 0; 
1139         }       
1140         return mmu; 
1141  }
1142  
1143 -dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size, int dir)
1144 +static inline int nonforced_iommu(struct pci_dev *dev, unsigned long addr, size_t size)
1145 +{ 
1146 +       u64 mask = dev ? dev->dma_mask : 0xffffffff;
1147 +       int high = addr + size >= mask;
1148 +       int mmu = high;
1149 +       if (no_iommu) { 
1150 +               if (high) 
1151 +                       panic("PCI-DMA: high address but no IOMMU.\n"); 
1152 +               mmu = 0; 
1153 +       }       
1154 +       return mmu; 
1155 +}
1156 +
1157 +/* Map a single continuous physical area into the IOMMU.
1158 + * Caller needs to check if the iommu is needed and flush.
1159 + */
1160 +static dma_addr_t pci_map_area(struct pci_dev *dev, unsigned long phys_mem, 
1161 +                               size_t size, int *flush, int dir)
1162 +{ 
1163 +       unsigned long npages = to_pages(phys_mem, size);
1164 +       unsigned long iommu_page = alloc_iommu(npages, flush);
1165 +       if (iommu_page == -1) {
1166 +               if (!nonforced_iommu(dev, phys_mem, size))
1167 +                       return phys_mem; 
1168 +               iommu_full(dev, size, dir);
1169 +               return bad_dma_address;
1170 +       }
1171 +
1172 +       int i;
1173 +       for (i = 0; i < npages; i++) {
1174 +               iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
1175 +               SET_LEAK(iommu_page + i);
1176 +               phys_mem += PAGE_SIZE;
1177 +       }
1178 +       return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK);
1179 +}
1180 +
1181 +/* Map a single area into the IOMMU */
1182 +dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size, 
1183 +                                                int dir)
1184  { 
1185 -       unsigned long iommu_page;
1186         unsigned long phys_mem, bus;
1187 -       int i, npages;
1188         int flush = 0;
1189  
1190         BUG_ON(dir == PCI_DMA_NONE);
1191 @@ -304,39 +325,154 @@ dma_addr_t pci_map_single(struct pci_dev
1192         if (!need_iommu(dev, phys_mem, size))
1193                 return phys_mem; 
1194  
1195 -       npages = round_up(size + ((u64)addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
1196 +       bus = pci_map_area(dev, phys_mem, size, &flush, dir);
1197 +       if (flush)
1198 +               flush_gart(dev->bus->number); 
1199 +       return bus; 
1200 +} 
1201  
1202 -       iommu_page = alloc_iommu(npages, &flush); 
1203 -       if (iommu_page == -1) {
1204 -               iommu_full(dev, addr, size, dir); 
1205 -               return iommu_bus_base; 
1206 +/* Fallback for pci_map_sg in case of overflow */ 
1207 +static int pci_map_sg_nonforce(struct pci_dev *dev, struct scatterlist *sg,
1208 +                              int nents, int dir)
1209 +{
1210 +       int i;
1211 +       int flush = 0;
1212 +       for (i = 0; i < nents; i++ ) {
1213 +               struct scatterlist *s = &sg[i];
1214 +               unsigned long addr = page_to_phys(s->page) + s->offset; 
1215 +               if (nonforced_iommu(dev, addr, s->length)) { 
1216 +                       addr = pci_map_area(dev, addr, s->length, &flush, dir); 
1217 +                       if (addr == bad_dma_address) { 
1218 +                               if (i > 0) 
1219 +                                       pci_unmap_sg(dev, sg, i, dir); 
1220 +                               nents = 0; 
1221 +                               break;
1222         } 
1223 +               }
1224 +               s->dma_address = addr;
1225 +       }
1226 +       if (flush) 
1227 +               flush_gart(dev->bus->number);
1228 +       return nents;
1229 +}
1230  
1231 -       phys_mem &= PAGE_MASK;
1232 -       for (i = 0; i < npages; i++, phys_mem += PAGE_SIZE) {
1233 -               BUG_ON(phys_mem & ~PHYSICAL_PAGE_MASK); 
1234 +/* Map multiple scatterlist entries continuous into the first. */
1235 +static int __pci_map_cont(struct scatterlist *sg, int start, int stopat, 
1236 +                     struct scatterlist *sout,
1237 +                     unsigned long pages, int *flush)
1238 +{
1239 +       unsigned long iommu_start = alloc_iommu(pages, flush);
1240 +       if (iommu_start == -1)
1241 +               return -1;
1242                 
1243 -               /* 
1244 -                * Set coherent mapping here to avoid needing to flush
1245 -                * the caches on mapping.
1246 +       unsigned long iommu_page = iommu_start; 
1247 +       int i;
1248 +       
1249 +       for (i = start; i < stopat; i++) {
1250 +               struct scatterlist *s = &sg[i];
1251 +               unsigned long start_addr = s->dma_address;
1252 +               BUG_ON(i > 0 && s->offset);
1253 +               if (i == start) {
1254 +                       *sout = *s; 
1255 +                       sout->dma_address = iommu_bus_base;
1256 +                       sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
1257 +               } else { 
1258 +                       sout->length += s->length; 
1259 +               }
1260 +               unsigned long addr = start_addr;
1261 +               while (addr < start_addr + s->length) { 
1262 +                       iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); 
1263 +                       SET_LEAK(iommu_page);
1264 +                       addr += PAGE_SIZE;
1265 +                       iommu_page++;
1266 +               }
1267 +               BUG_ON(i > 0 && addr % PAGE_SIZE); 
1268 +       } 
1269 +       BUG_ON(iommu_page - iommu_start != pages);      
1270 +       return 0;
1271 +}
1272 +
1273 +static inline int pci_map_cont(struct scatterlist *sg, int start, int stopat, 
1274 +                     struct scatterlist *sout,
1275 +                     unsigned long pages, int *flush, int need)
1276 +{
1277 +       if (!need) { 
1278 +               BUG_ON(stopat - start != 1);
1279 +               if (sout != sg + start)
1280 +                       *sout = sg[start]; 
1281 +               return 0;
1282 +       } 
1283 +       return __pci_map_cont(sg, start, stopat, sout, pages, flush);
1284 +}
1285 +               
1286 +/*
1287 + * DMA map all entries in a scatterlist.
1288 + * Merge chunks that have page aligned sizes into a continuous mapping. 
1289                  */
1290 -               iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
1291 +int pci_map_sg(struct pci_dev *dev, struct scatterlist *sg,
1292 +              int nents, int dir)
1293 +{
1294 +       int i;
1295 +       int out;
1296 +       int flush = 0;
1297 +       int start;
1298 +       unsigned long pages = 0;
1299 +       int need = 0;
1300  
1301 -#ifdef CONFIG_IOMMU_LEAK
1302 -               /* XXX need eventually caller of pci_map_sg */
1303 -               if (iommu_leak_tab) 
1304 -                       iommu_leak_tab[iommu_page + i] = __builtin_return_address(0); 
1305 -#endif
1306 +       BUG_ON(dir == PCI_DMA_NONE);
1307 +       if (nents == 0) 
1308 +               return 0;
1309 +       out = 0;
1310 +       start = 0;
1311 +       for (i = 0; i < nents; i++) {
1312 +               struct scatterlist *s = &sg[i];
1313 +               dma_addr_t addr = page_to_phys(s->page) + s->offset;
1314 +               s->dma_address = addr;
1315 +               BUG_ON(s->length == 0); 
1316 +
1317 +               /* Handle the previous not yet processed entries */
1318 +               if (i > 0) {
1319 +                       struct scatterlist *ps = &sg[i-1];
1320 +                       /* Can only merge when the last chunk ends on a page 
1321 +                          boundary */
1322 +                       if (!need || (i > start+1 && ps->offset) ||
1323 +                           (ps->offset + ps->length) % PAGE_SIZE) { 
1324 +                               if (pci_map_cont(sg, start, i, sg+out, pages, 
1325 +                                                &flush, need) < 0)
1326 +                                       goto error;
1327 +                               out++;
1328 +                               pages = 0;
1329 +                               start = i;              
1330 +                       }
1331         }
1332 -       if (flush)
1333 -       flush_gart(); 
1334  
1335 -       bus = iommu_bus_base + iommu_page*PAGE_SIZE; 
1336 -       return bus + ((unsigned long)addr & ~PAGE_MASK);        
1337 +               need = need_iommu(dev, addr, s->length); 
1338 +               pages += to_pages(s->offset, s->length);
1339 +       }
1340 +       if (pci_map_cont(sg, start, i, sg+out, pages, &flush, need) < 0)
1341 +               goto error;
1342 +       out++;  
1343 +       if (flush)
1344 +               flush_gart(dev->bus->number);
1345 +       if (out < nents) 
1346 +               sg[out].length = 0; 
1347 +       return out;
1348 +
1349 +error:
1350 +       if (out > 0) 
1351 +               flush_gart(-1);
1352 +       pci_unmap_sg(dev, sg, nents, dir);
1353 +       /* When it was forced try again unforced */
1354 +       if (force_iommu) 
1355 +               return pci_map_sg_nonforce(dev, sg, nents, dir);
1356 +       iommu_full(dev, pages << PAGE_SHIFT, dir);      
1357 +       for (i = 0; i < nents; i++)
1358 +               sg[i].dma_address = bad_dma_address;
1359 +       return 0;
1360  } 
1361  
1362  /*
1363 - * Free a temporary PCI mapping.
1364 + * Free a PCI mapping.
1365   */ 
1366  void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
1367                       size_t size, int direction)
1368 @@ -347,20 +483,60 @@ void pci_unmap_single(struct pci_dev *hw
1369             dma_addr > iommu_bus_base + iommu_size)
1370                 return;
1371         iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;   
1372 -       npages = round_up(size + (dma_addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
1373 +       npages = to_pages(dma_addr, size);
1374         int i;
1375         for (i = 0; i < npages; i++) { 
1376                 iommu_gatt_base[iommu_page + i] = 0; 
1377 -#ifdef CONFIG_IOMMU_LEAK
1378 -               if (iommu_leak_tab)
1379 -                       iommu_leak_tab[iommu_page + i] = 0; 
1380 -#endif
1381 +               CLEAR_LEAK(iommu_page + i);
1382         }
1383         free_iommu(iommu_page, npages);
1384  }
1385  
1386 +/* 
1387 + * Wrapper for pci_unmap_single working with scatterlists.
1388 + */ 
1389 +void pci_unmap_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, 
1390 +                 int dir)
1391 +{
1392 +       int i;
1393 +       for (i = 0; i < nents; i++) { 
1394 +               struct scatterlist *s = &sg[i];
1395 +               if (!s->length) 
1396 +                       break;
1397 +               pci_unmap_single(dev, s->dma_address, s->length, dir);
1398 +       }
1399 +}
1400 +
1401 +int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
1402 +{
1403 +       /* Copied from i386. Doesn't make much sense, because it will 
1404 +          only work for pci_alloc_consistent. 
1405 +          The caller just has to use GFP_DMA in this case. */
1406 +        if (mask < 0x00ffffff)
1407 +                return 0;
1408 +
1409 +       /* Tell the device to use SAC. This allows it to use cheaper accesses
1410 +          in some cases.
1411 +          Problem with this is that if we overflow the IOMMU area
1412 +          and return DAC as fallback address the device may not handle it correctly.
1413 +          As a compromise we only do this if the IOMMU area is >= 256MB,
1414 +          which should make overflow unlikely enough. */
1415 +       if (force_iommu && mask > 0xffffffff && iommu_size >= 256*1024*1024) 
1416 +               return 0; 
1417 +
1418 +       if (no_iommu && (~mask & (end_pfn << PAGE_SHIFT)))
1419 +               return 0;
1420 +
1421 +       return 1;
1422 +} 
1423 +
1424 +EXPORT_SYMBOL(pci_unmap_sg);
1425 +EXPORT_SYMBOL(pci_map_sg);
1426  EXPORT_SYMBOL(pci_map_single);
1427  EXPORT_SYMBOL(pci_unmap_single);
1428 +EXPORT_SYMBOL(pci_dma_supported);
1429 +EXPORT_SYMBOL(no_iommu);
1430 +EXPORT_SYMBOL(force_iommu); 
1431  
1432  static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
1433  { 
1434 @@ -452,13 +628,12 @@ static __init int init_k8_gatt(struct ag
1435  
1436                 pci_write_config_dword(dev, 0x90, ctl); 
1437         }
1438 -       flush_gart(); 
1439 +       flush_gart(-1); 
1440         
1441 -       printk("PCI-DMA: aperture base @ %x size %u KB\n", aper_base, aper_size>>10); 
1442 +       printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10); 
1443         return 0;
1444  
1445   nommu:
1446 -       /* XXX: reject 0xffffffff mask now in pci mapping functions */
1447         printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
1448                KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction."); 
1449         return -1; 
1450 @@ -466,11 +641,12 @@ static __init int init_k8_gatt(struct ag
1451  
1452  extern int agp_amdk8_init(void);
1453  
1454 -int __init pci_iommu_init(void)
1455 +static int __init pci_iommu_init(void)
1456  { 
1457         struct agp_kern_info info;
1458         unsigned long aper_size;
1459         unsigned long iommu_start;
1460 +       struct pci_dev *dev;
1461                 
1462  #ifndef CONFIG_AGP_AMD_8151
1463         no_agp = 1; 
1464 @@ -482,7 +658,7 @@ int __init pci_iommu_init(void)
1465                 (agp_copy_info(&info) < 0); 
1466  #endif 
1467  
1468 -       if (no_iommu || (!force_mmu && end_pfn < 0xffffffff>>PAGE_SHIFT)) { 
1469 +       if (no_iommu || (!force_iommu && end_pfn < 0xffffffff>>PAGE_SHIFT)) { 
1470                 printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); 
1471                 no_iommu = 1;
1472                 return -1;
1473 @@ -492,7 +668,7 @@ int __init pci_iommu_init(void)
1474                 int err = -1;
1475                 printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
1476                 no_agp = 1;
1477 -               if (force_mmu || end_pfn >= 0xffffffff>>PAGE_SHIFT)
1478 +               if (force_iommu || end_pfn >= 0xffffffff>>PAGE_SHIFT)
1479                         err = init_k8_gatt(&info);
1480                 if (err < 0) { 
1481                         printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); 
1482 @@ -529,25 +705,38 @@ int __init pci_iommu_init(void)
1483         set_bit_string(iommu_gart_bitmap, 0, EMERGENCY_PAGES); 
1484  
1485         agp_memory_reserved = iommu_size;       
1486 -       printk(KERN_INFO"PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
1487 +       printk(KERN_INFO
1488 +              "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
1489                iommu_size>>20); 
1490  
1491         iommu_start = aper_size - iommu_size;   
1492         iommu_bus_base = info.aper_base + iommu_start; 
1493 -       iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
1494         bad_dma_address = iommu_bus_base;
1495 +       iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
1496  
1497         /* 
1498 -         * Unmap the IOMMU part of the GART. The alias of the page is always mapped
1499 -        * with cache enabled and there is no full cache coherency across the GART
1500 -        * remapping. The unmapping avoids automatic prefetches from the CPU 
1501 -        * allocating cache lines in there. All CPU accesses are done via the 
1502 -        * direct mapping to the backing memory. The GART address is only used by PCI 
1503 +        * Unmap the IOMMU part of the GART. The alias of the page is
1504 +        * always mapped with cache enabled and there is no full cache
1505 +        * coherency across the GART remapping. The unmapping avoids
1506 +        * automatic prefetches from the CPU allocating cache lines in
1507 +        * there. All CPU accesses are done via the direct mapping to
1508 +        * the backing memory. The GART address is only used by PCI
1509          * devices. 
1510          */
1511         clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size);
1512  
1513 -       flush_gart();
1514 +       for_all_nb(dev) {
1515 +               u32 flag; 
1516 +               int cpu = PCI_SLOT(dev->devfn) - 24;
1517 +               if (cpu >= NR_CPUS)
1518 +                       continue;
1519 +               northbridges[cpu] = dev;
1520 +
1521 +               pci_read_config_dword(dev, 0x9c, &flag); /* cache flush word */
1522 +               northbridge_flush_word[cpu] = flag; 
1523 +       }
1524 +                    
1525 +       flush_gart(-1);
1526  
1527         return 0;
1528  } 
1529 @@ -561,8 +750,8 @@ fs_initcall(pci_iommu_init);
1530     off   don't use the IOMMU
1531     leak  turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on)
1532     memaper[=order] allocate an own aperture over RAM with size 32MB^order.  
1533 -   noforce don't force IOMMU usage. Should be fastest.
1534 -   force  Force IOMMU and turn on unmap debugging.
1535 +   noforce don't force IOMMU usage. Default.
1536 +   force  Force IOMMU.
1537  */
1538  __init int iommu_setup(char *opt) 
1539  { 
1540 @@ -575,9 +764,9 @@ __init int iommu_setup(char *opt) 
1541             if (!memcmp(p,"off", 3))
1542                     no_iommu = 1;
1543             if (!memcmp(p,"force", 5))
1544 -                   force_mmu = 1;
1545 +                   force_iommu = 1;
1546             if (!memcmp(p,"noforce", 7))
1547 -                   force_mmu = 0;
1548 +                   force_iommu = 0;
1549             if (!memcmp(p, "memaper", 7)) { 
1550                     fallback_aper_force = 1; 
1551                     p += 7; 
1552 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/pci-nommu.c linux-2.6.0test2-amd64/arch/x86_64/kernel/pci-nommu.c
1553 --- linux/arch/x86_64/kernel/pci-nommu.c        2003-07-18 02:39:30.000000000 +0200
1554 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/pci-nommu.c       2003-07-11 13:34:21.000000000 +0200
1555 @@ -33,15 +33,30 @@ void pci_free_consistent(struct pci_dev 
1556         free_pages((unsigned long)vaddr, get_order(size));
1557  }
1558  
1559 +int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
1560 +{
1561 +        /*
1562 +         * we fall back to GFP_DMA when the mask isn't all 1s,
1563 +         * so we can't guarantee allocations that must be
1564 +         * within a tighter range than GFP_DMA..
1565 +        * XXX: this won't work for pci_map_single. Caller has to
1566 +        * use GFP_DMA in the first place.
1567 +         */
1568 +        if (mask < 0x00ffffff)
1569 +                return 0;
1570 +
1571 +       return 1;
1572 +} 
1573  
1574 -static void __init check_ram(void) 
1575 +EXPORT_SYMBOL(pci_dma_supported);
1576 +
1577 +static int __init check_ram(void) 
1578  { 
1579         if (end_pfn >= 0xffffffff>>PAGE_SHIFT) { 
1580                 printk(KERN_ERR "WARNING more than 4GB of memory but no IOMMU.\n"
1581                        KERN_ERR "WARNING 32bit PCI may malfunction.\n"); 
1582 -               /* Could play with highmem_start_page here to trick some subsystems
1583 -                  into bounce buffers. Unfortunately that would require setting
1584 -                  CONFIG_HIGHMEM too. 
1585 -                */ 
1586         } 
1587 +       return 0;
1588  } 
1589 +__initcall(check_ram);
1590 +
1591 diff -burpN -X ../KDIFX linux/arch/x86_64/kernel/setup64.c linux-2.6.0test2-amd64/arch/x86_64/kernel/setup64.c
1592 --- linux/arch/x86_64/kernel/setup64.c  2003-07-18 02:40:03.000000000 +0200
1593 +++ linux-2.6.0test2-amd64/arch/x86_64/kernel/setup64.c 2003-07-29 03:01:39.000000000 +0200
1594 @@ -114,32 +114,37 @@ Valid options: 
1595  
1596  __setup("noexec32=", nonx32_setup); 
1597  
1598 -#ifndef  __GENERIC_PER_CPU
1599 -
1600 -unsigned long __per_cpu_offset[NR_CPUS];
1601 -
1602 +/* 
1603 + * Great future plan: 
1604 + * Declare PDA itself and support (irqstack,tss,pml4) as per cpu data.
1605 + * Always point %gs to its beginning
1606 + */
1607  void __init setup_per_cpu_areas(void)
1608  { 
1609 -       unsigned long size, i;
1610 -       unsigned char *ptr;
1611 +       int i;
1612 +       unsigned long size;
1613  
1614         /* Copy section for each CPU (we discard the original) */
1615         size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
1616 -       if (!size)
1617 -               return;
1618 +#ifdef CONFIG_MODULES
1619 +       if (size < PERCPU_ENOUGH_ROOM)
1620 +               size = PERCPU_ENOUGH_ROOM;
1621 +#endif
1622 +
1623 +       /* We don't support CPU hotplug, so only allocate as much as needed here */
1624  
1625 -       ptr = alloc_bootmem(size * NR_CPUS);
1626 +       int maxi = max_t(unsigned, numnodes, num_online_cpus()); 
1627  
1628 -       for (i = 0; i < NR_CPUS; i++, ptr += size) {
1629 -               /* hide this from the compiler to avoid problems */ 
1630 -               unsigned long offset;
1631 -               asm("subq %[b],%0" : "=r" (offset) : "0" (ptr), [b] "r" (&__per_cpu_start));
1632 -               __per_cpu_offset[i] = offset;
1633 -               cpu_pda[i].cpudata_offset = offset;
1634 -               memcpy(ptr, __per_cpu_start, size);
1635 +       for (i = 0; i < maxi; i++) { 
1636 +               /* If possible allocate on the node of the CPU.
1637 +                  In case it doesn't exist round-robin nodes. */
1638 +               unsigned char *ptr = alloc_bootmem_node(NODE_DATA(i % numnodes), size);
1639 +               if (!ptr)
1640 +                       panic("Cannot allocate cpu data for CPU %d\n", i);
1641 +               cpu_pda[i].data_offset = ptr - __per_cpu_start;
1642 +               memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
1643         }
1644  } 
1645 -#endif
1646  
1647  void pda_init(int cpu)
1648  { 
1649 @@ -153,7 +158,7 @@ void pda_init(int cpu)
1650         pda->me = pda;
1651         pda->cpunumber = cpu; 
1652         pda->irqcount = -1;
1653 -       pda->cpudata_offset = 0;
1654 +       pda->data_offset = 0;
1655         pda->kernelstack = 
1656                 (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; 
1657         pda->active_mm = &init_mm;
1658 diff -burpN -X ../KDIFX linux/arch/x86_64/mm/extable.c linux-2.6.0test2-amd64/arch/x86_64/mm/extable.c
1659 --- linux/arch/x86_64/mm/extable.c      2003-05-27 03:00:58.000000000 +0200
1660 +++ linux-2.6.0test2-amd64/arch/x86_64/mm/extable.c     2003-07-15 15:49:55.000000000 +0200
1661 @@ -5,6 +5,7 @@
1662  #include <linux/config.h>
1663  #include <linux/module.h>
1664  #include <linux/spinlock.h>
1665 +#include <linux/init.h>
1666  #include <asm/uaccess.h>
1667  
1668  /* Simple binary search */
1669 @@ -28,3 +29,29 @@ search_extable(const struct exception_ta
1670          }
1671          return NULL;
1672  }
1673 +
1674 +/* When an exception handler is in an non standard section (like __init) 
1675 +   the fixup table can end up unordered. Fix that here. */
1676 +static __init int check_extable(void)
1677 +{ 
1678 +       extern struct exception_table_entry __start___ex_table[];
1679 +       extern struct exception_table_entry  __stop___ex_table[];
1680 +       struct exception_table_entry *e;
1681 +       int change; 
1682 +
1683 +       /* The input is near completely presorted, which makes bubble sort the
1684 +          best (and simplest) sort algorithm. */
1685 +       do { 
1686 +               change = 0;
1687 +               for (e = __start___ex_table+1; e < __stop___ex_table; e++) {
1688 +                       if (e->insn < e[-1].insn) { 
1689 +                               struct exception_table_entry tmp = e[-1];
1690 +                               e[-1] = e[0];
1691 +                               e[0] = tmp;
1692 +                               change = 1; 
1693 +                       } 
1694 +               } 
1695 +       } while (change != 0); 
1696 +       return 0;
1697 +} 
1698 +core_initcall(check_extable);
1699 diff -burpN -X ../KDIFX linux/drivers/char/agp/Kconfig linux-2.6.0test2-amd64/drivers/char/agp/Kconfig
1700 --- linux/drivers/char/agp/Kconfig      2003-07-18 02:39:06.000000000 +0200
1701 +++ linux-2.6.0test2-amd64/drivers/char/agp/Kconfig     2003-07-14 18:39:56.000000000 +0200
1702 @@ -53,15 +53,19 @@ config AGP_AMD
1703           You should say Y here if you use XFree86 3.3.6 or 4.x and want to
1704           use GLX or DRI.  If unsure, say N.
1705  
1706 +# RED-PEN this option is misnamed, it's not 8151 specific
1707  config AGP_AMD_8151
1708         tristate "AMD Opteron/Athlon64 on-CPU GART support"
1709         depends on AGP && X86
1710         default GART_IOMMU
1711         help
1712           This option gives you AGP support for the GLX component of
1713 -         XFree86 4.x using the on-CPU AGP bridge of the AMD Athlon64/Opteron CPUs.
1714 +         XFree86 4.x using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
1715 +         You still need an external AGP bridge like the AMD 8151, VIA
1716 +          K8T400M, SiS755. It may also support other AGP bridges when loaded
1717 +         with agp_try_unsupported=1.
1718           You should say Y here if you use XFree86 3.3.6 or 4.x and want to
1719 -         use GLX or DRI.  If unsure, say N
1720 +         use GLX or DRI.  If unsure, say Y
1721  
1722  config AGP_INTEL
1723         tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support"
1724 diff -burpN -X ../KDIFX linux/drivers/char/agp/amd-k8-agp.c linux-2.6.0test2-amd64/drivers/char/agp/amd-k8-agp.c
1725 --- linux/drivers/char/agp/amd-k8-agp.c 2003-07-18 02:42:38.000000000 +0200
1726 +++ linux-2.6.0test2-amd64/drivers/char/agp/amd-k8-agp.c        2003-07-14 20:45:20.000000000 +0200
1727 @@ -21,7 +21,11 @@
1728  #include "agp.h"
1729  
1730  /* Will need to be increased if hammer ever goes >8-way. */
1731 +#ifdef CONFIG_SMP
1732  #define MAX_HAMMER_GARTS   8
1733 +#else
1734 +#define MAX_HAMMER_GARTS   1
1735 +#endif
1736  
1737  /* PTE bits. */
1738  #define GPTE_VALID     1
1739 @@ -39,6 +43,8 @@
1740  static int nr_garts;
1741  static struct pci_dev * hammers[MAX_HAMMER_GARTS];
1742  
1743 +static int __initdata agp_try_unsupported;
1744 +
1745  static int gart_iterator;
1746  #define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
1747  
1748 @@ -246,24 +252,94 @@ struct agp_bridge_driver amd_8151_driver
1749         .agp_destroy_page       = agp_generic_destroy_page,
1750  };
1751  
1752 +/* Some basic sanity checks for the aperture. */
1753 +static int __init aperture_valid(u64 aper, u32 size)
1754 +{ 
1755 +       u32 pfn, c;
1756 +       if (aper == 0)
1757 +               return 0; 
1758 +       if (size < 32*1024*1024) {
1759 +               printk(KERN_INFO "Aperture too small (%d MB)\n", size>>20);
1760 +               return 0;
1761 +       }
1762 +       if (aper + size > 0xffffffff) { 
1763 +               printk(KERN_INFO "Aperture out of bounds\n"); 
1764 +               return 0;
1765 +       } 
1766 +       pfn = aper >> PAGE_SHIFT;
1767 +       for (c = 0; c < size/PAGE_SIZE; c++) { 
1768 +               if (!pfn_valid(pfn + c))
1769 +                       break;
1770 +               if (!PageReserved(pfn_to_page(pfn + c))) { 
1771 +                       printk(KERN_INFO "Aperture pointing to RAM\n");
1772 +                       return 0;
1773 +               }
1774 +       }
1775 +       return 1;
1776 +} 
1777  
1778 -#ifdef CONFIG_SMP
1779 -static int cache_nbs (void)
1780 +/* 
1781 + * W*s centric BIOS sometimes only set up the aperture in the AGP
1782 + * bridge, not the northbridge. On AMD64 this is handled early 
1783 + * in aperture.c, but when GART_IOMMU is not enabled or we run
1784 + * on a 32bit kernel this needs to be redone. 
1785 + */ 
1786 +static __init int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, 
1787 +                                                                u16 cap)
1788 +{
1789 +       u32 aper_low, aper_hi;
1790 +       u64 aper, nb_aper;
1791 +       int order = 0;
1792 +       u32 nb_order, nb_base;
1793 +       u16 apsize;
1794 +
1795 +       pci_read_config_dword(nb, 0x90, &nb_order); 
1796 +       nb_order = (nb_order >> 1) & 7;
1797 +       pci_read_config_dword(nb, 0x94, &nb_base); 
1798 +       nb_aper = nb_base << 25;        
1799 +       if (aperture_valid(nb_aper, (32*1024*1024)<<nb_order))
1800 +               return 0;
1801 +
1802 +       /* Northbridge seems to contain crap. Try the AGP bridge. */
1803 +
1804 +       pci_read_config_word(agp, cap+0x14, &apsize); 
1805 +       if (apsize == 0xffff) 
1806 +               return -1; 
1807 +
1808 +       apsize &= 0xfff;
1809 +       order = 7 - hweight16(apsize); 
1810 +       pci_read_config_dword(agp, 0x10, &aper_low);
1811 +       pci_read_config_dword(agp, 0x14, &aper_hi);
1812 +       aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); 
1813 +       printk(KERN_INFO "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order);
1814 +       if (order < 0 || !aperture_valid(aper, (32*1024*1024)<<order))
1815 +               return -1; 
1816 +       
1817 +       pci_write_config_dword(nb, 0x90, order << 1); 
1818 +       pci_write_config_dword(nb, 0x94, aper >> 25); 
1819 +
1820 +       return 0;
1821 +} 
1822 +
1823 +static __init int cache_nbs (struct pci_dev *pdev, u32 cap_ptr)
1824  {
1825         struct pci_dev *loop_dev = NULL;
1826         int i = 0;
1827  
1828         /* cache pci_devs of northbridges. */
1829 -       while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) != NULL) {
1830 +       while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) 
1831 +                       != NULL) {
1832 +               if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) 
1833 +                       return -1;  
1834                 hammers[i++] = loop_dev;
1835                 nr_garts = i;
1836 -               if (i == MAX_HAMMER_GARTS)
1837 +               if (i == MAX_HAMMER_GARTS) { 
1838 +                       printk(KERN_INFO "Too many northbridges for AGP\n");
1839                         return -1;
1840         }
1841 -       return 0;
1842 +       }
1843 +       return i == 0 ? -1 : 0;
1844  }
1845 -#endif
1846 -
1847  
1848  static int __init agp_amdk8_probe(struct pci_dev *pdev,
1849                                   const struct pci_device_id *ent)
1850 @@ -277,7 +353,7 @@ static int __init agp_amdk8_probe(struct
1851         if (!cap_ptr)
1852                 return -ENODEV;
1853  
1854 -       printk(KERN_INFO PFX "Detected Opteron/Athlon64 on-CPU GART\n");
1855 +       /* Could check for AGPv3 here */
1856  
1857         bridge = agp_alloc_bridge();
1858         if (!bridge)
1859 @@ -311,6 +387,9 @@ static int __init agp_amdk8_probe(struct
1860                         bridge->major_version = 3;
1861                         bridge->minor_version = 0;
1862                 }
1863 +       } else {
1864 +               printk(KERN_INFO PFX "Detected AGP bridge %x\n",
1865 +                       pdev->devfn);
1866         }
1867  
1868         bridge->driver = &amd_8151_driver;
1869 @@ -320,22 +399,10 @@ static int __init agp_amdk8_probe(struct
1870         /* Fill in the mode register */
1871         pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
1872  
1873 -#ifdef CONFIG_SMP
1874 -       if (cache_nbs() == -1) {
1875 +       if (cache_nbs(pdev, cap_ptr) == -1) {
1876                 agp_put_bridge(bridge);
1877 -               return -ENOMEM;
1878 -       }
1879 -#else
1880 -       {
1881 -       struct pci_dev *loop_dev = NULL;
1882 -       while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) != NULL) {
1883 -               /* For UP, we only care about the first GART. */
1884 -               hammers[0] = loop_dev;
1885 -               nr_garts = 1;
1886 -               break;
1887 -       }
1888 +               return -ENODEV;
1889         }
1890 -#endif
1891  
1892         pci_set_drvdata(pdev, bridge);
1893         return agp_add_bridge(bridge);
1894 @@ -389,7 +456,29 @@ static struct pci_driver agp_amdk8_pci_d
1895  /* Not static due to IOMMU code calling it early. */
1896  int __init agp_amdk8_init(void)
1897  {
1898 -       return pci_module_init(&agp_amdk8_pci_driver);
1899 +       int err = pci_module_init(&agp_amdk8_pci_driver);
1900 +       if (err == -ENODEV) { 
1901 +               struct pci_dev *dev;
1902 +               if (!agp_try_unsupported) { 
1903 +                       printk(KERN_INFO "No supported AGP bridge found.\n");
1904 +                       printk(KERN_INFO "You can try agp_try_unsupported=1\n");
1905 +                       return err;
1906 +               }
1907 +
1908 +               /* First check that we have at least one K8 NB */
1909 +               if (!pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL))
1910 +                       return -ENODEV;
1911 +
1912 +               /* Look for any AGP bridge */
1913 +               dev = NULL;
1914 +               while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev))) {
1915 +                       if (!pci_find_capability(dev, PCI_CAP_ID_AGP))
1916 +                               continue;
1917 +                       if (agp_amdk8_probe(dev, NULL) == 0)
1918 +                               err = 0;
1919 +               }               
1920 +       }
1921 +       return err;
1922  }
1923  
1924  static void __exit agp_amdk8_cleanup(void)
1925 @@ -405,5 +494,5 @@ module_exit(agp_amdk8_cleanup);
1926  #endif
1927  
1928  MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
1929 +MODULE_PARM(agp_try_unsupported, "1i");
1930  MODULE_LICENSE("GPL and additional rights");
1931 -
1932 diff -burpN -X ../KDIFX linux/fs/compat.c linux-2.6.0test2-amd64/fs/compat.c
1933 --- linux/fs/compat.c   2003-07-18 02:39:58.000000000 +0200
1934 +++ linux-2.6.0test2-amd64/fs/compat.c  2003-07-13 23:26:23.000000000 +0200
1935 @@ -53,6 +53,19 @@ asmlinkage long compat_sys_utime(char *f
1936         return do_utimes(filename, t ? tv : NULL);
1937  }
1938  
1939 +asmlinkage long compat_sys_utimes(char *filename, struct compat_timeval *t)
1940 +{
1941 +       struct timeval tv[2];
1942 +
1943 +       if (t) { 
1944 +               if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
1945 +                   get_user(tv[0].tv_usec, &t[0].tv_usec) ||
1946 +                   get_user(tv[1].tv_sec, &t[1].tv_sec) ||
1947 +                   get_user(tv[1].tv_usec, &t[1].tv_usec))
1948 +                       return -EFAULT; 
1949 +       } 
1950 +       return do_utimes(filename, t ? tv : NULL);
1951 +}
1952  
1953  asmlinkage long compat_sys_newstat(char * filename,
1954                 struct compat_stat *statbuf)
1955 @@ -150,6 +163,64 @@ out:
1956         return error;
1957  }
1958  
1959 +static int put_compat_statfs64(struct compat_statfs64 *ubuf, struct kstatfs *kbuf)
1960 +{
1961 +       
1962 +       if (sizeof ubuf->f_blocks == 4) {
1963 +               if ((kbuf->f_blocks | kbuf->f_bfree |
1964 +                    kbuf->f_bavail | kbuf->f_files | kbuf->f_ffree) &
1965 +                   0xffffffff00000000ULL)
1966 +                       return -EOVERFLOW;
1967 +       }
1968 +       if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
1969 +           __put_user(kbuf->f_type, &ubuf->f_type) ||
1970 +           __put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
1971 +           __put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
1972 +           __put_user(kbuf->f_bfree, &ubuf->f_bfree) ||
1973 +           __put_user(kbuf->f_bavail, &ubuf->f_bavail) ||
1974 +           __put_user(kbuf->f_files, &ubuf->f_files) ||
1975 +           __put_user(kbuf->f_ffree, &ubuf->f_ffree) ||
1976 +           __put_user(kbuf->f_namelen, &ubuf->f_namelen) ||
1977 +           __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
1978 +           __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) ||
1979 +           __put_user(kbuf->f_frsize, &ubuf->f_frsize))
1980 +               return -EFAULT;
1981 +       return 0;
1982 +}
1983 +
1984 +asmlinkage long compat_statfs64(const char *path, struct compat_statfs64 *buf)
1985 +{
1986 +       struct nameidata nd;
1987 +       int error;
1988 +
1989 +       error = user_path_walk(path, &nd);
1990 +       if (!error) {
1991 +               struct kstatfs tmp;
1992 +               error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
1993 +               if (!error && put_compat_statfs64(buf, &tmp))
1994 +                       error = -EFAULT;
1995 +               path_release(&nd);
1996 +       }
1997 +       return error;
1998 +}
1999 +
2000 +asmlinkage long compat_fstatfs64(unsigned int fd, struct compat_statfs64 *buf)
2001 +{
2002 +       struct file * file;
2003 +       struct kstatfs tmp;
2004 +       int error;
2005 +
2006 +       error = -EBADF;
2007 +       file = fget(fd);
2008 +       if (!file)
2009 +               goto out;
2010 +       error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
2011 +       if (!error && put_compat_statfs64(buf, &tmp))
2012 +               error = -EFAULT;
2013 +       fput(file);
2014 +out:
2015 +       return error;
2016 +}
2017  
2018  /* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64 */
2019  
2020 diff -burpN -X ../KDIFX linux/include/asm-x86_64/apic.h linux-2.6.0test2-amd64/include/asm-x86_64/apic.h
2021 --- linux/include/asm-x86_64/apic.h     2003-07-18 02:40:01.000000000 +0200
2022 +++ linux-2.6.0test2-amd64/include/asm-x86_64/apic.h    2003-07-11 13:34:21.000000000 +0200
2023 @@ -84,10 +84,6 @@ extern int APIC_init_uniprocessor (void)
2024  extern void disable_APIC_timer(void);
2025  extern void enable_APIC_timer(void);
2026  
2027 -#ifdef CONFIG_PM
2028 -extern struct sys_device device_lapic;
2029 -#endif
2030 -
2031  extern int check_nmi_watchdog (void);
2032  
2033  extern unsigned int nmi_watchdog;
2034 diff -burpN -X ../KDIFX linux/include/asm-x86_64/bitops.h linux-2.6.0test2-amd64/include/asm-x86_64/bitops.h
2035 --- linux/include/asm-x86_64/bitops.h   2003-05-27 03:00:38.000000000 +0200
2036 +++ linux-2.6.0test2-amd64/include/asm-x86_64/bitops.h  2003-07-11 13:34:21.000000000 +0200
2037 @@ -402,12 +402,12 @@ static inline void set_bit_string(unsign
2038         }
2039  } 
2040  
2041 -static inline void clear_bit_string(unsigned long *bitmap, unsigned long i, 
2042 +static inline void __clear_bit_string(unsigned long *bitmap, unsigned long i, 
2043                                     int len) 
2044  { 
2045         unsigned long end = i + len; 
2046         while (i < end) {
2047 -               clear_bit(i, bitmap); 
2048 +               __clear_bit(i, bitmap); 
2049                 i++;
2050         }
2051  } 
2052 diff -burpN -X ../KDIFX linux/include/asm-x86_64/desc.h linux-2.6.0test2-amd64/include/asm-x86_64/desc.h
2053 --- linux/include/asm-x86_64/desc.h     2003-05-27 03:01:03.000000000 +0200
2054 +++ linux-2.6.0test2-amd64/include/asm-x86_64/desc.h    2003-07-11 13:34:21.000000000 +0200
2055 @@ -7,6 +7,7 @@
2056  
2057  #ifndef __ASSEMBLY__
2058  
2059 +#include <linux/string.h>
2060  #include <asm/segment.h>
2061  #include <asm/mmu.h>
2062  
2063 diff -burpN -X ../KDIFX linux/include/asm-x86_64/hw_irq.h linux-2.6.0test2-amd64/include/asm-x86_64/hw_irq.h
2064 --- linux/include/asm-x86_64/hw_irq.h   2003-05-27 03:00:59.000000000 +0200
2065 +++ linux-2.6.0test2-amd64/include/asm-x86_64/hw_irq.h  2003-07-28 20:03:02.000000000 +0200
2066 @@ -164,7 +164,7 @@ static inline void x86_do_profile (struc
2067         atomic_inc((atomic_t *)&prof_buffer[rip]);
2068  }
2069  
2070 -#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
2071 +#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP)
2072  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
2073         if (IO_APIC_IRQ(i))
2074                 send_IPI_self(IO_APIC_VECTOR(i));
2075 diff -burpN -X ../KDIFX linux/include/asm-x86_64/ia32_unistd.h linux-2.6.0test2-amd64/include/asm-x86_64/ia32_unistd.h
2076 --- linux/include/asm-x86_64/ia32_unistd.h      2003-05-27 03:00:42.000000000 +0200
2077 +++ linux-2.6.0test2-amd64/include/asm-x86_64/ia32_unistd.h     2003-07-13 23:27:13.000000000 +0200
2078 @@ -264,7 +264,20 @@
2079  #define __NR_ia32_sys_epoll_wait       256
2080  #define __NR_ia32_remap_file_pages     257
2081  #define __NR_ia32_set_tid_address      258
2082 +#define __NR_ia32_timer_create         259
2083 +#define __NR_ia32_timer_settime        (__NR_ia32_timer_create+1)
2084 +#define __NR_ia32_timer_gettime        (__NR_ia32_timer_create+2)
2085 +#define __NR_ia32_timer_getoverrun     (__NR_ia32_timer_create+3)
2086 +#define __NR_ia32_timer_delete (__NR_ia32_timer_create+4)
2087 +#define __NR_ia32_clock_settime        (__NR_ia32_timer_create+5)
2088 +#define __NR_ia32_clock_gettime        (__NR_ia32_timer_create+6)
2089 +#define __NR_ia32_clock_getres (__NR_ia32_timer_create+7)
2090 +#define __NR_ia32_clock_nanosleep      (__NR_ia32_timer_create+8)
2091 +#define __NR_ia32_statfs64             268
2092 +#define __NR_ia32_fstatfs64            269
2093 +#define __NR_ia32_tgkill               270
2094 +#define __NR_ia32_utimes               271
2095  
2096 -#define IA32_NR_syscalls 265   /* must be > than biggest syscall! */   
2097 +#define IA32_NR_syscalls 275   /* must be > than biggest syscall! */   
2098  
2099  #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
2100 diff -burpN -X ../KDIFX linux/include/asm-x86_64/io.h linux-2.6.0test2-amd64/include/asm-x86_64/io.h
2101 --- linux/include/asm-x86_64/io.h       2003-07-18 02:39:31.000000000 +0200
2102 +++ linux-2.6.0test2-amd64/include/asm-x86_64/io.h      2003-07-11 13:34:21.000000000 +0200
2103 @@ -301,6 +301,12 @@ out:
2104  
2105  #define flush_write_buffers() 
2106  
2107 +/* Disable vmerge for now. Need to fix the block layer code
2108 +   to check for non iommu addresses first.
2109 +   When the IOMMU is force it is safe to enable. */
2110 +extern int force_iommu; 
2111 +#define BIO_VERMGE_BOUNDARY (force_iommu ? 4096 : 0)
2112 +
2113  #endif /* __KERNEL__ */
2114  
2115  #endif
2116 diff -burpN -X ../KDIFX linux/include/asm-x86_64/local.h linux-2.6.0test2-amd64/include/asm-x86_64/local.h
2117 --- linux/include/asm-x86_64/local.h    1970-01-01 01:00:00.000000000 +0100
2118 +++ linux-2.6.0test2-amd64/include/asm-x86_64/local.h   2003-07-28 20:07:06.000000000 +0200
2119 @@ -0,0 +1,73 @@
2120 +#ifndef _ARCH_X8664_LOCAL_H
2121 +#define _ARCH_X8664_LOCAL_H
2122 +
2123 +#include <linux/percpu.h>
2124 +
2125 +typedef struct
2126 +{
2127 +       volatile unsigned int counter;
2128 +} local_t;
2129 +
2130 +#define LOCAL_INIT(i)  { (i) }
2131 +
2132 +#define local_read(v)  ((v)->counter)
2133 +#define local_set(v,i) (((v)->counter) = (i))
2134 +
2135 +static __inline__ void local_inc(local_t *v)
2136 +{
2137 +       __asm__ __volatile__(
2138 +               "incl %0"
2139 +               :"=m" (v->counter)
2140 +               :"m" (v->counter));
2141 +}
2142 +
2143 +static __inline__ void local_dec(local_t *v)
2144 +{
2145 +       __asm__ __volatile__(
2146 +               "decl %0"
2147 +               :"=m" (v->counter)
2148 +               :"m" (v->counter));
2149 +}
2150 +
2151 +static __inline__ void local_add(unsigned long i, local_t *v)
2152 +{
2153 +       __asm__ __volatile__(
2154 +               "addl %1,%0"
2155 +               :"=m" (v->counter)
2156 +               :"ir" (i), "m" (v->counter));
2157 +}
2158 +
2159 +static __inline__ void local_sub(unsigned long i, local_t *v)
2160 +{
2161 +       __asm__ __volatile__(
2162 +               "subl %1,%0"
2163 +               :"=m" (v->counter)
2164 +               :"ir" (i), "m" (v->counter));
2165 +}
2166 +
2167 +/* On x86, these are no better than the atomic variants. */
2168 +#define __local_inc(l)         local_inc(l)
2169 +#define __local_dec(l)         local_dec(l)
2170 +#define __local_add(i,l)       local_add((i),(l))
2171 +#define __local_sub(i,l)       local_sub((i),(l))
2172 +
2173 +/* Use these for per-cpu local_t variables: on some archs they are
2174 + * much more efficient than these naive implementations.  Note they take
2175 + * a variable, not an address.
2176 + * 
2177 + * This could be done better if we moved the per cpu data directly 
2178 + * after GS.
2179 + */
2180 +#define cpu_local_read(v)      local_read(&__get_cpu_var(v))
2181 +#define cpu_local_set(v, i)    local_set(&__get_cpu_var(v), (i))
2182 +#define cpu_local_inc(v)       local_inc(&__get_cpu_var(v))
2183 +#define cpu_local_dec(v)       local_dec(&__get_cpu_var(v))
2184 +#define cpu_local_add(i, v)    local_add((i), &__get_cpu_var(v))
2185 +#define cpu_local_sub(i, v)    local_sub((i), &__get_cpu_var(v))
2186 +
2187 +#define __cpu_local_inc(v)     cpu_local_inc(v)
2188 +#define __cpu_local_dec(v)     cpu_local_dec(v)
2189 +#define __cpu_local_add(i, v)  cpu_local_add((i), (v))
2190 +#define __cpu_local_sub(i, v)  cpu_local_sub((i), (v))
2191 +
2192 +#endif /* _ARCH_I386_LOCAL_H */
2193 diff -burpN -X ../KDIFX linux/include/asm-x86_64/mpspec.h linux-2.6.0test2-amd64/include/asm-x86_64/mpspec.h
2194 --- linux/include/asm-x86_64/mpspec.h   2003-05-27 03:00:39.000000000 +0200
2195 +++ linux-2.6.0test2-amd64/include/asm-x86_64/mpspec.h  2003-07-11 13:34:21.000000000 +0200
2196 @@ -164,11 +164,9 @@ enum mp_bustype {
2197         MP_BUS_PCI,
2198         MP_BUS_MCA
2199  };
2200 -extern int mp_bus_id_to_type [MAX_MP_BUSSES];
2201 -extern int mp_bus_id_to_node [MAX_MP_BUSSES];
2202 -extern int mp_bus_id_to_local [MAX_MP_BUSSES];
2203 -extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
2204 +extern unsigned char mp_bus_id_to_type [MAX_MP_BUSSES];
2205  extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
2206 +extern unsigned long mp_bus_to_cpumask [MAX_MP_BUSSES];
2207  
2208  extern unsigned int boot_cpu_physical_apicid;
2209  extern unsigned long phys_cpu_present_map;
2210 @@ -177,11 +175,9 @@ extern void find_smp_config (void);
2211  extern void get_smp_config (void);
2212  extern int nr_ioapics;
2213  extern int apic_version [MAX_APICS];
2214 -extern int mp_bus_id_to_type [MAX_MP_BUSSES];
2215  extern int mp_irq_entries;
2216  extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
2217  extern int mpc_default_type;
2218 -extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
2219  extern int mp_current_pci_id;
2220  extern unsigned long mp_lapic_addr;
2221  extern int pic_mode;
2222 diff -burpN -X ../KDIFX linux/include/asm-x86_64/nmi.h linux-2.6.0test2-amd64/include/asm-x86_64/nmi.h
2223 --- linux/include/asm-x86_64/nmi.h      2003-07-18 02:40:01.000000000 +0200
2224 +++ linux-2.6.0test2-amd64/include/asm-x86_64/nmi.h     2003-07-11 13:34:21.000000000 +0200
2225 @@ -48,4 +48,6 @@ static inline void unset_nmi_pm_callback
2226   
2227  extern void default_do_nmi(struct pt_regs *);
2228   
2229 +extern void default_do_nmi(struct pt_regs *);
2230
2231  #endif /* ASM_NMI_H */
2232 diff -burpN -X ../KDIFX linux/include/asm-x86_64/pci-direct.h linux-2.6.0test2-amd64/include/asm-x86_64/pci-direct.h
2233 --- linux/include/asm-x86_64/pci-direct.h       2003-05-27 03:00:25.000000000 +0200
2234 +++ linux-2.6.0test2-amd64/include/asm-x86_64/pci-direct.h      2003-07-11 13:35:37.000000000 +0200
2235 @@ -14,7 +14,26 @@ static inline u32 read_pci_config(u8 bus
2236         u32 v; 
2237         outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
2238         v = inl(0xcfc); 
2239 -       PDprintk("%x reading from %x: %x\n", slot, offset, v);
2240 +       if (v != 0xffffffff)
2241 +               PDprintk("%x reading 4 from %x: %x\n", slot, offset, v);
2242 +       return v;
2243 +}
2244 +
2245 +static inline u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
2246 +{
2247 +       u8 v; 
2248 +       outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
2249 +       v = inb(0xcfc + (offset&3)); 
2250 +       PDprintk("%x reading 1 from %x: %x\n", slot, offset, v);
2251 +       return v;
2252 +}
2253 +
2254 +static inline u8 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
2255 +{
2256 +       u16 v; 
2257 +       outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
2258 +       v = inw(0xcfc + (offset&2)); 
2259 +       PDprintk("%x reading 2 from %x: %x\n", slot, offset, v);
2260         return v;
2261  }
2262  
2263 diff -burpN -X ../KDIFX linux/include/asm-x86_64/pci.h linux-2.6.0test2-amd64/include/asm-x86_64/pci.h
2264 --- linux/include/asm-x86_64/pci.h      2003-07-18 02:40:01.000000000 +0200
2265 +++ linux-2.6.0test2-amd64/include/asm-x86_64/pci.h     2003-07-11 13:34:21.000000000 +0200
2266 @@ -8,9 +8,6 @@
2267  
2268  #include <linux/mm.h> /* for struct page */
2269  
2270 -
2271 -extern dma_addr_t bad_dma_address;
2272 -
2273  /* Can be used to override the logic in pci_scan_bus for skipping
2274     already-configured bus numbers - to be used for buggy BIOSes
2275     or architectures with incomplete PCI setup by the loader */
2276 @@ -21,6 +18,8 @@ extern unsigned int pcibios_assign_all_b
2277  #define pcibios_assign_all_busses()    0
2278  #endif
2279  
2280 +extern int no_iommu, force_iommu;
2281 +
2282  extern unsigned long pci_mem_start;
2283  #define PCIBIOS_MIN_IO         0x1000
2284  #define PCIBIOS_MIN_MEM                (pci_mem_start)
2285 @@ -46,6 +45,9 @@ struct pci_dev;
2286  
2287  extern int iommu_setup(char *opt);
2288  
2289 +extern dma_addr_t bad_dma_address;
2290 +#define pci_dma_error(x) ((x) == bad_dma_address)
2291 +
2292  /* Allocate and map kernel buffer using consistent mode DMA for a device.
2293   * hwdev should be valid struct pci_dev pointer for PCI devices,
2294   * NULL for PCI-like buses (ISA, EISA).
2295 @@ -119,10 +121,16 @@ static inline void pci_dma_sync_sg(struc
2296  
2297  /* The PCI address space does equal the physical memory
2298   * address space.  The networking and block device layers use
2299 - * this boolean for bounce buffer decisions.
2300 + * this boolean for bounce buffer decisions
2301 + *
2302 + * On AMD64 it mostly equals, but we set it to zero to tell some subsystems
2303 + * that an IOMMU is available.
2304   */
2305 -#define PCI_DMA_BUS_IS_PHYS    (0)
2306 +#define PCI_DMA_BUS_IS_PHYS    (no_iommu ? 1 : 0) 
2307  
2308 +/* We lie slightly when the IOMMU is forced to get the device to 
2309 +   use SAC instead of DAC. */
2310 +#define pci_dac_dma_supported(pci_dev, mask)   (force_iommu ? 0 : 1)
2311  
2312  #else
2313  static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
2314 @@ -206,6 +214,7 @@ static inline void pci_dma_sync_sg(struc
2315  
2316  #define PCI_DMA_BUS_IS_PHYS    1
2317  
2318 +#define pci_dac_dma_supported(pci_dev, mask)   1
2319  #endif
2320  
2321  extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
2322 @@ -220,21 +229,7 @@ extern void pci_unmap_sg(struct pci_dev 
2323   * only drive the low 24-bits during PCI bus mastering, then
2324   * you would pass 0x00ffffff as the mask to this function.
2325   */
2326 -static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
2327 -{
2328 -        /*
2329 -         * we fall back to GFP_DMA when the mask isn't all 1s,
2330 -         * so we can't guarantee allocations that must be
2331 -         * within a tighter range than GFP_DMA..
2332 -         */
2333 -        if(mask < 0x00ffffff)
2334 -                return 0;
2335 -
2336 -       return 1;
2337 -}
2338 -
2339 -/* This is always fine. */
2340 -#define pci_dac_dma_supported(pci_dev, mask)   (1)
2341 +extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
2342  
2343  static __inline__ dma64_addr_t
2344  pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
2345 diff -burpN -X ../KDIFX linux/include/asm-x86_64/pda.h linux-2.6.0test2-amd64/include/asm-x86_64/pda.h
2346 --- linux/include/asm-x86_64/pda.h      2003-05-27 03:00:38.000000000 +0200
2347 +++ linux-2.6.0test2-amd64/include/asm-x86_64/pda.h     2003-07-29 01:37:11.000000000 +0200
2348 @@ -9,7 +9,7 @@
2349  /* Per processor datastructure. %gs points to it while the kernel runs */ 
2350  struct x8664_pda {
2351         struct task_struct *pcurrent;   /* Current process */
2352 -       unsigned long cpudata_offset;
2353 +       unsigned long data_offset;      /* Per cpu data offset from linker address */
2354         struct x8664_pda *me;       /* Pointer to itself */  
2355         unsigned long kernelstack;  /* TOS for current process */ 
2356         unsigned long oldrsp;       /* user rsp for system call */
2357 diff -burpN -X ../KDIFX linux/include/asm-x86_64/percpu.h linux-2.6.0test2-amd64/include/asm-x86_64/percpu.h
2358 --- linux/include/asm-x86_64/percpu.h   2003-05-27 03:00:43.000000000 +0200
2359 +++ linux-2.6.0test2-amd64/include/asm-x86_64/percpu.h  2003-07-29 01:37:25.000000000 +0200
2360 @@ -1,6 +1,53 @@
2361 -#ifndef __ARCH_I386_PERCPU__
2362 -#define __ARCH_I386_PERCPU__
2363 +#ifndef _ASM_X8664_PERCPU_H_
2364 +#define _ASM_X8664_PERCPU_H_
2365  
2366 -#include <asm-generic/percpu.h>
2367 +#include <asm/pda.h>
2368  
2369 -#endif /* __ARCH_I386_PERCPU__ */
2370 +#ifdef CONFIG_SMP
2371 +
2372 +/* Same as the generic code except that we cache the per cpu offset
2373 +   in the pda. This gives an 3 instruction reference for per cpu data */
2374 +
2375 +#include <linux/compiler.h>
2376 +#include <asm/pda.h>
2377 +#define __my_cpu_offset() read_pda(data_offset)
2378 +#define __per_cpu_offset(cpu) (cpu_pda[cpu].data_offset)
2379 +
2380 +/* Separate out the type, so (int[3], foo) works. */
2381 +#define DEFINE_PER_CPU(type, name) \
2382 +    __attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu
2383 +
2384 +/* var is in discarded region: offset to particular copy we want */
2385 +#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset(cpu)))
2386 +#define __get_cpu_var(var) \
2387 +       (*RELOC_HIDE(&var##__per_cpu, __my_cpu_offset()))
2388 +
2389 +static inline void percpu_modcopy(void *pcpudst, const void *src,
2390 +                                 unsigned long size)
2391 +{
2392 +       unsigned int i;
2393 +       for (i = 0; i < NR_CPUS; i++)
2394 +               if (cpu_possible(i))
2395 +                       memcpy(pcpudst + __per_cpu_offset(i), src, size);
2396 +}
2397 +
2398 +extern void setup_per_cpu_areas(void);
2399 +
2400 +#else /* ! SMP */
2401 +
2402 +#define DEFINE_PER_CPU(type, name) \
2403 +    __typeof__(type) name##__per_cpu
2404 +
2405 +#define per_cpu(var, cpu)                      ((void)cpu, var##__per_cpu)
2406 +#define __get_cpu_var(var)                     var##__per_cpu
2407 +
2408 +#endif /* SMP */
2409 +
2410 +#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu
2411 +
2412 +#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var##__per_cpu)
2413 +#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var##__per_cpu)
2414 +
2415 +DECLARE_PER_CPU(struct x8664_pda, per_cpu_pda); 
2416 +
2417 +#endif
2418 diff -burpN -X ../KDIFX linux/include/asm-x86_64/processor.h linux-2.6.0test2-amd64/include/asm-x86_64/processor.h
2419 --- linux/include/asm-x86_64/processor.h        2003-07-18 02:40:01.000000000 +0200
2420 +++ linux-2.6.0test2-amd64/include/asm-x86_64/processor.h       2003-07-29 01:42:29.000000000 +0200
2421 @@ -181,6 +181,7 @@ static inline void clear_in_cr4 (unsigne
2422   * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
2423   */
2424  #define IO_BITMAP_SIZE 32
2425 +#define IO_BITMAP_BYTES (IO_BITMAP_SIZE * 4)
2426  #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
2427  #define INVALID_IO_BITMAP_OFFSET 0x8000
2428  
2429 diff -burpN -X ../KDIFX linux/include/asm-x86_64/proto.h linux-2.6.0test2-amd64/include/asm-x86_64/proto.h
2430 --- linux/include/asm-x86_64/proto.h    2003-07-18 02:40:01.000000000 +0200
2431 +++ linux-2.6.0test2-amd64/include/asm-x86_64/proto.h   2003-07-11 13:34:21.000000000 +0200
2432 @@ -77,7 +77,7 @@ extern unsigned long end_pfn; 
2433  extern unsigned long table_start, table_end;
2434  
2435  extern int exception_trace;
2436 -extern int no_iommu, force_mmu;
2437 +extern int force_iommu, no_iommu;
2438  extern int using_apic_timer;
2439  extern int disable_apic;
2440  extern unsigned cpu_khz;
2441 diff -burpN -X ../KDIFX linux/include/asm-x86_64/smp.h linux-2.6.0test2-amd64/include/asm-x86_64/smp.h
2442 --- linux/include/asm-x86_64/smp.h      2003-07-18 02:39:47.000000000 +0200
2443 +++ linux-2.6.0test2-amd64/include/asm-x86_64/smp.h     2003-07-28 19:41:24.000000000 +0200
2444 @@ -117,7 +117,7 @@ extern inline int safe_smp_processor_id(
2445  #ifndef CONFIG_SMP
2446  #define stack_smp_processor_id() 0
2447  #define safe_smp_processor_id() 0
2448 -#define for_each_cpu(x) (x)=0;
2449 +#define for_each_cpu(x,mask) (void)(mask), (x)=0;
2450  #define cpu_logical_map(x) (x)
2451  #else
2452  #include <asm/thread_info.h>
2453 diff -burpN -X ../KDIFX linux/include/asm-x86_64/topology.h linux-2.6.0test2-amd64/include/asm-x86_64/topology.h
2454 --- linux/include/asm-x86_64/topology.h 2003-05-27 03:00:43.000000000 +0200
2455 +++ linux-2.6.0test2-amd64/include/asm-x86_64/topology.h        2003-07-11 13:34:21.000000000 +0200
2456 @@ -5,6 +5,8 @@
2457  
2458  #ifdef CONFIG_DISCONTIGMEM
2459  
2460 +#include <asm/mpspec.h>
2461 +
2462  /* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */
2463  
2464  extern int fake_node;
2465 @@ -17,6 +19,11 @@ extern unsigned long cpu_online_map;
2466  #define node_to_cpu_mask(node) (fake_node ? cpu_online_map : (1UL << (node)))
2467  #define node_to_memblk(node)           (node)
2468  
2469 +static inline unsigned long pcibus_to_cpumask(int bus)
2470 +{ 
2471 +       return mp_bus_to_cpumask[bus] & cpu_online_map; 
2472 +} 
2473 +
2474  #define NODE_BALANCE_RATE 30   /* CHECKME */ 
2475  
2476  #endif
2477 diff -burpN -X ../KDIFX linux/include/asm-x86_64/unistd.h linux-2.6.0test2-amd64/include/asm-x86_64/unistd.h
2478 --- linux/include/asm-x86_64/unistd.h   2003-07-18 02:40:01.000000000 +0200
2479 +++ linux-2.6.0test2-amd64/include/asm-x86_64/unistd.h  2003-07-14 12:00:43.000000000 +0200
2480 @@ -526,8 +526,12 @@ __SYSCALL(__NR_exit_group, sys_exit_grou
2481  __SYSCALL(__NR_epoll_wait, sys_epoll_wait)
2482  #define __NR_epoll_ctl         233
2483  __SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
2484 +#define __NR_tgkill            234
2485 +__SYSCALL(__NR_tgkill, sys_tgkill)
2486 +#define __NR_utimes            235
2487 +__SYSCALL(__NR_utimes, sys_utimes)
2488  
2489 -#define __NR_syscall_max __NR_epoll_ctl
2490 +#define __NR_syscall_max __NR_utimes
2491  #ifndef __NO_STUBS
2492  
2493  /* user-visible error numbers are in the range -1 - -4095 */
2494 diff -burpN -X ../KDIFX linux/include/linux/compat.h linux-2.6.0test2-amd64/include/linux/compat.h
2495 --- linux/include/linux/compat.h        2003-05-27 03:00:39.000000000 +0200
2496 +++ linux-2.6.0test2-amd64/include/linux/compat.h       2003-07-11 13:34:21.000000000 +0200
2497 @@ -15,6 +15,11 @@
2498  #define compat_jiffies_to_clock_t(x)   \
2499                 (((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
2500  
2501 +struct compat_itimerspec { 
2502 +       struct compat_timespec it_interval;
2503 +       struct compat_timespec it_value;
2504 +};
2505 +
2506  struct compat_utimbuf {
2507         compat_time_t           actime;
2508         compat_time_t           modtime;
2509 @@ -71,5 +76,19 @@ struct compat_rusage {
2510         compat_long_t   ru_nivcsw;
2511  };
2512  
2513 +struct compat_statfs64 {
2514 +       __u32 f_type;
2515 +       __u32 f_bsize;
2516 +       __u64 f_blocks;
2517 +       __u64 f_bfree;
2518 +       __u64 f_bavail;
2519 +       __u64 f_files;
2520 +       __u64 f_ffree;
2521 +       __kernel_fsid_t f_fsid;
2522 +       __u32 f_namelen;
2523 +       __u32 f_frsize;
2524 +       __u32 f_spare[5];
2525 +};
2526 +
2527  #endif /* CONFIG_COMPAT */
2528  #endif /* _LINUX_COMPAT_H */
2529 diff -burpN -X ../KDIFX linux/include/linux/pci.h linux-2.6.0test2-amd64/include/linux/pci.h
2530 --- linux/include/linux/pci.h   2003-07-28 23:12:30.000000000 +0200
2531 +++ linux-2.6.0test2-amd64/include/linux/pci.h  2003-07-28 19:18:18.000000000 +0200
2532 @@ -671,6 +671,10 @@ extern struct pci_dev *isa_bridge;
2533  
2534  #include <asm/pci.h>
2535  
2536 +#ifdef pci_dma_error
2537 +#define pci_dma_error(x) 0 
2538 +#endif
2539 +
2540  /*
2541   *  If the system does not have PCI, clearly these return errors.  Define
2542   *  these as simple inline functions to avoid hair in drivers.
2543 diff -burpN -X ../KDIFX linux/kernel/compat.c linux-2.6.0test2-amd64/kernel/compat.c
2544 --- linux/kernel/compat.c       2003-07-28 23:12:31.000000000 +0200
2545 +++ linux-2.6.0test2-amd64/kernel/compat.c      2003-07-28 19:18:18.000000000 +0200
2546 @@ -434,3 +434,130 @@ asmlinkage int compat_sys_sched_getaffin
2547         return ret;
2548  }
2549  
2550 +static int get_compat_itimerspec(struct itimerspec *dst, 
2551 +                                struct compat_itimerspec *src)
2552 +{ 
2553 +       if (get_compat_timespec(&dst->it_interval, &src->it_interval) ||
2554 +           get_compat_timespec(&dst->it_value, &src->it_value))
2555 +               return -EFAULT;
2556 +       return 0;
2557 +} 
2558 +
2559 +static int put_compat_itimerspec(struct compat_itimerspec *dst, 
2560 +                                struct itimerspec *src)
2561 +{ 
2562 +       if (put_compat_timespec(&src->it_interval, &dst->it_interval) ||
2563 +           put_compat_timespec(&src->it_value, &dst->it_value))
2564 +               return -EFAULT;
2565 +       return 0;
2566 +} 
2567 +
2568 +extern asmlinkage long sys_timer_settime(timer_t timer_id, int flags,
2569 +                                 struct itimerspec __user *new_setting,
2570 +                                struct itimerspec __user *old_setting);
2571 +extern asmlinkage long sys_timer_gettime(timer_t timer_id, 
2572 +                                        struct itimerspec __user *setting);
2573 +
2574 +long compat_timer_settime(timer_t timer_id, int flags, 
2575 +                         struct compat_itimerspec *new, 
2576 +                         struct compat_itimerspec *old)
2577 +{ 
2578 +       long err;
2579 +       mm_segment_t oldfs;
2580 +       struct itimerspec newts, oldts;
2581 +       if (get_compat_itimerspec(&newts, new))
2582 +               return -EFAULT; 
2583 +       oldfs = get_fs();
2584 +       err = sys_timer_settime(timer_id, flags, &newts, &oldts);
2585 +       set_fs(oldfs); 
2586 +       if (!err && old && put_compat_itimerspec(old, &oldts))
2587 +               return -EFAULT;
2588 +       return err;
2589 +} 
2590 +
2591 +long compat_timer_gettime(timer_t timer_id, struct compat_itimerspec *setting)
2592 +{ 
2593 +       long err;
2594 +       mm_segment_t oldfs;
2595 +       struct itimerspec ts; 
2596 +       oldfs = get_fs();
2597 +       err = sys_timer_gettime(timer_id, &ts); 
2598 +       set_fs(oldfs); 
2599 +       if (!err && put_compat_itimerspec(setting, &ts))
2600 +               return -EFAULT;
2601 +       return err;
2602 +} 
2603 +
2604 +extern asmlinkage long
2605 +sys_clock_settime(clockid_t which_clock, struct timespec __user *tp);
2606 +
2607 +long compat_clock_settime(clockid_t which_clock,  struct compat_timespec *tp)
2608 +{
2609 +       long err;
2610 +       mm_segment_t oldfs;
2611 +       struct timespec ts; 
2612 +       if (get_compat_timespec(&ts, tp))
2613 +               return -EFAULT; 
2614 +       oldfs = get_fs(); 
2615 +       err = sys_clock_settime(which_clock, &ts); 
2616 +       set_fs(oldfs);
2617 +       return err;
2618 +} 
2619 +
2620 +extern asmlinkage long
2621 +sys_clock_gettime(clockid_t which_clock, struct timespec __user *tp);
2622 +
2623 +long compat_clock_gettime(clockid_t which_clock,  struct compat_timespec *tp)
2624 +{
2625 +       long err;
2626 +       mm_segment_t oldfs;
2627 +       struct timespec ts; 
2628 +       oldfs = get_fs(); 
2629 +       err = sys_clock_gettime(which_clock, &ts); 
2630 +       set_fs(oldfs);
2631 +       if (!err && put_compat_timespec(&ts, tp))
2632 +               return -EFAULT; 
2633 +       return err;
2634 +} 
2635 +
2636 +extern asmlinkage long
2637 +sys_clock_getres(clockid_t which_clock, struct timespec __user *tp);
2638 +
2639 +long compat_clock_getres(clockid_t which_clock,  struct compat_timespec *tp)
2640 +{
2641 +       long err;
2642 +       mm_segment_t oldfs;
2643 +       struct timespec ts; 
2644 +       oldfs = get_fs(); 
2645 +       err = sys_clock_getres(which_clock, &ts); 
2646 +       set_fs(oldfs);
2647 +       if (!err && put_compat_timespec(&ts, tp))
2648 +               return -EFAULT; 
2649 +       return err;
2650 +} 
2651 +
2652 +extern asmlinkage long
2653 +sys_clock_nanosleep(clockid_t which_clock, int flags,
2654 +                    struct timespec __user *rqtp,
2655 +                   struct timespec __user *rmtp);
2656 +
2657 +long compat_clock_nanosleep(clockid_t which_clock, int flags,
2658 +                           struct compat_timespec __user *rqtp,
2659 +                           struct compat_timespec __user *rmtp)
2660 +{
2661 +       long err;
2662 +       mm_segment_t oldfs;
2663 +       struct timespec in, out; 
2664 +       if (get_compat_timespec(&in, rqtp)) 
2665 +               return -EFAULT;
2666 +       oldfs = get_fs(); 
2667 +       err = sys_clock_nanosleep(which_clock, flags, &in, &out);  
2668 +       set_fs(oldfs);
2669 +       if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
2670 +           put_compat_timespec(&out, rmtp))
2671 +               return -EFAULT;
2672 +       return err;     
2673 +} 
2674 +
2675 +/* timer_create is architecture specific because it needs sigevent conversion */
2676 +
2677 diff -burpN -X ../KDIFX linux/kernel/sysctl.c linux-2.6.0test2-amd64/kernel/sysctl.c
2678 --- linux/kernel/sysctl.c       2003-07-18 02:42:42.000000000 +0200
2679 +++ linux-2.6.0test2-amd64/kernel/sysctl.c      2003-07-14 11:57:37.000000000 +0200
2680 @@ -798,7 +798,17 @@ static ctl_table fs_table[] = {
2681         { .ctl_name = 0 }
2682  };
2683  
2684 +extern int sysctl_vsyscall32;
2685 +
2686  static ctl_table debug_table[] = {
2687 +#if defined(__x86_64__) && defined(CONFIG_IA32_EMULATION)
2688 +       { .ctl_name = 100, 
2689 +         .procname = "vsyscall32", 
2690 +         .data = &sysctl_vsyscall32, 
2691 +         .maxlen = sizeof(int), 
2692 +         .mode = 0644, 
2693 +         .proc_handler = &proc_dointvec},
2694 +#endif
2695         { .ctl_name = 0 }
2696  };
2697