Commit dd430ca2 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86

* git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86: (890 commits)
  x86: fix nodemap_size according to nodeid bits
  x86: fix overlap between pagetable with bss section
  x86: add PCI IDs to k8topology_64.c
  x86: fix early_ioremap pagetable ops
  x86: use the same pgd_list for PAE and 64-bit
  x86: defer cr3 reload when doing pud_clear()
  x86: early boot debugging via FireWire (ohci1394_dma=early)
  x86: don't special-case pmd allocations as much
  x86: shrink some ifdefs in fault.c
  x86: ignore spurious faults
  x86: remove nx_enabled from fault.c
  x86: unify fault_32|64.c
  x86: unify fault_32|64.c with ifdefs
  x86: unify fault_32|64.c by ifdef'd function bodies
  x86: arch/x86/mm/init_32.c printk fixes
  x86: arch/x86/mm/init_32.c cleanup
  x86: arch/x86/mm/init_64.c printk fixes
  x86: unify ioremap
  x86: fixes some bugs about EFI memory map handling
  x86: use reboot_type on EFI 32
  ...
parents 60e23317 afadcd78
Using physical DMA provided by OHCI-1394 FireWire controllers for debugging
---------------------------------------------------------------------------
Introduction
------------
Basically all FireWire controllers which are in use today are compliant
to the OHCI-1394 specification which defines the controller to be a PCI
bus master which uses DMA to offload data transfers from the CPU and has
a "Physical Response Unit" which executes specific requests by employing
PCI-Bus master DMA after applying filters defined by the OHCI-1394 driver.
Once properly configured, remote machines can send these requests to
ask the OHCI-1394 controller to perform read and write requests on
physical system memory and, for read requests, send the result of
the physical memory read back to the requester.
With that, it is possible to debug issues by reading interesting memory
locations such as buffers like the printk buffer or the process table.
Retrieving a full system memory dump is also possible over the FireWire,
using data transfer rates in the order of 10MB/s or more.
Memory access is currently limited to the low 4G of physical address
space which can be a problem on IA64 machines where memory is located
mostly above that limit, but it is rarely a problem on more common
hardware such as hardware based on x86, x86-64 and PowerPC.
Together with a early initialization of the OHCI-1394 controller for debugging,
this facility proved most useful for examining long debugs logs in the printk
buffer on to debug early boot problems in areas like ACPI where the system
fails to boot and other means for debugging (serial port) are either not
available (notebooks) or too slow for extensive debug information (like ACPI).
Drivers
-------
The OHCI-1394 drivers in drivers/firewire and drivers/ieee1394 initialize
the OHCI-1394 controllers to a working state and can be used to enable
physical DMA. By default you only have to load the driver, and physical
DMA access will be granted to all remote nodes, but it can be turned off
when using the ohci1394 driver.
Because these drivers depend on the PCI enumeration to be completed, an
initialization routine which can runs pretty early (long before console_init(),
which makes the printk buffer appear on the console can be called) was written.
To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu:
Provide code for enabling DMA over FireWire early on boot) and pass the
parameter "ohci1394_dma=early" to the recompiled kernel on boot.
Tools
-----
firescope - Originally developed by Benjamin Herrenschmidt, Andi Kleen ported
it from PowerPC to x86 and x86_64 and added functionality, firescope can now
be used to view the printk buffer of a remote machine, even with live update.
Bernhard Kaindl enhanced firescope to support accessing 64-bit machines
from 32-bit firescope and vice versa:
- ftp://ftp.suse.de/private/bk/firewire/tools/firescope-0.2.2.tar.bz2
and he implemented fast system dump (alpha version - read README.txt):
- ftp://ftp.suse.de/private/bk/firewire/tools/firedump-0.1.tar.bz2
There is also a gdb proxy for firewire which allows to use gdb to access
data which can be referenced from symbols found by gdb in vmlinux:
- ftp://ftp.suse.de/private/bk/firewire/tools/fireproxy-0.33.tar.bz2
The latest version of this gdb proxy (fireproxy-0.34) can communicate (not
yet stable) with kgdb over an memory-based communication module (kgdbom).
Getting Started
---------------
The OHCI-1394 specification regulates that the OHCI-1394 controller must
disable all physical DMA on each bus reset.
This means that if you want to debug an issue in a system state where
interrupts are disabled and where no polling of the OHCI-1394 controller
for bus resets takes place, you have to establish any FireWire cable
connections and fully initialize all FireWire hardware __before__ the
system enters such state.
Step-by-step instructions for using firescope with early OHCI initialization:
1) Verify that your hardware is supported:
Load the ohci1394 or the fw-ohci module and check your kernel logs.
You should see a line similar to
ohci1394: fw-host0: OHCI-1394 1.1 (PCI): IRQ=[18] MMIO=[fe9ff800-fe9fffff]
... Max Packet=[2048] IR/IT contexts=[4/8]
when loading the driver. If you have no supported controller, many PCI,
CardBus and even some Express cards which are fully compliant to OHCI-1394
specification are available. If it requires no driver for Windows operating
systems, it most likely is. Only specialized shops have cards which are not
compliant, they are based on TI PCILynx chips and require drivers for Win-
dows operating systems.
2) Establish a working FireWire cable connection:
Any FireWire cable, as long at it provides electrically and mechanically
stable connection and has matching connectors (there are small 4-pin and
large 6-pin FireWire ports) will do.
If an driver is running on both machines you should see a line like
ieee1394: Node added: ID:BUS[0-01:1023] GUID[0090270001b84bba]
on both machines in the kernel log when the cable is plugged in
and connects the two machines.
3) Test physical DMA using firescope:
On the debug host,
- load the raw1394 module,
- make sure that /dev/raw1394 is accessible,
then start firescope:
$ firescope
Port 0 (ohci1394) opened, 2 nodes detected
FireScope
---------
Target : <unspecified>
Gen : 1
[Ctrl-T] choose target
[Ctrl-H] this menu
[Ctrl-Q] quit
------> Press Ctrl-T now, the output should be similar to:
2 nodes available, local node is: 0
0: ffc0, uuid: 00000000 00000000 [LOCAL]
1: ffc1, uuid: 00279000 ba4bb801
Besides the [LOCAL] node, it must show another node without error message.
4) Prepare for debugging with early OHCI-1394 initialization:
4.1) Kernel compilation and installation on debug target
Compile the kernel to be debugged with CONFIG_PROVIDE_OHCI1394_DMA_INIT
(Kernel hacking: Provide code for enabling DMA over FireWire early on boot)
enabled and install it on the machine to be debugged (debug target).
4.2) Transfer the System.map of the debugged kernel to the debug host
Copy the System.map of the kernel be debugged to the debug host (the host
which is connected to the debugged machine over the FireWire cable).
5) Retrieving the printk buffer contents:
With the FireWire cable connected, the OHCI-1394 driver on the debugging
host loaded, reboot the debugged machine, booting the kernel which has
CONFIG_PROVIDE_OHCI1394_DMA_INIT enabled, with the option ohci1394_dma=early.
Then, on the debugging host, run firescope, for example by using -A:
firescope -A System.map-of-debug-target-kernel
Note: -A automatically attaches to the first non-local node. It only works
reliably if only connected two machines are connected using FireWire.
After having attached to the debug target, press Ctrl-D to view the
complete printk buffer or Ctrl-U to enter auto update mode and get an
updated live view of recent kernel messages logged on the debug target.
Call "firescope -h" to get more information on firescope's options.
Notes
-----
Documentation and specifications: ftp://ftp.suse.de/private/bk/firewire/docs
FireWire is a trademark of Apple Inc. - for more information please refer to:
http://en.wikipedia.org/wiki/FireWire
...@@ -416,8 +416,21 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -416,8 +416,21 @@ and is between 256 and 4096 characters. It is defined in the file
[SPARC64] tick [SPARC64] tick
[X86-64] hpet,tsc [X86-64] hpet,tsc
code_bytes [IA32] How many bytes of object code to print in an clearcpuid=BITNUM [X86]
oops report. Disable CPUID feature X for the kernel. See
include/asm-x86/cpufeature.h for the valid bit numbers.
Note the Linux specific bits are not necessarily
stable over kernel options, but the vendor specific
ones should be.
Also note that user programs calling CPUID directly
or using the feature without checking anything
will still see it. This just prevents it from
being used by the kernel or shown in /proc/cpuinfo.
Also note the kernel might malfunction if you disable
some critical bits.
code_bytes [IA32/X86_64] How many bytes of object code to print
in an oops report.
Range: 0 - 8192 Range: 0 - 8192
Default: 64 Default: 64
...@@ -570,6 +583,12 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -570,6 +583,12 @@ and is between 256 and 4096 characters. It is defined in the file
See drivers/char/README.epca and See drivers/char/README.epca and
Documentation/digiepca.txt. Documentation/digiepca.txt.
disable_mtrr_trim [X86, Intel and AMD only]
By default the kernel will trim any uncacheable
memory out of your available memory pool based on
MTRR settings. This parameter disables that behavior,
possibly causing your machine to run very slowly.
dmasound= [HW,OSS] Sound subsystem buffers dmasound= [HW,OSS] Sound subsystem buffers
dscc4.setup= [NET] dscc4.setup= [NET]
...@@ -660,6 +679,10 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -660,6 +679,10 @@ and is between 256 and 4096 characters. It is defined in the file
gamma= [HW,DRM] gamma= [HW,DRM]
gart_fix_e820= [X86_64] disable the fix e820 for K8 GART
Format: off | on
default: on
gdth= [HW,SCSI] gdth= [HW,SCSI]
See header of drivers/scsi/gdth.c. See header of drivers/scsi/gdth.c.
...@@ -794,6 +817,16 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -794,6 +817,16 @@ and is between 256 and 4096 characters. It is defined in the file
for translation below 32 bit and if not available for translation below 32 bit and if not available
then look in the higher range. then look in the higher range.
io_delay= [X86-32,X86-64] I/O delay method
0x80
Standard port 0x80 based delay
0xed
Alternate port 0xed based delay (needed on some systems)
udelay
Simple two microseconds delay
none
No delay
io7= [HW] IO7 for Marvel based alpha systems io7= [HW] IO7 for Marvel based alpha systems
See comment before marvel_specify_io7 in See comment before marvel_specify_io7 in
arch/alpha/kernel/core_marvel.c. arch/alpha/kernel/core_marvel.c.
...@@ -1059,6 +1092,11 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1059,6 +1092,11 @@ and is between 256 and 4096 characters. It is defined in the file
Multi-Function General Purpose Timers on AMD Geode Multi-Function General Purpose Timers on AMD Geode
platforms. platforms.
mfgptfix [X86-32] Fix MFGPT timers on AMD Geode platforms when
the BIOS has incorrectly applied a workaround. TinyBIOS
version 0.98 is known to be affected, 0.99 fixes the
problem by letting the user disable the workaround.
mga= [HW,DRM] mga= [HW,DRM]
mousedev.tap_time= mousedev.tap_time=
...@@ -1159,6 +1197,8 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1159,6 +1197,8 @@ and is between 256 and 4096 characters. It is defined in the file
nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects. nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
noefi [X86-32,X86-64] Disable EFI runtime services support.
noexec [IA-64] noexec [IA-64]
noexec [X86-32,X86-64] noexec [X86-32,X86-64]
...@@ -1169,6 +1209,8 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1169,6 +1209,8 @@ and is between 256 and 4096 characters. It is defined in the file
register save and restore. The kernel will only save register save and restore. The kernel will only save
legacy floating-point registers on task switch. legacy floating-point registers on task switch.
noclflush [BUGS=X86] Don't use the CLFLUSH instruction
nohlt [BUGS=ARM] nohlt [BUGS=ARM]
no-hlt [BUGS=X86-32] Tells the kernel that the hlt no-hlt [BUGS=X86-32] Tells the kernel that the hlt
...@@ -1978,6 +2020,11 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1978,6 +2020,11 @@ and is between 256 and 4096 characters. It is defined in the file
vdso=1: enable VDSO (default) vdso=1: enable VDSO (default)
vdso=0: disable VDSO mapping vdso=0: disable VDSO mapping
vdso32= [X86-32,X86-64]
vdso32=2: enable compat VDSO (default with COMPAT_VDSO)
vdso32=1: enable 32-bit VDSO (default)
vdso32=0: disable 32-bit VDSO mapping
vector= [IA-64,SMP] vector= [IA-64,SMP]
vector=percpu: enable percpu vector domain vector=percpu: enable percpu vector domain
......
...@@ -110,12 +110,18 @@ Idle loop ...@@ -110,12 +110,18 @@ Idle loop
Rebooting Rebooting
reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old] reboot=b[ios] | t[riple] | k[bd] | a[cpi] | e[fi] [, [w]arm | [c]old]
bios Use the CPU reboot vector for warm reset bios Use the CPU reboot vector for warm reset
warm Don't set the cold reboot flag warm Don't set the cold reboot flag
cold Set the cold reboot flag cold Set the cold reboot flag
triple Force a triple fault (init) triple Force a triple fault (init)
kbd Use the keyboard controller. cold reset (default) kbd Use the keyboard controller. cold reset (default)
acpi Use the ACPI RESET_REG in the FADT. If ACPI is not configured or the
ACPI reset does not work, the reboot path attempts the reset using
the keyboard controller.
efi Use efi reset_system runtime service. If EFI is not configured or the
EFI reset does not work, the reboot path attempts the reset using
the keyboard controller.
Using warm reset will be much faster especially on big memory Using warm reset will be much faster especially on big memory
systems because the BIOS will not go through the memory check. systems because the BIOS will not go through the memory check.
......
...@@ -19,6 +19,10 @@ Mechanics: ...@@ -19,6 +19,10 @@ Mechanics:
- Build the kernel with the following configuration. - Build the kernel with the following configuration.
CONFIG_FB_EFI=y CONFIG_FB_EFI=y
CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y
If EFI runtime services are expected, the following configuration should
be selected.
CONFIG_EFI=y
CONFIG_EFI_VARS=y or m # optional
- Create a VFAT partition on the disk - Create a VFAT partition on the disk
- Copy the following to the VFAT partition: - Copy the following to the VFAT partition:
elilo bootloader with x86_64 support, elilo configuration file, elilo bootloader with x86_64 support, elilo configuration file,
...@@ -27,3 +31,8 @@ Mechanics: ...@@ -27,3 +31,8 @@ Mechanics:
can be found in the elilo sourceforge project. can be found in the elilo sourceforge project.
- Boot to EFI shell and invoke elilo choosing the kernel image built - Boot to EFI shell and invoke elilo choosing the kernel image built
in first step. in first step.
- If some or all EFI runtime services don't work, you can try following
kernel command line parameters to turn off some or all EFI runtime
services.
noefi turn off all EFI runtime services
reboot_type=k turn off EFI reboot runtime service
...@@ -91,6 +91,11 @@ config GENERIC_IRQ_PROBE ...@@ -91,6 +91,11 @@ config GENERIC_IRQ_PROBE
bool bool
default y default y
config GENERIC_LOCKBREAK
bool
default y
depends on SMP && PREEMPT
config RWSEM_GENERIC_SPINLOCK config RWSEM_GENERIC_SPINLOCK
bool bool
default y default y
......
...@@ -42,6 +42,11 @@ config MMU ...@@ -42,6 +42,11 @@ config MMU
config SWIOTLB config SWIOTLB
bool bool
config GENERIC_LOCKBREAK
bool
default y
depends on SMP && PREEMPT
config RWSEM_XCHGADD_ALGORITHM config RWSEM_XCHGADD_ALGORITHM
bool bool
default y default y
...@@ -75,6 +80,9 @@ config GENERIC_TIME_VSYSCALL ...@@ -75,6 +80,9 @@ config GENERIC_TIME_VSYSCALL
bool bool
default y default y
config ARCH_SETS_UP_PER_CPU_AREA
def_bool y
config DMI config DMI
bool bool
default y default y
......
...@@ -222,7 +222,8 @@ elf32_set_personality (void) ...@@ -222,7 +222,8 @@ elf32_set_personality (void)
} }
static unsigned long static unsigned long
elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) elf32_map(struct file *filep, unsigned long addr, struct elf_phdr *eppnt,
int prot, int type, unsigned long unused)
{ {
unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK; unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
......
...@@ -947,7 +947,7 @@ percpu_modcopy (void *pcpudst, const void *src, unsigned long size) ...@@ -947,7 +947,7 @@ percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
{ {
unsigned int i; unsigned int i;
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
memcpy(pcpudst + __per_cpu_offset[i], src, size); memcpy(pcpudst + per_cpu_offset(i), src, size);
} }
} }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
...@@ -235,6 +235,11 @@ config IRAM_SIZE ...@@ -235,6 +235,11 @@ config IRAM_SIZE
# Define implied options from the CPU selection here # Define implied options from the CPU selection here
# #
config GENERIC_LOCKBREAK
bool
default y
depends on SMP && PREEMPT
config RWSEM_GENERIC_SPINLOCK config RWSEM_GENERIC_SPINLOCK
bool bool
depends on M32R depends on M32R
......
...@@ -694,6 +694,11 @@ source "arch/mips/vr41xx/Kconfig" ...@@ -694,6 +694,11 @@ source "arch/mips/vr41xx/Kconfig"
endmenu endmenu
config GENERIC_LOCKBREAK
bool
default y
depends on SMP && PREEMPT
config RWSEM_GENERIC_SPINLOCK config RWSEM_GENERIC_SPINLOCK
bool bool
default y default y
......
...@@ -24,9 +24,7 @@ DEFINE_SPINLOCK(i8253_lock); ...@@ -24,9 +24,7 @@ DEFINE_SPINLOCK(i8253_lock);
static void init_pit_timer(enum clock_event_mode mode, static void init_pit_timer(enum clock_event_mode mode,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
unsigned long flags; spin_lock(&i8253_lock);
spin_lock_irqsave(&i8253_lock, flags);
switch(mode) { switch(mode) {
case CLOCK_EVT_MODE_PERIODIC: case CLOCK_EVT_MODE_PERIODIC:
...@@ -55,7 +53,7 @@ static void init_pit_timer(enum clock_event_mode mode, ...@@ -55,7 +53,7 @@ static void init_pit_timer(enum clock_event_mode mode,
/* Nothing to do here */ /* Nothing to do here */
break; break;
} }
spin_unlock_irqrestore(&i8253_lock, flags); spin_unlock(&i8253_lock);
} }
/* /*
...@@ -65,12 +63,10 @@ static void init_pit_timer(enum clock_event_mode mode, ...@@ -65,12 +63,10 @@ static void init_pit_timer(enum clock_event_mode mode,
*/ */
static int pit_next_event(unsigned long delta, struct clock_event_device *evt) static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
{ {
unsigned long flags; spin_lock(&i8253_lock);
spin_lock_irqsave(&i8253_lock, flags);
outb_p(delta & 0xff , PIT_CH0); /* LSB */ outb_p(delta & 0xff , PIT_CH0); /* LSB */
outb(delta >> 8 , PIT_CH0); /* MSB */ outb(delta >> 8 , PIT_CH0); /* MSB */
spin_unlock_irqrestore(&i8253_lock, flags); spin_unlock(&i8253_lock);
return 0; return 0;
} }
......
...@@ -19,6 +19,11 @@ config MMU ...@@ -19,6 +19,11 @@ config MMU
config STACK_GROWSUP config STACK_GROWSUP
def_bool y def_bool y
config GENERIC_LOCKBREAK
bool
default y
depends on SMP && PREEMPT
config RWSEM_GENERIC_SPINLOCK config RWSEM_GENERIC_SPINLOCK
def_bool y def_bool y
......
...@@ -42,6 +42,9 @@ config GENERIC_HARDIRQS ...@@ -42,6 +42,9 @@ config GENERIC_HARDIRQS
bool bool
default y default y
config ARCH_SETS_UP_PER_CPU_AREA
def_bool PPC64
config IRQ_PER_CPU config IRQ_PER_CPU
bool bool
default y default y
...@@ -53,6 +56,11 @@ config RWSEM_XCHGADD_ALGORITHM ...@@ -53,6 +56,11 @@ config RWSEM_XCHGADD_ALGORITHM
bool bool
default y default y
config GENERIC_LOCKBREAK
bool
default y
depends on SMP && PREEMPT
config ARCH_HAS_ILOG2_U32 config ARCH_HAS_ILOG2_U32
bool bool
default y default y
......
...@@ -256,7 +256,7 @@ static int set_evrregs(struct task_struct *task, unsigned long *data) ...@@ -256,7 +256,7 @@ static int set_evrregs(struct task_struct *task, unsigned long *data)
#endif /* CONFIG_SPE */ #endif /* CONFIG_SPE */
static void set_single_step(struct task_struct *task) void user_enable_single_step(struct task_struct *task)
{ {
struct pt_regs *regs = task->thread.regs; struct pt_regs *regs = task->thread.regs;
...@@ -271,7 +271,7 @@ static void set_single_step(struct task_struct *task) ...@@ -271,7 +271,7 @@ static void set_single_step(struct task_struct *task)
set_tsk_thread_flag(task, TIF_SINGLESTEP); set_tsk_thread_flag(task, TIF_SINGLESTEP);
} }
static void clear_single_step(struct task_struct *task) void user_disable_single_step(struct task_struct *task)
{ {
struct pt_regs *regs = task->thread.regs; struct pt_regs *regs = task->thread.regs;
...@@ -313,7 +313,7 @@ static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, ...@@ -313,7 +313,7 @@ static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child)
{ {
/* make sure the single step bit is not set. */ /* make sure the single step bit is not set. */
clear_single_step(child); user_disable_single_step(child);
} }
/* /*
...@@ -445,52 +445,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -445,52 +445,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break; break;
} }
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
else
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
/* make sure the single step bit is not set. */
clear_single_step(child);
wake_up_process(child);
ret = 0;
break;
}
/*
* make the child exit. Best I can do is send it a sigkill.
* perhaps it should be put in the status that it wants to
* exit.
*/
case PTRACE_KILL: {
ret = 0;
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
clear_single_step(child);
wake_up_process(child);
break;
}
case PTRACE_SINGLESTEP: { /* set the trap flag. */
ret = -EIO;
if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
set_single_step(child);
child->exit_code = data;
/* give it a chance to run. */
wake_up_process(child);
ret = 0;
break;
}
case PTRACE_GET_DEBUGREG: { case PTRACE_GET_DEBUGREG: {
ret = -EINVAL; ret = -EINVAL;
/* We only support one DABR and no IABRS at the moment */ /* We only support one DABR and no IABRS at the moment */
......
...@@ -66,6 +66,9 @@ config AUDIT_ARCH ...@@ -66,6 +66,9 @@ config AUDIT_ARCH
bool bool
default y default y
config ARCH_SETS_UP_PER_CPU_AREA
def_bool y
config ARCH_NO_VIRT_TO_BUS config ARCH_NO_VIRT_TO_BUS
def_bool y def_bool y
...@@ -200,6 +203,11 @@ config US2E_FREQ ...@@ -200,6 +203,11 @@ config US2E_FREQ
If in doubt, say N. If in doubt, say N.
# Global things across all Sun machines. # Global things across all Sun machines.
config GENERIC_LOCKBREAK
bool
default y
depends on SMP && PREEMPT
config RWSEM_GENERIC_SPINLOCK config RWSEM_GENERIC_SPINLOCK
bool bool
......
...@@ -71,10 +71,10 @@ EXPORT_SYMBOL(dump_thread); ...@@ -71,10 +71,10 @@ EXPORT_SYMBOL(dump_thread);
/* required for SMP */ /* required for SMP */
extern void FASTCALL( __write_lock_failed(rwlock_t *rw)); extern void __write_lock_failed(rwlock_t *rw);
EXPORT_SYMBOL(__write_lock_failed); EXPORT_SYMBOL(__write_lock_failed);
extern void FASTCALL( __read_lock_failed(rwlock_t *rw)); extern void __read_lock_failed(rwlock_t *rw);
EXPORT_SYMBOL(__read_lock_failed); EXPORT_SYMBOL(__read_lock_failed);
#endif #endif
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/ptrace.h" #include <linux/ptrace.h>
#include "asm/unistd.h" #include <asm/unistd.h>
#include "asm/uaccess.h" #include <asm/uaccess.h>
#include "asm/ucontext.h" #include <asm/ucontext.h>
#include "frame_kern.h" #include "frame_kern.h"
#include "skas.h" #include "skas.h"
...@@ -18,17 +18,17 @@ void copy_sc(struct uml_pt_regs *regs, void *from) ...@@ -18,17 +18,17 @@ void copy_sc(struct uml_pt_regs *regs, void *from)
REGS_FS(regs->gp) = sc->fs; REGS_FS(regs->gp) = sc->fs;
REGS_ES(regs->gp) = sc->es; REGS_ES(regs->gp) = sc->es;
REGS_DS(regs->gp) = sc->ds; REGS_DS(regs->gp) = sc->ds;
REGS_EDI(regs->gp) = sc->edi; REGS_EDI(regs->gp) = sc->di;
REGS_ESI(regs->gp) = sc->esi; REGS_ESI(regs->gp) = sc->si;
REGS_EBP(regs->gp) = sc->ebp; REGS_EBP(regs->gp) = sc->bp;
REGS_SP(regs->gp) = sc->esp; REGS_SP(regs->gp) = sc->sp;
REGS_EBX(regs->gp) = sc->ebx; REGS_EBX(regs->gp) = sc->bx;
REGS_EDX(regs->gp) = sc->edx; REGS_EDX(regs->gp) = sc->dx;
REGS_ECX(regs->gp) = sc->ecx; REGS_ECX(regs->gp) = sc->cx;
REGS_EAX(regs->gp) = sc->eax; REGS_EAX(regs->gp) = sc->ax;
REGS_IP(regs->gp) = sc->eip; REGS_IP(regs->gp) = sc->ip;
REGS_CS(regs->gp) = sc->cs; REGS_CS(regs->gp) = sc->cs;
REGS_EFLAGS(regs->gp) = sc->eflags; REGS_EFLAGS(regs->gp) = sc->flags;
REGS_SS(regs->gp) = sc->ss; REGS_SS(regs->gp) = sc->ss;
} }
...@@ -229,18 +229,18 @@ static int copy_sc_to_user(struct sigcontext __user *to, ...@@ -229,18 +229,18 @@ static int copy_sc_to_user(struct sigcontext __user *to,
sc.fs = REGS_FS(regs->regs.gp); sc.fs = REGS_FS(regs->regs.gp);
sc.es = REGS_ES(regs->regs.gp); sc.es = REGS_ES(regs->regs.gp);
sc.ds = REGS_DS(regs->regs.gp); sc.ds = REGS_DS(regs->regs.gp);
sc.edi = REGS_EDI(regs->regs.gp); sc.di = REGS_EDI(regs->regs.gp);
sc.esi = REGS_ESI(regs->regs.gp); sc.si = REGS_ESI(regs->regs.gp);
sc.ebp = REGS_EBP(regs->regs.gp); sc.bp = REGS_EBP(regs->regs.gp);
sc.esp = sp; sc.sp = sp;
sc.ebx = REGS_EBX(regs->regs.gp); sc.bx = REGS_EBX(regs->regs.gp);
sc.edx = REGS_EDX(regs->regs.gp); sc.dx = REGS_EDX(regs->regs.gp);
sc.ecx = REGS_ECX(regs->regs.gp); sc.cx = REGS_ECX(regs->regs.gp);
sc.eax = REGS_EAX(regs->regs.gp); sc.ax = REGS_EAX(regs->regs.gp);
sc.eip = REGS_IP(regs->regs.gp); sc.ip = REGS_IP(regs->regs.gp);
sc.cs = REGS_CS(regs->regs.gp); sc.cs = REGS_CS(regs->regs.gp);
sc.eflags = REGS_EFLAGS(regs->regs.gp); sc.flags = REGS_EFLAGS(regs->regs.gp);
sc.esp_at_signal = regs->regs.gp[UESP]; sc.sp_at_signal = regs->regs.gp[UESP];
sc.ss = regs->regs.gp[SS]; sc.ss = regs->regs.gp[SS];
sc.cr2 = fi->cr2; sc.cr2 = fi->cr2;
sc.err = fi->error_code; sc.err = fi->error_code;
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/personality.h" #include <linux/personality.h>
#include "linux/ptrace.h" #include <linux/ptrace.h>
#include "asm/unistd.h" #include <asm/unistd.h>
#include "asm/uaccess.h" #include <asm/uaccess.h>
#include "asm/ucontext.h" #include <asm/ucontext.h>
#include "frame_kern.h" #include "frame_kern.h"
#include "skas.h" #include "skas.h"
...@@ -27,16 +27,16 @@ void copy_sc(struct uml_pt_regs *regs, void *from) ...@@ -27,16 +27,16 @@ void copy_sc(struct uml_pt_regs *regs, void *from)
GETREG(regs, R13, sc, r13); GETREG(regs, R13, sc, r13);
GETREG(regs, R14, sc, r14); GETREG(regs, R14, sc, r14);
GETREG(regs, R15, sc, r15); GETREG(regs, R15, sc, r15);
GETREG(regs, RDI, sc, rdi); GETREG(regs, RDI, sc, di);
GETREG(regs, RSI, sc, rsi); GETREG(regs, RSI, sc, si);
GETREG(regs, RBP, sc, rbp); GETREG(regs, RBP, sc, bp);
GETREG(regs, RBX, sc, rbx); GETREG(regs, RBX, sc, bx);
GETREG(regs, RDX, sc, rdx); GETREG(regs, RDX, sc, dx);
GETREG(regs, RAX, sc, rax); GETREG(regs, RAX, sc, ax);
GETREG(regs, RCX, sc, rcx); GETREG(regs, RCX, sc, cx);
GETREG(regs, RSP, sc, rsp); GETREG(regs, RSP, sc, sp);
GETREG(regs, RIP, sc, rip); GETREG(regs, RIP, sc, ip);
GETREG(regs, EFLAGS, sc, eflags); GETREG(regs, EFLAGS, sc, flags);
GETREG(regs, CS, sc, cs); GETREG(regs, CS, sc, cs);
#undef GETREG #undef GETREG
...@@ -61,16 +61,16 @@ static int copy_sc_from_user(struct pt_regs *regs, ...@@ -61,16 +61,16 @@ static int copy_sc_from_user(struct pt_regs *regs,
err |= GETREG(regs, R13, from, r13); err |= GETREG(regs, R13, from, r13);
err |= GETREG(regs, R14, from, r14); err |= GETREG(regs, R14, from, r14);
err |= GETREG(regs, R15, from, r15); err |= GETREG(regs, R15, from, r15);
err |= GETREG(regs, RDI, from, rdi); err |= GETREG(regs, RDI, from, di);
err |= GETREG(regs, RSI, from, rsi); err |= GETREG(regs, RSI, from, si);
err |= GETREG(regs, RBP, from, rbp); err |= GETREG(regs, RBP, from, bp);
err |= GETREG(regs, RBX, from, rbx); err |= GETREG(regs, RBX, from, bx);
err |= GETREG(regs, RDX, from, rdx); err |= GETREG(regs, RDX, from, dx);
err |= GETREG(regs, RAX, from, rax); err |= GETREG(regs, RAX, from, ax);
err |= GETREG(regs, RCX, from, rcx); err |= GETREG(regs, RCX, from, cx);
err |= GETREG(regs, RSP, from, rsp); err |= GETREG(regs, RSP, from, sp);
err |= GETREG(regs, RIP, from, rip); err |= GETREG(regs, RIP, from, ip);
err |= GETREG(regs, EFLAGS, from, eflags); err |= GETREG(regs, EFLAGS, from, flags);
err |= GETREG(regs, CS, from, cs); err |= GETREG(regs, CS, from, cs);
if (err) if (err)
return 1; return 1;
...@@ -108,19 +108,19 @@ static int copy_sc_to_user(struct sigcontext __user *to, ...@@ -108,19 +108,19 @@ static int copy_sc_to_user(struct sigcontext __user *to,
__put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \
&(sc)->regname) &(sc)->regname)
err |= PUTREG(regs, RDI, to, rdi); err |= PUTREG(regs, RDI, to, di);
err |= PUTREG(regs, RSI, to, rsi); err |= PUTREG(regs, RSI, to, si);
err |= PUTREG(regs, RBP, to, rbp); err |= PUTREG(regs, RBP, to, bp);
/* /*
* Must use orignal RSP, which is passed in, rather than what's in * Must use orignal RSP, which is passed in, rather than what's in
* the pt_regs, because that's already been updated to point at the * the pt_regs, because that's already been updated to point at the
* signal frame. * signal frame.
*/ */
err |= __put_user(sp, &to->rsp); err |= __put_user(sp, &to->sp);
err |= PUTREG(regs, RBX, to, rbx); err |= PUTREG(regs, RBX, to, bx);
err |= PUTREG(regs, RDX, to, rdx); err |= PUTREG(regs, RDX, to, dx);
err |= PUTREG(regs, RCX, to, rcx); err |= PUTREG(regs, RCX, to, cx);
err |= PUTREG(regs, RAX, to, rax); err |= PUTREG(regs, RAX, to, ax);
err |= PUTREG(regs, R8, to, r8); err |= PUTREG(regs, R8, to, r8);
err |= PUTREG(regs, R9, to, r9); err |= PUTREG(regs, R9, to, r9);
err |= PUTREG(regs, R10, to, r10); err |= PUTREG(regs, R10, to, r10);
...@@ -135,8 +135,8 @@ static int copy_sc_to_user(struct sigcontext __user *to, ...@@ -135,8 +135,8 @@ static int copy_sc_to_user(struct sigcontext __user *to,
err |= __put_user(fi->error_code, &to->err); err |= __put_user(fi->error_code, &to->err);
err |= __put_user(fi->trap_no, &to->trapno); err |= __put_user(fi->trap_no, &to->trapno);
err |= PUTREG(regs, RIP, to, rip); err |= PUTREG(regs, RIP, to, ip);
err |= PUTREG(regs, EFLAGS, to, eflags); err |= PUTREG(regs, EFLAGS, to, flags);
#undef PUTREG #undef PUTREG
err |= __put_user(mask, &to->oldmask); err |= __put_user(mask, &to->oldmask);
......
This diff is collapsed.
...@@ -219,10 +219,10 @@ config MGEODEGX1 ...@@ -219,10 +219,10 @@ config MGEODEGX1
Select this for a Geode GX1 (Cyrix MediaGX) chip. Select this for a Geode GX1 (Cyrix MediaGX) chip.
config MGEODE_LX config MGEODE_LX
bool "Geode GX/LX" bool "Geode GX/LX"
depends on X86_32 depends on X86_32
help help
Select this for AMD Geode GX and LX processors. Select this for AMD Geode GX and LX processors.
config MCYRIXIII config MCYRIXIII
bool "CyrixIII/VIA-C3" bool "CyrixIII/VIA-C3"
...@@ -258,7 +258,7 @@ config MPSC ...@@ -258,7 +258,7 @@ config MPSC
Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey
Xeon CPUs with Intel 64bit which is compatible with x86-64. Xeon CPUs with Intel 64bit which is compatible with x86-64.
Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the
Netburst core and shouldn't use this option. You can distinguish them Netburst core and shouldn't use this option. You can distinguish them
using the cpu family field using the cpu family field
in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one. in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
...@@ -317,81 +317,75 @@ config X86_L1_CACHE_SHIFT ...@@ -317,81 +317,75 @@ config X86_L1_CACHE_SHIFT
default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7
config X86_XADD config X86_XADD
bool def_bool y
depends on X86_32 && !M386 depends on X86_32 && !M386
default y
config X86_PPRO_FENCE config X86_PPRO_FENCE
bool bool "PentiumPro memory ordering errata workaround"
depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1 depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
default y help
Old PentiumPro multiprocessor systems had errata that could cause memory
operations to violate the x86 ordering standard in rare cases. Enabling this
option will attempt to work around some (but not all) occurances of
this problem, at the cost of much heavier spinlock and memory barrier
operations.
If unsure, say n here. Even distro kernels should think twice before enabling
this: there are few systems, and an unlikely bug.
config X86_F00F_BUG config X86_F00F_BUG
bool def_bool y
depends on M586MMX || M586TSC || M586 || M486 || M386 depends on M586MMX || M586TSC || M586 || M486 || M386
default y
config X86_WP_WORKS_OK config X86_WP_WORKS_OK
bool def_bool y
depends on X86_32 && !M386 depends on X86_32 && !M386
default y
config X86_INVLPG config X86_INVLPG
bool def_bool y
depends on X86_32 && !M386 depends on X86_32 && !M386
default y
config X86_BSWAP config X86_BSWAP
bool def_bool y
depends on X86_32 && !M386 depends on X86_32 && !M386
default y
config X86_POPAD_OK config X86_POPAD_OK
bool def_bool y
depends on X86_32 && !M386 depends on X86_32 && !M386
default y
config X86_ALIGNMENT_16 config X86_ALIGNMENT_16
bool def_bool y
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
default y
config X86_GOOD_APIC config X86_GOOD_APIC
bool def_bool y
depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64 depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64
default y
config X86_INTEL_USERCOPY config X86_INTEL_USERCOPY
bool def_bool y
depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
default y
config X86_USE_PPRO_CHECKSUM config X86_USE_PPRO_CHECKSUM
bool def_bool y
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2
default y
config X86_USE_3DNOW config X86_USE_3DNOW
bool def_bool y
depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
default y
config X86_OOSTORE config X86_OOSTORE
bool def_bool y
depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
default y
config X86_TSC config X86_TSC
bool def_bool y
depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64
default y
# this should be set for all -march=.. options where the compiler # this should be set for all -march=.. options where the compiler
# generates cmov. # generates cmov.
config X86_CMOV config X86_CMOV
bool def_bool y
depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7) depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
default y
config X86_MINIMUM_CPU_FAMILY config X86_MINIMUM_CPU_FAMILY
int int
...@@ -399,3 +393,6 @@ config X86_MINIMUM_CPU_FAMILY ...@@ -399,3 +393,6 @@ config X86_MINIMUM_CPU_FAMILY
default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
default "3" default "3"
config X86_DEBUGCTLMSR
def_bool y
depends on !(M586MMX || M586TSC || M586 || M486 || M386)
...@@ -6,7 +6,7 @@ config TRACE_IRQFLAGS_SUPPORT ...@@ -6,7 +6,7 @@ config TRACE_IRQFLAGS_SUPPORT
source "lib/Kconfig.debug" source "lib/Kconfig.debug"
config EARLY_PRINTK config EARLY_PRINTK
bool "Early printk" if EMBEDDED && DEBUG_KERNEL && X86_32 bool "Early printk" if EMBEDDED
default y default y
help help
Write kernel log output directly into the VGA buffer or to a serial Write kernel log output directly into the VGA buffer or to a serial
...@@ -40,22 +40,49 @@ comment "Page alloc debug is incompatible with Software Suspend on i386" ...@@ -40,22 +40,49 @@ comment "Page alloc debug is incompatible with Software Suspend on i386"
config DEBUG_PAGEALLOC config DEBUG_PAGEALLOC
bool "Debug page memory allocations" bool "Debug page memory allocations"
depends on DEBUG_KERNEL && !HIBERNATION && !HUGETLBFS depends on DEBUG_KERNEL && X86_32
depends on X86_32
help help
Unmap pages from the kernel linear mapping after free_pages(). Unmap pages from the kernel linear mapping after free_pages().
This results in a large slowdown, but helps to find certain types This results in a large slowdown, but helps to find certain types
of memory corruptions. of memory corruptions.
config DEBUG_PER_CPU_MAPS
bool "Debug access to per_cpu maps"
depends on DEBUG_KERNEL
depends on X86_64_SMP
default n
help
Say Y to verify that the per_cpu map being accessed has
been setup. Adds a fair amount of code to kernel memory
and decreases performance.
Say N if unsure.
config DEBUG_RODATA config DEBUG_RODATA
bool "Write protect kernel read-only data structures" bool "Write protect kernel read-only data structures"
default y
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
help help
Mark the kernel read-only data as write-protected in the pagetables, Mark the kernel read-only data as write-protected in the pagetables,
in order to catch accidental (and incorrect) writes to such const in order to catch accidental (and incorrect) writes to such const
data. This option may have a slight performance impact because a data. This is recommended so that we can catch kernel bugs sooner.
portion of the kernel code won't be covered by a 2MB TLB anymore. If in doubt, say "Y".
If in doubt, say "N".
config DEBUG_RODATA_TEST
bool "Testcase for the DEBUG_RODATA feature"
depends on DEBUG_RODATA
help
This option enables a testcase for the DEBUG_RODATA
feature as well as for the change_page_attr() infrastructure.
If in doubt, say "N"
config DEBUG_NX_TEST
tristate "Testcase for the NX non-executable stack feature"
depends on DEBUG_KERNEL && m
help
This option enables a testcase for the CPU NX capability
and the software setup of this feature.
If in doubt, say "N"
config 4KSTACKS config 4KSTACKS
bool "Use 4Kb for kernel stacks instead of 8Kb" bool "Use 4Kb for kernel stacks instead of 8Kb"
...@@ -75,8 +102,7 @@ config X86_FIND_SMP_CONFIG ...@@ -75,8 +102,7 @@ config X86_FIND_SMP_CONFIG
config X86_MPPARSE config X86_MPPARSE
def_bool y def_bool y
depends on X86_LOCAL_APIC && !X86_VISWS depends on (X86_32 && (X86_LOCAL_APIC && !X86_VISWS)) || X86_64
depends on X86_32
config DOUBLEFAULT config DOUBLEFAULT
default y default y
...@@ -112,4 +138,91 @@ config IOMMU_LEAK ...@@ -112,4 +138,91 @@ config IOMMU_LEAK
Add a simple leak tracer to the IOMMU code. This is useful when you Add a simple leak tracer to the IOMMU code. This is useful when you
are debugging a buggy device driver that leaks IOMMU mappings. are debugging a buggy device driver that leaks IOMMU mappings.
#
# IO delay types:
#
config IO_DELAY_TYPE_0X80
int
default "0"
config IO_DELAY_TYPE_0XED
int
default "1"
config IO_DELAY_TYPE_UDELAY
int
default "2"
config IO_DELAY_TYPE_NONE
int
default "3"
choice
prompt "IO delay type"
default IO_DELAY_0XED
config IO_DELAY_0X80
bool "port 0x80 based port-IO delay [recommended]"
help
This is the traditional Linux IO delay used for in/out_p.
It is the most tested hence safest selection here.
config IO_DELAY_0XED
bool "port 0xed based port-IO delay"
help
Use port 0xed as the IO delay. This frees up port 0x80 which is
often used as a hardware-debug port.
config IO_DELAY_UDELAY
bool "udelay based port-IO delay"
help
Use udelay(2) as the IO delay method. This provides the delay
while not having any side-effect on the IO port space.
config IO_DELAY_NONE
bool "no port-IO delay"
help
No port-IO delay. Will break on old boxes that require port-IO
delay for certain operations. Should work on most new machines.
endchoice
if IO_DELAY_0X80
config DEFAULT_IO_DELAY_TYPE
int
default IO_DELAY_TYPE_0X80
endif
if IO_DELAY_0XED
config DEFAULT_IO_DELAY_TYPE
int
default IO_DELAY_TYPE_0XED
endif
if IO_DELAY_UDELAY
config DEFAULT_IO_DELAY_TYPE
int
default IO_DELAY_TYPE_UDELAY
endif
if IO_DELAY_NONE
config DEFAULT_IO_DELAY_TYPE
int
default IO_DELAY_TYPE_NONE
endif
config DEBUG_BOOT_PARAMS
bool "Debug boot parameters"
depends on DEBUG_KERNEL
depends on DEBUG_FS
help
This option will cause struct boot_params to be exported via debugfs.
config CPA_DEBUG
bool "CPA self test code"
depends on DEBUG_KERNEL
help
Do change_page_attr self tests at boot.
endmenu endmenu
...@@ -7,13 +7,252 @@ else ...@@ -7,13 +7,252 @@ else
KBUILD_DEFCONFIG := $(ARCH)_defconfig KBUILD_DEFCONFIG := $(ARCH)_defconfig
endif endif
# No need to remake these files # BITS is used as extension for files which are available in a 32 bit
$(srctree)/arch/x86/Makefile%: ; # and a 64 bit version to simplify shared Makefiles.
# e.g.: obj-y += foo_$(BITS).o
export BITS
ifeq ($(CONFIG_X86_32),y) ifeq ($(CONFIG_X86_32),y)
BITS := 32
UTS_MACHINE := i386 UTS_MACHINE := i386
include $(srctree)/arch/x86/Makefile_32 CHECKFLAGS += -D__i386__
biarch := $(call cc-option,-m32)
KBUILD_AFLAGS += $(biarch)
KBUILD_CFLAGS += $(biarch)
ifdef CONFIG_RELOCATABLE
LDFLAGS_vmlinux := --emit-relocs
endif
KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return
# prevent gcc from keeping the stack 16 byte aligned
KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
# a lot more stack due to the lack of sharing of stacklots:
KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \
echo $(call cc-option,-fno-unit-at-a-time); fi ;)
# CPU-specific tuning. Anything which can be shared with UML should go here.
include $(srctree)/arch/x86/Makefile_32.cpu
KBUILD_CFLAGS += $(cflags-y)
# temporary until string.h is fixed
KBUILD_CFLAGS += -ffreestanding
else else
BITS := 64
UTS_MACHINE := x86_64 UTS_MACHINE := x86_64
include $(srctree)/arch/x86/Makefile_64 CHECKFLAGS += -D__x86_64__ -m64
KBUILD_AFLAGS += -m64
KBUILD_CFLAGS += -m64
# FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
cflags-$(CONFIG_MCORE2) += \
$(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += -mno-red-zone
KBUILD_CFLAGS += -mcmodel=kernel
# -funit-at-a-time shrinks the kernel .text considerably
# unfortunately it makes reading oopses harder.
KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
# this works around some issues with generating unwind tables in older gccs
# newer gccs do it by default
KBUILD_CFLAGS += -maccumulate-outgoing-args
stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh
stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \
"$(CC)" -fstack-protector )
stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \
"$(CC)" -fstack-protector-all )
KBUILD_CFLAGS += $(stackp-y)
endif
# Stackpointer is addressed different for 32 bit and 64 bit x86
sp-$(CONFIG_X86_32) := esp
sp-$(CONFIG_X86_64) := rsp
# do binutils support CFI?
cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1)
# is .cfi_signal_frame supported too?
cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1)
KBUILD_AFLAGS += $(cfi) $(cfi-sigframe)
KBUILD_CFLAGS += $(cfi) $(cfi-sigframe)
LDFLAGS := -m elf_$(UTS_MACHINE)
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
# Speed up the build
KBUILD_CFLAGS += -pipe
# Workaround for a gcc prelease that unfortunately was shipped in a suse release
KBUILD_CFLAGS += -Wno-sign-compare
#
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
# prevent gcc from generating any FP code by mistake
KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
###
# Sub architecture support
# fcore-y is linked before mcore-y files.
# Default subarch .c files
mcore-y := arch/x86/mach-default/
# Voyager subarch support
mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-x86/mach-voyager
mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager/
# VISWS subarch support
mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws
mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws/
# NUMAQ subarch support
mflags-$(CONFIG_X86_NUMAQ) := -Iinclude/asm-x86/mach-numaq
mcore-$(CONFIG_X86_NUMAQ) := arch/x86/mach-default/
# BIGSMP subarch support
mflags-$(CONFIG_X86_BIGSMP) := -Iinclude/asm-x86/mach-bigsmp
mcore-$(CONFIG_X86_BIGSMP) := arch/x86/mach-default/
#Summit subarch support
mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-x86/mach-summit
mcore-$(CONFIG_X86_SUMMIT) := arch/x86/mach-default/
# generic subarchitecture
mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic
fcore-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/
mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default/
# ES7000 subarch support
mflags-$(CONFIG_X86_ES7000) := -Iinclude/asm-x86/mach-es7000
fcore-$(CONFIG_X86_ES7000) := arch/x86/mach-es7000/
mcore-$(CONFIG_X86_ES7000) := arch/x86/mach-default/
# RDC R-321x subarch support
mflags-$(CONFIG_X86_RDC321X) := -Iinclude/asm-x86/mach-rdc321x
mcore-$(CONFIG_X86_RDC321X) := arch/x86/mach-default
core-$(CONFIG_X86_RDC321X) += arch/x86/mach-rdc321x/
# default subarch .h files
mflags-y += -Iinclude/asm-x86/mach-default
# 64 bit does not support subarch support - clear sub arch variables
fcore-$(CONFIG_X86_64) :=
mcore-$(CONFIG_X86_64) :=
mflags-$(CONFIG_X86_64) :=
KBUILD_CFLAGS += $(mflags-y)
KBUILD_AFLAGS += $(mflags-y)
###
# Kernel objects
head-y := arch/x86/kernel/head_$(BITS).o
head-$(CONFIG_X86_64) += arch/x86/kernel/head64.o
head-y += arch/x86/kernel/init_task.o
libs-y += arch/x86/lib/
# Sub architecture files that needs linking first
core-y += $(fcore-y)
# Xen paravirtualization support
core-$(CONFIG_XEN) += arch/x86/xen/
# lguest paravirtualization support
core-$(CONFIG_LGUEST_GUEST) += arch/x86/lguest/
core-y += arch/x86/kernel/
core-y += arch/x86/mm/
# Remaining sub architecture files
core-y += $(mcore-y)
core-y += arch/x86/crypto/
core-y += arch/x86/vdso/
core-$(CONFIG_IA32_EMULATION) += arch/x86/ia32/
# drivers-y are linked after core-y
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
drivers-$(CONFIG_PCI) += arch/x86/pci/
# must be linked after kernel/
drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
ifeq ($(CONFIG_X86_32),y)
drivers-$(CONFIG_PM) += arch/x86/power/
drivers-$(CONFIG_FB) += arch/x86/video/
endif endif
####
# boot loader support. Several targets are kept for legacy purposes
boot := arch/x86/boot
PHONY += zImage bzImage compressed zlilo bzlilo \
zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
# Default kernel to build
all: bzImage
# KBUILD_IMAGE specify target image being built
KBUILD_IMAGE := $(boot)/bzImage
zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
zImage bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
$(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/bzImage
compressed: zImage
zlilo bzlilo: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zlilo
zdisk bzdisk: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk
fdimage fdimage144 fdimage288 isoimage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
install: vdso_install
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
PHONY += vdso_install
vdso_install:
$(Q)$(MAKE) $(build)=arch/x86/vdso $@
archclean:
$(Q)rm -rf $(objtree)/arch/i386
$(Q)rm -rf $(objtree)/arch/x86_64
$(Q)$(MAKE) $(clean)=$(boot)
define archhelp
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
echo ' install - Install kernel using'
echo ' (your) ~/bin/installkernel or'
echo ' (distribution) /sbin/installkernel or'
echo ' install to $$(INSTALL_PATH) and run lilo'
echo ' fdimage - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)'
echo ' fdimage144 - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)'
echo ' fdimage288 - Create 2.8MB boot floppy image (arch/x86/boot/fdimage)'
echo ' isoimage - Create a boot CD-ROM image (arch/x86/boot/image.iso)'
echo ' bzdisk/fdimage*/isoimage also accept:'
echo ' FDARGS="..." arguments for the booted kernel'
echo ' FDINITRD=file initrd for the booted kernel'
endef
CLEAN_FILES += arch/x86/boot/fdimage \
arch/x86/boot/image.iso \
arch/x86/boot/mtools.conf
#
# i386 Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" cleaning up for this architecture.
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1994 by Linus Torvalds
#
# 19990713 Artur Skawina <skawina@geocities.com>
# Added '-march' and '-mpreferred-stack-boundary' support
#
# 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net>
# Added support for GEODE CPU
# BITS is used as extension for files which are available in a 32 bit
# and a 64 bit version to simplify shared Makefiles.
# e.g.: obj-y += foo_$(BITS).o
BITS := 32
export BITS
HAS_BIARCH := $(call cc-option-yn, -m32)
ifeq ($(HAS_BIARCH),y)
AS := $(AS) --32
LD := $(LD) -m elf_i386
CC := $(CC) -m32
endif
LDFLAGS := -m elf_i386
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
ifdef CONFIG_RELOCATABLE
LDFLAGS_vmlinux := --emit-relocs
endif
CHECKFLAGS += -D__i386__
KBUILD_CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return
# prevent gcc from keeping the stack 16 byte aligned
KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
# CPU-specific tuning. Anything which can be shared with UML should go here.
include $(srctree)/arch/x86/Makefile_32.cpu
# temporary until string.h is fixed
cflags-y += -ffreestanding
# this works around some issues with generating unwind tables in older gccs
# newer gccs do it by default
cflags-y += -maccumulate-outgoing-args
# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
# a lot more stack due to the lack of sharing of stacklots:
KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
# do binutils support CFI?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
# is .cfi_signal_frame supported too?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
KBUILD_CFLAGS += $(cflags-y)
# Default subarch .c files
mcore-y := arch/x86/mach-default
# Voyager subarch support
mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-x86/mach-voyager
mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager
# VISWS subarch support
mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws
mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws
# NUMAQ subarch support
mflags-$(CONFIG_X86_NUMAQ) := -Iinclude/asm-x86/mach-numaq
mcore-$(CONFIG_X86_NUMAQ) := arch/x86/mach-default
# BIGSMP subarch support
mflags-$(CONFIG_X86_BIGSMP) := -Iinclude/asm-x86/mach-bigsmp
mcore-$(CONFIG_X86_BIGSMP) := arch/x86/mach-default
#Summit subarch support
mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-x86/mach-summit
mcore-$(CONFIG_X86_SUMMIT) := arch/x86/mach-default
# generic subarchitecture
mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-x86/mach-generic
mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default
core-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/
# ES7000 subarch support
mflags-$(CONFIG_X86_ES7000) := -Iinclude/asm-x86/mach-es7000
mcore-$(CONFIG_X86_ES7000) := arch/x86/mach-default
core-$(CONFIG_X86_ES7000) := arch/x86/mach-es7000/
# Xen paravirtualization support
core-$(CONFIG_XEN) += arch/x86/xen/
# lguest paravirtualization support
core-$(CONFIG_LGUEST_GUEST) += arch/x86/lguest/
# default subarch .h files
mflags-y += -Iinclude/asm-x86/mach-default
head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task.o
libs-y += arch/x86/lib/
core-y += arch/x86/kernel/ \
arch/x86/mm/ \
$(mcore-y)/ \
arch/x86/crypto/
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
drivers-$(CONFIG_PCI) += arch/x86/pci/
# must be linked after kernel/
drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
drivers-$(CONFIG_PM) += arch/x86/power/
drivers-$(CONFIG_FB) += arch/x86/video/
KBUILD_CFLAGS += $(mflags-y)
KBUILD_AFLAGS += $(mflags-y)
boot := arch/x86/boot
PHONY += zImage bzImage compressed zlilo bzlilo \
zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
all: bzImage
# KBUILD_IMAGE specify target image being built
KBUILD_IMAGE := $(boot)/bzImage
zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
zImage bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
$(Q)mkdir -p $(objtree)/arch/i386/boot
$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
compressed: zImage
zlilo bzlilo: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zlilo
zdisk bzdisk: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk
fdimage fdimage144 fdimage288 isoimage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
install:
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
archclean:
$(Q)rm -rf $(objtree)/arch/i386/boot
$(Q)$(MAKE) $(clean)=arch/x86/boot
define archhelp
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
echo ' install - Install kernel using'
echo ' (your) ~/bin/installkernel or'
echo ' (distribution) /sbin/installkernel or'
echo ' install to $$(INSTALL_PATH) and run lilo'
echo ' bzdisk - Create a boot floppy in /dev/fd0'
echo ' fdimage - Create a boot floppy image'
echo ' isoimage - Create a boot CD-ROM image'
endef
CLEAN_FILES += arch/x86/boot/fdimage \
arch/x86/boot/image.iso \
arch/x86/boot/mtools.conf
#
# x86_64 Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1994 by Linus Torvalds
#
# 19990713 Artur Skawina <skawina@geocities.com>
# Added '-march' and '-mpreferred-stack-boundary' support
# 20000913 Pavel Machek <pavel@suse.cz>
# Converted for x86_64 architecture
# 20010105 Andi Kleen, add IA32 compiler.
# ....and later removed it again....
#
# $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $
# BITS is used as extension for files which are available in a 32 bit
# and a 64 bit version to simplify shared Makefiles.
# e.g.: obj-y += foo_$(BITS).o
BITS := 64
export BITS
LDFLAGS := -m elf_x86_64
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux :=
CHECKFLAGS += -D__x86_64__ -m64
cflags-y :=
cflags-kernel-y :=
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
# gcc doesn't support -march=core2 yet as of gcc 4.3, but I hope it
# will eventually. Use -mtune=generic as fallback
cflags-$(CONFIG_MCORE2) += \
$(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
cflags-y += -m64
cflags-y += -mno-red-zone
cflags-y += -mcmodel=kernel
cflags-y += -pipe
cflags-y += -Wno-sign-compare
cflags-y += -fno-asynchronous-unwind-tables
ifneq ($(CONFIG_DEBUG_INFO),y)
# -fweb shrinks the kernel a bit, but the difference is very small
# it also messes up debugging, so don't use it for now.
#cflags-y += $(call cc-option,-fweb)
endif
# -funit-at-a-time shrinks the kernel .text considerably
# unfortunately it makes reading oopses harder.
cflags-y += $(call cc-option,-funit-at-a-time)
# prevent gcc from generating any FP code by mistake
cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
# this works around some issues with generating unwind tables in older gccs
# newer gccs do it by default
cflags-y += -maccumulate-outgoing-args
# do binutils support CFI?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
# is .cfi_signal_frame supported too?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector )
cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector-all )
KBUILD_CFLAGS += $(cflags-y)
CFLAGS_KERNEL += $(cflags-kernel-y)
KBUILD_AFLAGS += -m64
head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task.o
libs-y += arch/x86/lib/
core-y += arch/x86/kernel/ \
arch/x86/mm/ \
arch/x86/crypto/ \
arch/x86/vdso/
core-$(CONFIG_IA32_EMULATION) += arch/x86/ia32/
drivers-$(CONFIG_PCI) += arch/x86/pci/
drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
boot := arch/x86/boot
PHONY += bzImage bzlilo install archmrproper \
fdimage fdimage144 fdimage288 isoimage archclean
#Default target when executing "make"
all: bzImage
BOOTIMAGE := arch/x86/boot/bzImage
KBUILD_IMAGE := $(BOOTIMAGE)
bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
$(Q)mkdir -p $(objtree)/arch/x86_64/boot
$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
bzlilo: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zlilo
bzdisk: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zdisk
fdimage fdimage144 fdimage288 isoimage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
install: vdso_install
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
vdso_install:
ifeq ($(CONFIG_IA32_EMULATION),y)
$(Q)$(MAKE) $(build)=arch/x86/ia32 $@
endif
$(Q)$(MAKE) $(build)=arch/x86/vdso $@
archclean:
$(Q)rm -rf $(objtree)/arch/x86_64/boot
$(Q)$(MAKE) $(clean)=$(boot)
define archhelp
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
echo ' install - Install kernel using'
echo ' (your) ~/bin/installkernel or'
echo ' (distribution) /sbin/installkernel or'
echo ' install to $$(INSTALL_PATH) and run lilo'
echo ' bzdisk - Create a boot floppy in /dev/fd0'
echo ' fdimage - Create a boot floppy image'
echo ' isoimage - Create a boot CD-ROM image'
endef
CLEAN_FILES += arch/x86/boot/fdimage \
arch/x86/boot/image.iso \
arch/x86/boot/mtools.conf
...@@ -28,9 +28,11 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA ...@@ -28,9 +28,11 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
targets := vmlinux.bin setup.bin setup.elf zImage bzImage targets := vmlinux.bin setup.bin setup.elf zImage bzImage
subdir- := compressed subdir- := compressed
setup-y += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
setup-y += header.o main.o mca.o memory.o pm.o pmjump.o setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
setup-y += printf.o string.o tty.o video.o version.o voyager.o setup-y += printf.o string.o tty.o video.o version.o
setup-$(CONFIG_X86_APM_BOOT) += apm.o
setup-$(CONFIG_X86_VOYAGER) += voyager.o
# The link order of the video-*.o modules can matter. In particular, # The link order of the video-*.o modules can matter. In particular,
# video-vga.o *must* be listed first, followed by video-vesa.o. # video-vga.o *must* be listed first, followed by video-vesa.o.
...@@ -49,10 +51,7 @@ HOSTCFLAGS_build.o := $(LINUXINCLUDE) ...@@ -49,10 +51,7 @@ HOSTCFLAGS_build.o := $(LINUXINCLUDE)
# How to compile the 16-bit code. Note we always compile for -march=i386, # How to compile the 16-bit code. Note we always compile for -march=i386,
# that way we can complain to the user if the CPU is insufficient. # that way we can complain to the user if the CPU is insufficient.
cflags-$(CONFIG_X86_32) :=
cflags-$(CONFIG_X86_64) := -m32
KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
$(cflags-y) \
-Wall -Wstrict-prototypes \ -Wall -Wstrict-prototypes \
-march=i386 -mregparm=3 \ -march=i386 -mregparm=3 \
-include $(srctree)/$(src)/code16gcc.h \ -include $(srctree)/$(src)/code16gcc.h \
...@@ -62,6 +61,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ ...@@ -62,6 +61,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
$(call cc-option, -fno-unit-at-a-time)) \ $(call cc-option, -fno-unit-at-a-time)) \
$(call cc-option, -fno-stack-protector) \ $(call cc-option, -fno-stack-protector) \
$(call cc-option, -mpreferred-stack-boundary=2) $(call cc-option, -mpreferred-stack-boundary=2)
KBUILD_CFLAGS += $(call cc-option,-m32)
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
$(obj)/zImage: IMAGE_OFFSET := 0x1000 $(obj)/zImage: IMAGE_OFFSET := 0x1000
......
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
#include "boot.h" #include "boot.h"
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
int query_apm_bios(void) int query_apm_bios(void)
{ {
u16 ax, bx, cx, dx, di; u16 ax, bx, cx, dx, di;
...@@ -95,4 +93,3 @@ int query_apm_bios(void) ...@@ -95,4 +93,3 @@ int query_apm_bios(void)
return 0; return 0;
} }
#endif
...@@ -109,7 +109,7 @@ typedef unsigned int addr_t; ...@@ -109,7 +109,7 @@ typedef unsigned int addr_t;
static inline u8 rdfs8(addr_t addr) static inline u8 rdfs8(addr_t addr)
{ {
u8 v; u8 v;
asm volatile("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr)); asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
return v; return v;
} }
static inline u16 rdfs16(addr_t addr) static inline u16 rdfs16(addr_t addr)
...@@ -127,21 +127,21 @@ static inline u32 rdfs32(addr_t addr) ...@@ -127,21 +127,21 @@ static inline u32 rdfs32(addr_t addr)
static inline void wrfs8(u8 v, addr_t addr) static inline void wrfs8(u8 v, addr_t addr)
{ {
asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v)); asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "qi" (v));
} }
static inline void wrfs16(u16 v, addr_t addr) static inline void wrfs16(u16 v, addr_t addr)
{ {
asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v)); asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "ri" (v));
} }
static inline void wrfs32(u32 v, addr_t addr) static inline void wrfs32(u32 v, addr_t addr)
{ {
asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v)); asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "ri" (v));
} }
static inline u8 rdgs8(addr_t addr) static inline u8 rdgs8(addr_t addr)
{ {
u8 v; u8 v;
asm volatile("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr)); asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
return v; return v;
} }
static inline u16 rdgs16(addr_t addr) static inline u16 rdgs16(addr_t addr)
...@@ -159,15 +159,15 @@ static inline u32 rdgs32(addr_t addr) ...@@ -159,15 +159,15 @@ static inline u32 rdgs32(addr_t addr)
static inline void wrgs8(u8 v, addr_t addr) static inline void wrgs8(u8 v, addr_t addr)
{ {
asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v)); asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "qi" (v));
} }
static inline void wrgs16(u16 v, addr_t addr) static inline void wrgs16(u16 v, addr_t addr)
{ {
asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v)); asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "ri" (v));
} }
static inline void wrgs32(u32 v, addr_t addr) static inline void wrgs32(u32 v, addr_t addr)
{ {
asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v)); asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "ri" (v));
} }
/* Note: these only return true/false, not a signed return value! */ /* Note: these only return true/false, not a signed return value! */
...@@ -241,6 +241,7 @@ int query_apm_bios(void); ...@@ -241,6 +241,7 @@ int query_apm_bios(void);
/* cmdline.c */ /* cmdline.c */
int cmdline_find_option(const char *option, char *buffer, int bufsize); int cmdline_find_option(const char *option, char *buffer, int bufsize);
int cmdline_find_option_bool(const char *option);
/* cpu.c, cpucheck.c */ /* cpu.c, cpucheck.c */
int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr); int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
......
...@@ -95,3 +95,68 @@ int cmdline_find_option(const char *option, char *buffer, int bufsize) ...@@ -95,3 +95,68 @@ int cmdline_find_option(const char *option, char *buffer, int bufsize)
return len; return len;
} }
/*
* Find a boolean option (like quiet,noapic,nosmp....)
*
* Returns the position of that option (starts counting with 1)
* or 0 on not found
*/
int cmdline_find_option_bool(const char *option)
{
u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
addr_t cptr;
char c;
int pos = 0, wstart = 0;
const char *opptr = NULL;
enum {
st_wordstart, /* Start of word/after whitespace */
st_wordcmp, /* Comparing this word */
st_wordskip, /* Miscompare, skip */
} state = st_wordstart;
if (!cmdline_ptr || cmdline_ptr >= 0x100000)
return -1; /* No command line, or inaccessible */
cptr = cmdline_ptr & 0xf;
set_fs(cmdline_ptr >> 4);
while (cptr < 0x10000) {
c = rdfs8(cptr++);
pos++;
switch (state) {
case st_wordstart:
if (!c)
return 0;
else if (myisspace(c))
break;
state = st_wordcmp;
opptr = option;
wstart = pos;
/* fall through */
case st_wordcmp:
if (!*opptr)
if (!c || myisspace(c))
return wstart;
else
state = st_wordskip;
else if (!c)
return 0;
else if (c != *opptr++)
state = st_wordskip;
break;
case st_wordskip:
if (!c)
return 0;
else if (myisspace(c))
state = st_wordstart;
break;
}
}
return 0; /* Buffer overrun */
}
#
# linux/arch/x86/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
targets := vmlinux vmlinux.bin vmlinux.bin.gz head_$(BITS).o misc.o piggy.o
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
cflags-$(CONFIG_X86_64) := -mcmodel=small
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
LDFLAGS := -m elf_$(UTS_MACHINE)
LDFLAGS_vmlinux := -T
$(obj)/vmlinux: $(src)/vmlinux_$(BITS).lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE
$(call if_changed,ld)
@:
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
ifeq ($(CONFIG_X86_32),y) ifeq ($(CONFIG_X86_32),y)
include ${srctree}/arch/x86/boot/compressed/Makefile_32 targets += vmlinux.bin.all vmlinux.relocs
hostprogs-y := relocs
quiet_cmd_relocs = RELOCS $@
cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE
$(call if_changed,relocs)
vmlinux.bin.all-y := $(obj)/vmlinux.bin
vmlinux.bin.all-$(CONFIG_RELOCATABLE) += $(obj)/vmlinux.relocs
quiet_cmd_relocbin = BUILD $@
cmd_relocbin = cat $(filter-out FORCE,$^) > $@
$(obj)/vmlinux.bin.all: $(vmlinux.bin.all-y) FORCE
$(call if_changed,relocbin)
ifdef CONFIG_RELOCATABLE
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
$(call if_changed,gzip)
else else
include ${srctree}/arch/x86/boot/compressed/Makefile_64 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
endif endif
LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
else
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
endif
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,ld)
#
# linux/arch/x86/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
targets := vmlinux vmlinux.bin vmlinux.bin.gz head_32.o misc_32.o piggy.o \
vmlinux.bin.all vmlinux.relocs
EXTRA_AFLAGS := -traditional
LDFLAGS_vmlinux := -T
hostprogs-y := relocs
KBUILD_CFLAGS := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
-fno-strict-aliasing -fPIC \
$(call cc-option,-ffreestanding) \
$(call cc-option,-fno-stack-protector)
LDFLAGS := -m elf_i386
$(obj)/vmlinux: $(src)/vmlinux_32.lds $(obj)/head_32.o $(obj)/misc_32.o $(obj)/piggy.o FORCE
$(call if_changed,ld)
@:
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
quiet_cmd_relocs = RELOCS $@
cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE
$(call if_changed,relocs)
vmlinux.bin.all-y := $(obj)/vmlinux.bin
vmlinux.bin.all-$(CONFIG_RELOCATABLE) += $(obj)/vmlinux.relocs
quiet_cmd_relocbin = BUILD $@
cmd_relocbin = cat $(filter-out FORCE,$^) > $@
$(obj)/vmlinux.bin.all: $(vmlinux.bin.all-y) FORCE
$(call if_changed,relocbin)
ifdef CONFIG_RELOCATABLE
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
$(call if_changed,gzip)
else
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
endif
LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
$(obj)/piggy.o: $(src)/vmlinux_32.scr $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,ld)
#
# linux/arch/x86/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
targets := vmlinux vmlinux.bin vmlinux.bin.gz head_64.o misc_64.o piggy.o
KBUILD_CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2 \
-fno-strict-aliasing -fPIC -mcmodel=small \
$(call cc-option, -ffreestanding) \
$(call cc-option, -fno-stack-protector)
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
LDFLAGS := -m elf_x86_64
LDFLAGS_vmlinux := -T
$(obj)/vmlinux: $(src)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o $(obj)/piggy.o FORCE
$(call if_changed,ld)
@:
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
$(obj)/piggy.o: $(obj)/vmlinux_64.scr $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,ld)
/* /*
* misc.c * misc.c
* *
* This is a collection of several routines from gzip-1.0.3 * This is a collection of several routines from gzip-1.0.3
* adapted for Linux. * adapted for Linux.
* *
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
...@@ -9,9 +9,18 @@ ...@@ -9,9 +9,18 @@
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/ */
/*
* we have to be careful, because no indirections are allowed here, and
* paravirt_ops is a kind of one. As it will only run in baremetal anyway,
* we just keep it from happening
*/
#undef CONFIG_PARAVIRT #undef CONFIG_PARAVIRT
#ifdef CONFIG_X86_64
#define _LINUX_STRING_H_ 1
#define __LINUX_BITMAP_H 1
#endif
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/vmalloc.h>
#include <linux/screen_info.h> #include <linux/screen_info.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/page.h> #include <asm/page.h>
...@@ -186,10 +195,20 @@ static void *memcpy(void *dest, const void *src, unsigned n); ...@@ -186,10 +195,20 @@ static void *memcpy(void *dest, const void *src, unsigned n);
static void putstr(const char *); static void putstr(const char *);
static unsigned long free_mem_ptr; #ifdef CONFIG_X86_64
static unsigned long free_mem_end_ptr; #define memptr long
#else
#define memptr unsigned
#endif
static memptr free_mem_ptr;
static memptr free_mem_end_ptr;
#ifdef CONFIG_X86_64
#define HEAP_SIZE 0x7000
#else
#define HEAP_SIZE 0x4000 #define HEAP_SIZE 0x4000
#endif
static char *vidmem = (char *)0xb8000; static char *vidmem = (char *)0xb8000;
static int vidport; static int vidport;
...@@ -230,7 +249,7 @@ static void gzip_mark(void **ptr) ...@@ -230,7 +249,7 @@ static void gzip_mark(void **ptr)
static void gzip_release(void **ptr) static void gzip_release(void **ptr)
{ {
free_mem_ptr = (unsigned long) *ptr; free_mem_ptr = (memptr) *ptr;
} }
static void scroll(void) static void scroll(void)
...@@ -247,8 +266,10 @@ static void putstr(const char *s) ...@@ -247,8 +266,10 @@ static void putstr(const char *s)
int x,y,pos; int x,y,pos;
char c; char c;
#ifdef CONFIG_X86_32
if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0) if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
return; return;
#endif
x = RM_SCREEN_INFO.orig_x; x = RM_SCREEN_INFO.orig_x;
y = RM_SCREEN_INFO.orig_y; y = RM_SCREEN_INFO.orig_y;
...@@ -261,7 +282,7 @@ static void putstr(const char *s) ...@@ -261,7 +282,7 @@ static void putstr(const char *s)
y--; y--;
} }
} else { } else {
vidmem [ ( x + cols * y ) * 2 ] = c; vidmem [(x + cols * y) * 2] = c;
if ( ++x >= cols ) { if ( ++x >= cols ) {
x = 0; x = 0;
if ( ++y >= lines ) { if ( ++y >= lines ) {
...@@ -276,16 +297,16 @@ static void putstr(const char *s) ...@@ -276,16 +297,16 @@ static void putstr(const char *s)
RM_SCREEN_INFO.orig_y = y; RM_SCREEN_INFO.orig_y = y;
pos = (x + cols * y) * 2; /* Update cursor position */ pos = (x + cols * y) * 2; /* Update cursor position */
outb_p(14, vidport); outb(14, vidport);
outb_p(0xff & (pos >> 9), vidport+1); outb(0xff & (pos >> 9), vidport+1);
outb_p(15, vidport); outb(15, vidport);
outb_p(0xff & (pos >> 1), vidport+1); outb(0xff & (pos >> 1), vidport+1);
} }
static void* memset(void* s, int c, unsigned n) static void* memset(void* s, int c, unsigned n)
{ {
int i; int i;
char *ss = (char*)s; char *ss = s;
for (i=0;i<n;i++) ss[i] = c; for (i=0;i<n;i++) ss[i] = c;
return s; return s;
...@@ -294,7 +315,8 @@ static void* memset(void* s, int c, unsigned n) ...@@ -294,7 +315,8 @@ static void* memset(void* s, int c, unsigned n)
static void* memcpy(void* dest, const void* src, unsigned n) static void* memcpy(void* dest, const void* src, unsigned n)
{ {
int i; int i;
char *d = (char *)dest, *s = (char *)src; const char *s = src;
char *d = dest;
for (i=0;i<n;i++) d[i] = s[i]; for (i=0;i<n;i++) d[i] = s[i];
return dest; return dest;
...@@ -339,11 +361,13 @@ static void error(char *x) ...@@ -339,11 +361,13 @@ static void error(char *x)
putstr(x); putstr(x);
putstr("\n\n -- System halted"); putstr("\n\n -- System halted");
while(1); /* Halt */ while (1)
asm("hlt");
} }
asmlinkage void decompress_kernel(void *rmode, unsigned long end, asmlinkage void decompress_kernel(void *rmode, memptr heap,
uch *input_data, unsigned long input_len, uch *output) uch *input_data, unsigned long input_len,
uch *output)
{ {
real_mode = rmode; real_mode = rmode;
...@@ -358,25 +382,32 @@ asmlinkage void decompress_kernel(void *rmode, unsigned long end, ...@@ -358,25 +382,32 @@ asmlinkage void decompress_kernel(void *rmode, unsigned long end,
lines = RM_SCREEN_INFO.orig_video_lines; lines = RM_SCREEN_INFO.orig_video_lines;
cols = RM_SCREEN_INFO.orig_video_cols; cols = RM_SCREEN_INFO.orig_video_cols;
window = output; /* Output buffer (Normally at 1M) */ window = output; /* Output buffer (Normally at 1M) */
free_mem_ptr = end; /* Heap */ free_mem_ptr = heap; /* Heap */
free_mem_end_ptr = end + HEAP_SIZE; free_mem_end_ptr = heap + HEAP_SIZE;
inbuf = input_data; /* Input buffer */ inbuf = input_data; /* Input buffer */
insize = input_len; insize = input_len;
inptr = 0; inptr = 0;
#ifdef CONFIG_X86_64
if ((ulg)output & (__KERNEL_ALIGN - 1))
error("Destination address not 2M aligned");
if ((ulg)output >= 0xffffffffffUL)
error("Destination address too large");
#else
if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1)) if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1))
error("Destination address not CONFIG_PHYSICAL_ALIGN aligned"); error("Destination address not CONFIG_PHYSICAL_ALIGN aligned");
if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff)) if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
error("Destination address too large"); error("Destination address too large");
#ifndef CONFIG_RELOCATABLE #ifndef CONFIG_RELOCATABLE
if ((u32)output != LOAD_PHYSICAL_ADDR) if ((u32)output != LOAD_PHYSICAL_ADDR)
error("Wrong destination address"); error("Wrong destination address");
#endif
#endif #endif
makecrc(); makecrc();
putstr("Uncompressing Linux... "); putstr("\nDecompressing Linux... ");
gunzip(); gunzip();
putstr("Ok, booting the kernel.\n"); putstr("done.\nBooting the kernel.\n");
return; return;
} }
/*
* misc.c
*
* This is a collection of several routines from gzip-1.0.3
* adapted for Linux.
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
* puts by Nick Holloway 1993, better puts by Martin Mares 1995
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/
#define _LINUX_STRING_H_ 1
#define __LINUX_BITMAP_H 1
#include <linux/linkage.h>
#include <linux/screen_info.h>
#include <asm/io.h>
#include <asm/page.h>
/* WARNING!!
* This code is compiled with -fPIC and it is relocated dynamically
* at run time, but no relocation processing is performed.
* This means that it is not safe to place pointers in static structures.
*/
/*
* Getting to provable safe in place decompression is hard.
* Worst case behaviours need to be analyzed.
* Background information:
*
* The file layout is:
* magic[2]
* method[1]
* flags[1]
* timestamp[4]
* extraflags[1]
* os[1]
* compressed data blocks[N]
* crc[4] orig_len[4]
*
* resulting in 18 bytes of non compressed data overhead.
*
* Files divided into blocks
* 1 bit (last block flag)
* 2 bits (block type)
*
* 1 block occurs every 32K -1 bytes or when there 50% compression has been achieved.
* The smallest block type encoding is always used.
*
* stored:
* 32 bits length in bytes.
*
* fixed:
* magic fixed tree.
* symbols.
*
* dynamic:
* dynamic tree encoding.
* symbols.
*
*
* The buffer for decompression in place is the length of the
* uncompressed data, plus a small amount extra to keep the algorithm safe.
* The compressed data is placed at the end of the buffer. The output
* pointer is placed at the start of the buffer and the input pointer
* is placed where the compressed data starts. Problems will occur
* when the output pointer overruns the input pointer.
*
* The output pointer can only overrun the input pointer if the input
* pointer is moving faster than the output pointer. A condition only
* triggered by data whose compressed form is larger than the uncompressed
* form.
*
* The worst case at the block level is a growth of the compressed data
* of 5 bytes per 32767 bytes.
*
* The worst case internal to a compressed block is very hard to figure.
* The worst case can at least be boundined by having one bit that represents
* 32764 bytes and then all of the rest of the bytes representing the very
* very last byte.
*
* All of which is enough to compute an amount of extra data that is required
* to be safe. To avoid problems at the block level allocating 5 extra bytes
* per 32767 bytes of data is sufficient. To avoind problems internal to a block
* adding an extra 32767 bytes (the worst case uncompressed block size) is
* sufficient, to ensure that in the worst case the decompressed data for
* block will stop the byte before the compressed data for a block begins.
* To avoid problems with the compressed data's meta information an extra 18
* bytes are needed. Leading to the formula:
*
* extra_bytes = (uncompressed_size >> 12) + 32768 + 18 + decompressor_size.
*
* Adding 8 bytes per 32K is a bit excessive but much easier to calculate.
* Adding 32768 instead of 32767 just makes for round numbers.
* Adding the decompressor_size is necessary as it musht live after all
* of the data as well. Last I measured the decompressor is about 14K.
* 10K of actual data and 4K of bss.
*
*/
/*
* gzip declarations
*/
#define OF(args) args
#define STATIC static
#undef memset
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n))
typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;
#define WSIZE 0x80000000 /* Window size must be at least 32k,
* and a power of two
* We don't actually have a window just
* a huge output buffer so I report
* a 2G windows size, as that should
* always be larger than our output buffer.
*/
static uch *inbuf; /* input buffer */
static uch *window; /* Sliding window buffer, (and final output buffer) */
static unsigned insize; /* valid bytes in inbuf */
static unsigned inptr; /* index of next byte to be processed in inbuf */
static unsigned outcnt; /* bytes in output buffer */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
#define RESERVED 0xC0 /* bit 6,7: reserved */
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
/* Diagnostic functions */
#ifdef DEBUG
# define Assert(cond,msg) {if(!(cond)) error(msg);}
# define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x ;}
# define Tracevv(x) {if (verbose>1) fprintf x ;}
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
static int fill_inbuf(void);
static void flush_window(void);
static void error(char *m);
static void gzip_mark(void **);
static void gzip_release(void **);
/*
* This is set up by the setup-routine at boot-time
*/
static unsigned char *real_mode; /* Pointer to real-mode data */
#define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2))
#ifndef STANDARD_MEMORY_BIOS_CALL
#define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0))
#endif
#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0))
extern unsigned char input_data[];
extern int input_len;
static long bytes_out = 0;
static void *malloc(int size);
static void free(void *where);
static void *memset(void *s, int c, unsigned n);
static void *memcpy(void *dest, const void *src, unsigned n);
static void putstr(const char *);
static long free_mem_ptr;
static long free_mem_end_ptr;
#define HEAP_SIZE 0x7000
static char *vidmem = (char *)0xb8000;
static int vidport;
static int lines, cols;
#include "../../../../lib/inflate.c"
static void *malloc(int size)
{
void *p;
if (size <0) error("Malloc error");
if (free_mem_ptr <= 0) error("Memory error");
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr;
free_mem_ptr += size;
if (free_mem_ptr >= free_mem_end_ptr)
error("Out of memory");
return p;
}
static void free(void *where)
{ /* Don't care */
}
static void gzip_mark(void **ptr)
{
*ptr = (void *) free_mem_ptr;
}
static void gzip_release(void **ptr)
{
free_mem_ptr = (long) *ptr;
}
static void scroll(void)
{
int i;
memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
vidmem[i] = ' ';
}
static void putstr(const char *s)
{
int x,y,pos;
char c;
x = RM_SCREEN_INFO.orig_x;
y = RM_SCREEN_INFO.orig_y;
while ( ( c = *s++ ) != '\0' ) {
if ( c == '\n' ) {
x = 0;
if ( ++y >= lines ) {
scroll();
y--;
}
} else {
vidmem [ ( x + cols * y ) * 2 ] = c;
if ( ++x >= cols ) {
x = 0;
if ( ++y >= lines ) {
scroll();
y--;
}
}
}
}
RM_SCREEN_INFO.orig_x = x;
RM_SCREEN_INFO.orig_y = y;
pos = (x + cols * y) * 2; /* Update cursor position */
outb_p(14, vidport);
outb_p(0xff & (pos >> 9), vidport+1);
outb_p(15, vidport);
outb_p(0xff & (pos >> 1), vidport+1);
}
static void* memset(void* s, int c, unsigned n)
{
int i;
char *ss = (char*)s;
for (i=0;i<n;i++) ss[i] = c;
return s;
}
static void* memcpy(void* dest, const void* src, unsigned n)
{
int i;
char *d = (char *)dest, *s = (char *)src;
for (i=0;i<n;i++) d[i] = s[i];
return dest;
}
/* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty
* and at least one byte is really needed.
*/
static int fill_inbuf(void)
{
error("ran out of input data");
return 0;
}
/* ===========================================================================
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
* (Used for the decompressed data only.)
*/
static void flush_window(void)
{
/* With my window equal to my output buffer
* I only need to compute the crc here.
*/
ulg c = crc; /* temporary variable */
unsigned n;
uch *in, ch;
in = window;
for (n = 0; n < outcnt; n++) {
ch = *in++;
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
}
crc = c;
bytes_out += (ulg)outcnt;
outcnt = 0;
}
static void error(char *x)
{
putstr("\n\n");
putstr(x);
putstr("\n\n -- System halted");
while(1); /* Halt */
}
asmlinkage void decompress_kernel(void *rmode, unsigned long heap,
uch *input_data, unsigned long input_len, uch *output)
{
real_mode = rmode;
if (RM_SCREEN_INFO.orig_video_mode == 7) {
vidmem = (char *) 0xb0000;
vidport = 0x3b4;
} else {
vidmem = (char *) 0xb8000;
vidport = 0x3d4;
}
lines = RM_SCREEN_INFO.orig_video_lines;
cols = RM_SCREEN_INFO.orig_video_cols;
window = output; /* Output buffer (Normally at 1M) */
free_mem_ptr = heap; /* Heap */
free_mem_end_ptr = heap + HEAP_SIZE;
inbuf = input_data; /* Input buffer */
insize = input_len;
inptr = 0;
if ((ulg)output & (__KERNEL_ALIGN - 1))
error("Destination address not 2M aligned");
if ((ulg)output >= 0xffffffffffUL)
error("Destination address too large");
makecrc();
putstr(".\nDecompressing Linux...");
gunzip();
putstr("done.\nBooting the kernel.\n");
return;
}
...@@ -27,11 +27,6 @@ static unsigned long *relocs; ...@@ -27,11 +27,6 @@ static unsigned long *relocs;
* absolute relocations present w.r.t these symbols. * absolute relocations present w.r.t these symbols.
*/ */
static const char* safe_abs_relocs[] = { static const char* safe_abs_relocs[] = {
"__kernel_vsyscall",
"__kernel_rt_sigreturn",
"__kernel_sigreturn",
"SYSENTER_RETURN",
"VDSO_NOTE_MASK",
"xen_irq_disable_direct_reloc", "xen_irq_disable_direct_reloc",
"xen_save_fl_direct_reloc", "xen_save_fl_direct_reloc",
}; };
...@@ -45,6 +40,8 @@ static int is_safe_abs_reloc(const char* sym_name) ...@@ -45,6 +40,8 @@ static int is_safe_abs_reloc(const char* sym_name)
/* Match found */ /* Match found */
return 1; return 1;
} }
if (strncmp(sym_name, "VDSO", 4) == 0)
return 1;
if (strncmp(sym_name, "__crc_", 6) == 0) if (strncmp(sym_name, "__crc_", 6) == 0)
return 1; return 1;
return 0; return 0;
......
SECTIONS SECTIONS
{ {
.text.compressed : { .rodata.compressed : {
input_len = .; input_len = .;
LONG(input_data_end - input_data) input_data = .; LONG(input_data_end - input_data) input_data = .;
*(.data) *(.data)
......
...@@ -3,17 +3,17 @@ OUTPUT_ARCH(i386) ...@@ -3,17 +3,17 @@ OUTPUT_ARCH(i386)
ENTRY(startup_32) ENTRY(startup_32)
SECTIONS SECTIONS
{ {
/* Be careful parts of head.S assume startup_32 is at /* Be careful parts of head_32.S assume startup_32 is at
* address 0. * address 0.
*/ */
. = 0 ; . = 0;
.text.head : { .text.head : {
_head = . ; _head = . ;
*(.text.head) *(.text.head)
_ehead = . ; _ehead = . ;
} }
.data.compressed : { .rodata.compressed : {
*(.data.compressed) *(.rodata.compressed)
} }
.text : { .text : {
_text = .; /* Text */ _text = .; /* Text */
......
SECTIONS
{
.data.compressed : {
input_len = .;
LONG(input_data_end - input_data) input_data = .;
*(.data)
output_len = . - 4;
input_data_end = .;
}
}
...@@ -3,15 +3,19 @@ OUTPUT_ARCH(i386:x86-64) ...@@ -3,15 +3,19 @@ OUTPUT_ARCH(i386:x86-64)
ENTRY(startup_64) ENTRY(startup_64)
SECTIONS SECTIONS
{ {
/* Be careful parts of head.S assume startup_32 is at /* Be careful parts of head_64.S assume startup_64 is at
* address 0. * address 0.
*/ */
. = 0; . = 0;
.text : { .text.head : {
_head = . ; _head = . ;
*(.text.head) *(.text.head)
_ehead = . ; _ehead = . ;
*(.text.compressed) }
.rodata.compressed : {
*(.rodata.compressed)
}
.text : {
_text = .; /* Text */ _text = .; /* Text */
*(.text) *(.text)
*(.text.*) *(.text.*)
......
...@@ -129,6 +129,7 @@ void query_edd(void) ...@@ -129,6 +129,7 @@ void query_edd(void)
char eddarg[8]; char eddarg[8];
int do_mbr = 1; int do_mbr = 1;
int do_edd = 1; int do_edd = 1;
int be_quiet;
int devno; int devno;
struct edd_info ei, *edp; struct edd_info ei, *edp;
u32 *mbrptr; u32 *mbrptr;
...@@ -140,12 +141,21 @@ void query_edd(void) ...@@ -140,12 +141,21 @@ void query_edd(void)
do_edd = 0; do_edd = 0;
} }
be_quiet = cmdline_find_option_bool("quiet");
edp = boot_params.eddbuf; edp = boot_params.eddbuf;
mbrptr = boot_params.edd_mbr_sig_buffer; mbrptr = boot_params.edd_mbr_sig_buffer;
if (!do_edd) if (!do_edd)
return; return;
/* Bugs in OnBoard or AddOnCards Bios may hang the EDD probe,
* so give a hint if this happens.
*/
if (!be_quiet)
printf("Probing EDD (edd=off to disable)... ");
for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) { for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
/* /*
* Scan the BIOS-supported hard disks and query EDD * Scan the BIOS-supported hard disks and query EDD
...@@ -162,6 +172,9 @@ void query_edd(void) ...@@ -162,6 +172,9 @@ void query_edd(void)
if (do_mbr && !read_mbr_sig(devno, &ei, mbrptr++)) if (do_mbr && !read_mbr_sig(devno, &ei, mbrptr++))
boot_params.edd_mbr_sig_buf_entries = devno-0x80+1; boot_params.edd_mbr_sig_buf_entries = devno-0x80+1;
} }
if (!be_quiet)
printf("ok\n");
} }
#endif #endif
...@@ -195,10 +195,13 @@ cmd_line_ptr: .long 0 # (Header version 0x0202 or later) ...@@ -195,10 +195,13 @@ cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
# can be located anywhere in # can be located anywhere in
# low memory 0x10000 or higher. # low memory 0x10000 or higher.
ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff ramdisk_max: .long 0x7fffffff
# (Header version 0x0203 or later) # (Header version 0x0203 or later)
# The highest safe address for # The highest safe address for
# the contents of an initrd # the contents of an initrd
# The current kernel allows up to 4 GB,
# but leave it at 2 GB to avoid
# possible bootloader bugs.
kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
#required for protected mode #required for protected mode
......
...@@ -100,20 +100,32 @@ static void set_bios_mode(void) ...@@ -100,20 +100,32 @@ static void set_bios_mode(void)
#endif #endif
} }
void main(void) static void init_heap(void)
{ {
/* First, copy the boot header into the "zeropage" */ char *stack_end;
copy_boot_params();
/* End of heap check */
if (boot_params.hdr.loadflags & CAN_USE_HEAP) { if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
heap_end = (char *)(boot_params.hdr.heap_end_ptr asm("leal %P1(%%esp),%0"
+0x200-STACK_SIZE); : "=r" (stack_end) : "i" (-STACK_SIZE));
heap_end = (char *)
((size_t)boot_params.hdr.heap_end_ptr + 0x200);
if (heap_end > stack_end)
heap_end = stack_end;
} else { } else {
/* Boot protocol 2.00 only, no heap available */ /* Boot protocol 2.00 only, no heap available */
puts("WARNING: Ancient bootloader, some functionality " puts("WARNING: Ancient bootloader, some functionality "
"may be limited!\n"); "may be limited!\n");
} }
}
void main(void)
{
/* First, copy the boot header into the "zeropage" */
copy_boot_params();
/* End of heap check */
init_heap();
/* Make sure we have all the proper CPU support */ /* Make sure we have all the proper CPU support */
if (validate_cpu()) { if (validate_cpu()) {
...@@ -131,9 +143,6 @@ void main(void) ...@@ -131,9 +143,6 @@ void main(void)
/* Set keyboard repeat rate (why?) */ /* Set keyboard repeat rate (why?) */
keyboard_set_repeat(); keyboard_set_repeat();
/* Set the video mode */
set_video();
/* Query MCA information */ /* Query MCA information */
query_mca(); query_mca();
...@@ -154,6 +163,10 @@ void main(void) ...@@ -154,6 +163,10 @@ void main(void)
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
query_edd(); query_edd();
#endif #endif
/* Set the video mode */
set_video();
/* Do the last things and invoke protected mode */ /* Do the last things and invoke protected mode */
go_to_protected_mode(); go_to_protected_mode();
} }
...@@ -104,7 +104,7 @@ static void reset_coprocessor(void) ...@@ -104,7 +104,7 @@ static void reset_coprocessor(void)
(((u64)(base & 0xff000000) << 32) | \ (((u64)(base & 0xff000000) << 32) | \
((u64)flags << 40) | \ ((u64)flags << 40) | \
((u64)(limit & 0x00ff0000) << 32) | \ ((u64)(limit & 0x00ff0000) << 32) | \
((u64)(base & 0x00ffff00) << 16) | \ ((u64)(base & 0x00ffffff) << 16) | \
((u64)(limit & 0x0000ffff))) ((u64)(limit & 0x0000ffff)))
struct gdt_ptr { struct gdt_ptr {
...@@ -121,6 +121,10 @@ static void setup_gdt(void) ...@@ -121,6 +121,10 @@ static void setup_gdt(void)
[GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff), [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
/* DS: data, read/write, 4 GB, base 0 */ /* DS: data, read/write, 4 GB, base 0 */
[GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
/* TSS: 32-bit tss, 104 bytes, base 4096 */
/* We only have a TSS here to keep Intel VT happy;
we don't actually use it for anything. */
[GDT_ENTRY_BOOT_TSS] = GDT_ENTRY(0x0089, 4096, 103),
}; };
/* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead /* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead
of the gdt_ptr contents. Thus, make it static so it will of the gdt_ptr contents. Thus, make it static so it will
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
#include <asm/boot.h> #include <asm/boot.h>
#include <asm/processor-flags.h>
#include <asm/segment.h> #include <asm/segment.h>
.text .text
...@@ -29,28 +30,55 @@ ...@@ -29,28 +30,55 @@
*/ */
protected_mode_jump: protected_mode_jump:
movl %edx, %esi # Pointer to boot_params table movl %edx, %esi # Pointer to boot_params table
movl %eax, 2f # Patch ljmpl instruction
xorl %ebx, %ebx
movw %cs, %bx
shll $4, %ebx
addl %ebx, 2f
movw $__BOOT_DS, %cx movw $__BOOT_DS, %cx
xorl %ebx, %ebx # Per the 32-bit boot protocol movw $__BOOT_TSS, %di
xorl %ebp, %ebp # Per the 32-bit boot protocol
xorl %edi, %edi # Per the 32-bit boot protocol
movl %cr0, %edx movl %cr0, %edx
orb $1, %dl # Protected mode (PE) bit orb $X86_CR0_PE, %dl # Protected mode
movl %edx, %cr0 movl %edx, %cr0
jmp 1f # Short jump to serialize on 386/486 jmp 1f # Short jump to serialize on 386/486
1: 1:
movw %cx, %ds # Transition to 32-bit mode
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ss
# Jump to the 32-bit entrypoint
.byte 0x66, 0xea # ljmpl opcode .byte 0x66, 0xea # ljmpl opcode
2: .long 0 # offset 2: .long in_pm32 # offset
.word __BOOT_CS # segment .word __BOOT_CS # segment
.size protected_mode_jump, .-protected_mode_jump .size protected_mode_jump, .-protected_mode_jump
.code32
.type in_pm32, @function
in_pm32:
# Set up data segments for flat 32-bit mode
movl %ecx, %ds
movl %ecx, %es
movl %ecx, %fs
movl %ecx, %gs
movl %ecx, %ss
# The 32-bit code sets up its own stack, but this way we do have
# a valid stack if some debugging hack wants to use it.
addl %ebx, %esp
# Set up TR to make Intel VT happy
ltr %di
# Clear registers to allow for future extensions to the
# 32-bit boot protocol
xorl %ecx, %ecx
xorl %edx, %edx
xorl %ebx, %ebx
xorl %ebp, %ebp
xorl %edi, %edi
# Set up LDTR to make Intel VT happy
lldt %cx
jmpl *%eax # Jump to the 32-bit entrypoint
.size in_pm32, .-in_pm32
...@@ -104,6 +104,7 @@ static int bios_probe(void) ...@@ -104,6 +104,7 @@ static int bios_probe(void)
mi = GET_HEAP(struct mode_info, 1); mi = GET_HEAP(struct mode_info, 1);
mi->mode = VIDEO_FIRST_BIOS+mode; mi->mode = VIDEO_FIRST_BIOS+mode;
mi->depth = 0; /* text */
mi->x = rdfs16(0x44a); mi->x = rdfs16(0x44a);
mi->y = rdfs8(0x484)+1; mi->y = rdfs8(0x484)+1;
nmodes++; nmodes++;
...@@ -116,7 +117,7 @@ static int bios_probe(void) ...@@ -116,7 +117,7 @@ static int bios_probe(void)
__videocard video_bios = __videocard video_bios =
{ {
.card_name = "BIOS (scanned)", .card_name = "BIOS",
.probe = bios_probe, .probe = bios_probe,
.set_mode = bios_set_mode, .set_mode = bios_set_mode,
.unsafe = 1, .unsafe = 1,
......
...@@ -79,20 +79,28 @@ static int vesa_probe(void) ...@@ -79,20 +79,28 @@ static int vesa_probe(void)
/* Text Mode, TTY BIOS supported, /* Text Mode, TTY BIOS supported,
supported by hardware */ supported by hardware */
mi = GET_HEAP(struct mode_info, 1); mi = GET_HEAP(struct mode_info, 1);
mi->mode = mode + VIDEO_FIRST_VESA; mi->mode = mode + VIDEO_FIRST_VESA;
mi->x = vminfo.h_res; mi->depth = 0; /* text */
mi->y = vminfo.v_res; mi->x = vminfo.h_res;
mi->y = vminfo.v_res;
nmodes++; nmodes++;
} else if ((vminfo.mode_attr & 0x99) == 0x99) { } else if ((vminfo.mode_attr & 0x99) == 0x99 &&
(vminfo.memory_layout == 4 ||
vminfo.memory_layout == 6) &&
vminfo.memory_planes == 1) {
#ifdef CONFIG_FB #ifdef CONFIG_FB
/* Graphics mode, color, linear frame buffer /* Graphics mode, color, linear frame buffer
supported -- register the mode but hide from supported. Only register the mode if
the menu. Only do this if framebuffer is if framebuffer is configured, however,
configured, however, otherwise the user will otherwise the user will be left without a screen.
be left without a screen. */ We don't require CONFIG_FB_VESA, however, since
some of the other framebuffer drivers can use
this mode-setting, too. */
mi = GET_HEAP(struct mode_info, 1); mi = GET_HEAP(struct mode_info, 1);
mi->mode = mode + VIDEO_FIRST_VESA; mi->mode = mode + VIDEO_FIRST_VESA;
mi->x = mi->y = 0; mi->depth = vminfo.bpp;
mi->x = vminfo.h_res;
mi->y = vminfo.v_res;
nmodes++; nmodes++;
#endif #endif
} }
......
...@@ -18,22 +18,22 @@ ...@@ -18,22 +18,22 @@
#include "video.h" #include "video.h"
static struct mode_info vga_modes[] = { static struct mode_info vga_modes[] = {
{ VIDEO_80x25, 80, 25 }, { VIDEO_80x25, 80, 25, 0 },
{ VIDEO_8POINT, 80, 50 }, { VIDEO_8POINT, 80, 50, 0 },
{ VIDEO_80x43, 80, 43 }, { VIDEO_80x43, 80, 43, 0 },
{ VIDEO_80x28, 80, 28 }, { VIDEO_80x28, 80, 28, 0 },
{ VIDEO_80x30, 80, 30 }, { VIDEO_80x30, 80, 30, 0 },
{ VIDEO_80x34, 80, 34 }, { VIDEO_80x34, 80, 34, 0 },
{ VIDEO_80x60, 80, 60 }, { VIDEO_80x60, 80, 60, 0 },
}; };
static struct mode_info ega_modes[] = { static struct mode_info ega_modes[] = {
{ VIDEO_80x25, 80, 25 }, { VIDEO_80x25, 80, 25, 0 },
{ VIDEO_8POINT, 80, 43 }, { VIDEO_8POINT, 80, 43, 0 },
}; };
static struct mode_info cga_modes[] = { static struct mode_info cga_modes[] = {
{ VIDEO_80x25, 80, 25 }, { VIDEO_80x25, 80, 25, 0 },
}; };
__videocard video_vga; __videocard video_vga;
......
...@@ -293,13 +293,28 @@ static void display_menu(void) ...@@ -293,13 +293,28 @@ static void display_menu(void)
struct mode_info *mi; struct mode_info *mi;
char ch; char ch;
int i; int i;
int nmodes;
int modes_per_line;
int col;
puts("Mode: COLSxROWS:\n"); nmodes = 0;
for (card = video_cards; card < video_cards_end; card++)
nmodes += card->nmodes;
modes_per_line = 1;
if (nmodes >= 20)
modes_per_line = 3;
for (col = 0; col < modes_per_line; col++)
puts("Mode: Resolution: Type: ");
putchar('\n');
col = 0;
ch = '0'; ch = '0';
for (card = video_cards; card < video_cards_end; card++) { for (card = video_cards; card < video_cards_end; card++) {
mi = card->modes; mi = card->modes;
for (i = 0; i < card->nmodes; i++, mi++) { for (i = 0; i < card->nmodes; i++, mi++) {
char resbuf[32];
int visible = mi->x && mi->y; int visible = mi->x && mi->y;
u16 mode_id = mi->mode ? mi->mode : u16 mode_id = mi->mode ? mi->mode :
(mi->y << 8)+mi->x; (mi->y << 8)+mi->x;
...@@ -307,8 +322,18 @@ static void display_menu(void) ...@@ -307,8 +322,18 @@ static void display_menu(void)
if (!visible) if (!visible)
continue; /* Hidden mode */ continue; /* Hidden mode */
printf("%c %04X %3dx%-3d %s\n", if (mi->depth)
ch, mode_id, mi->x, mi->y, card->card_name); sprintf(resbuf, "%dx%d", mi->y, mi->depth);
else
sprintf(resbuf, "%d", mi->y);
printf("%c %03X %4dx%-7s %-6s",
ch, mode_id, mi->x, resbuf, card->card_name);
col++;
if (col >= modes_per_line) {
putchar('\n');
col = 0;
}
if (ch == '9') if (ch == '9')
ch = 'a'; ch = 'a';
...@@ -318,6 +343,8 @@ static void display_menu(void) ...@@ -318,6 +343,8 @@ static void display_menu(void)
ch++; ch++;
} }
} }
if (col)
putchar('\n');
} }
#define H(x) ((x)-'a'+10) #define H(x) ((x)-'a'+10)
......
...@@ -83,7 +83,8 @@ void store_screen(void); ...@@ -83,7 +83,8 @@ void store_screen(void);
struct mode_info { struct mode_info {
u16 mode; /* Mode number (vga= style) */ u16 mode; /* Mode number (vga= style) */
u8 x, y; /* Width, height */ u16 x, y; /* Width, height */
u16 depth; /* Bits per pixel, 0 for text mode */
}; };
struct card_info { struct card_info {
......
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
#include "boot.h" #include "boot.h"
#ifdef CONFIG_X86_VOYAGER
int query_voyager(void) int query_voyager(void)
{ {
u8 err; u8 err;
...@@ -42,5 +40,3 @@ int query_voyager(void) ...@@ -42,5 +40,3 @@ int query_voyager(void)
copy_from_fs(data_ptr, di, 7); /* Table is 7 bytes apparently */ copy_from_fs(data_ptr, di, 7); /* Table is 7 bytes apparently */
return 0; return 0;
} }
#endif /* CONFIG_X86_VOYAGER */
...@@ -99,9 +99,9 @@ CONFIG_IOSCHED_NOOP=y ...@@ -99,9 +99,9 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set # CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_DEFAULT_IOSCHED="anticipatory"
......
...@@ -145,15 +145,6 @@ CONFIG_K8_NUMA=y ...@@ -145,15 +145,6 @@ CONFIG_K8_NUMA=y
CONFIG_NODES_SHIFT=6 CONFIG_NODES_SHIFT=6
CONFIG_X86_64_ACPI_NUMA=y CONFIG_X86_64_ACPI_NUMA=y
CONFIG_NUMA_EMU=y CONFIG_NUMA_EMU=y
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
CONFIG_DISCONTIGMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_DISCONTIGMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_NEED_MULTIPLE_NODES=y CONFIG_NEED_MULTIPLE_NODES=y
# CONFIG_SPARSEMEM_STATIC is not set # CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_SPLIT_PTLOCK_CPUS=4
......
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
# Makefile for the ia32 kernel emulation subsystem. # Makefile for the ia32 kernel emulation subsystem.
# #
obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \ obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o
ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o \
mmap32.o
sysv-$(CONFIG_SYSVIPC) := ipc32.o sysv-$(CONFIG_SYSVIPC) := ipc32.o
obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) obj-$(CONFIG_IA32_EMULATION) += $(sysv-y)
...@@ -13,40 +11,3 @@ obj-$(CONFIG_IA32_AOUT) += ia32_aout.o ...@@ -13,40 +11,3 @@ obj-$(CONFIG_IA32_AOUT) += ia32_aout.o
audit-class-$(CONFIG_AUDIT) := audit.o audit-class-$(CONFIG_AUDIT) := audit.o
obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y) obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y)
$(obj)/syscall32_syscall.o: \
$(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so)
# Teach kbuild about targets
targets := $(foreach F,$(addprefix vsyscall-,sysenter syscall),\
$F.o $F.so $F.so.dbg)
# The DSO images are built using a special linker script
quiet_cmd_syscall = SYSCALL $@
cmd_syscall = $(CC) -m32 -nostdlib -shared \
$(call ld-option, -Wl$(comma)--hash-style=sysv) \
-Wl,-soname=linux-gate.so.1 -o $@ \
-Wl,-T,$(filter-out FORCE,$^)
$(obj)/%.so: OBJCOPYFLAGS := -S
$(obj)/%.so: $(obj)/%.so.dbg FORCE
$(call if_changed,objcopy)
$(obj)/vsyscall-sysenter.so.dbg $(obj)/vsyscall-syscall.so.dbg: \
$(obj)/vsyscall-%.so.dbg: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
$(call if_changed,syscall)
AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
vdsos := vdso32-sysenter.so vdso32-syscall.so
quiet_cmd_vdso_install = INSTALL $@
cmd_vdso_install = cp $(@:vdso32-%.so=$(obj)/vsyscall-%.so.dbg) \
$(MODLIB)/vdso/$@
$(vdsos):
@mkdir -p $(MODLIB)/vdso
$(call cmd,vdso_install)
vdso_install: $(vdsos)
...@@ -27,7 +27,7 @@ unsigned ia32_signal_class[] = { ...@@ -27,7 +27,7 @@ unsigned ia32_signal_class[] = {
int ia32_classify_syscall(unsigned syscall) int ia32_classify_syscall(unsigned syscall)
{ {
switch(syscall) { switch (syscall) {
case __NR_open: case __NR_open:
return 2; return 2;
case __NR_openat: case __NR_openat:
......
/*
* Copyright 2002 Andi Kleen, SuSE Labs.
* FXSAVE<->i387 conversion support. Based on code by Gareth Hughes.
* This is used for ptrace, signals and coredumps in 32bit emulation.
*/
#include <linux/sched.h>
#include <asm/sigcontext32.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/i387.h>
static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
{
unsigned int tmp; /* to avoid 16 bit prefixes in the code */
/* Transform each pair of bits into 01 (valid) or 00 (empty) */
tmp = ~twd;
tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
/* and move the valid bits to the lower byte. */
tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
return tmp;
}
static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
{
struct _fpxreg *st = NULL;
unsigned long tos = (fxsave->swd >> 11) & 7;
unsigned long twd = (unsigned long) fxsave->twd;
unsigned long tag;
unsigned long ret = 0xffff0000;
int i;
#define FPREG_ADDR(f, n) ((void *)&(f)->st_space + (n) * 16);
for (i = 0 ; i < 8 ; i++) {
if (twd & 0x1) {
st = FPREG_ADDR( fxsave, (i - tos) & 7 );
switch (st->exponent & 0x7fff) {
case 0x7fff:
tag = 2; /* Special */
break;
case 0x0000:
if ( !st->significand[0] &&
!st->significand[1] &&
!st->significand[2] &&
!st->significand[3] ) {
tag = 1; /* Zero */
} else {
tag = 2; /* Special */
}
break;
default:
if (st->significand[3] & 0x8000) {
tag = 0; /* Valid */
} else {
tag = 2; /* Special */
}
break;
}
} else {
tag = 3; /* Empty */
}
ret |= (tag << (2 * i));
twd = twd >> 1;
}
return ret;
}
static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave,
struct _fpstate_ia32 __user *buf)
{
struct _fpxreg *to;
struct _fpreg __user *from;
int i;
u32 v;
int err = 0;
#define G(num,val) err |= __get_user(val, num + (u32 __user *)buf)
G(0, fxsave->cwd);
G(1, fxsave->swd);
G(2, fxsave->twd);
fxsave->twd = twd_i387_to_fxsr(fxsave->twd);
G(3, fxsave->rip);
G(4, v);
fxsave->fop = v>>16; /* cs ignored */
G(5, fxsave->rdp);
/* 6: ds ignored */
#undef G
if (err)
return -1;
to = (struct _fpxreg *)&fxsave->st_space[0];
from = &buf->_st[0];
for (i = 0 ; i < 8 ; i++, to++, from++) {
if (__copy_from_user(to, from, sizeof(*from)))
return -1;
}
return 0;
}
static inline int convert_fxsr_to_user(struct _fpstate_ia32 __user *buf,
struct i387_fxsave_struct *fxsave,
struct pt_regs *regs,
struct task_struct *tsk)
{
struct _fpreg __user *to;
struct _fpxreg *from;
int i;
u16 cs,ds;
int err = 0;
if (tsk == current) {
/* should be actually ds/cs at fpu exception time,
but that information is not available in 64bit mode. */
asm("movw %%ds,%0 " : "=r" (ds));
asm("movw %%cs,%0 " : "=r" (cs));
} else { /* ptrace. task has stopped. */
ds = tsk->thread.ds;
cs = regs->cs;
}
#define P(num,val) err |= __put_user(val, num + (u32 __user *)buf)
P(0, (u32)fxsave->cwd | 0xffff0000);
P(1, (u32)fxsave->swd | 0xffff0000);
P(2, twd_fxsr_to_i387(fxsave));
P(3, (u32)fxsave->rip);
P(4, cs | ((u32)fxsave->fop) << 16);
P(5, fxsave->rdp);
P(6, 0xffff0000 | ds);
#undef P
if (err)
return -1;
to = &buf->_st[0];
from = (struct _fpxreg *) &fxsave->st_space[0];
for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
if (__copy_to_user(to, from, sizeof(*to)))
return -1;
}
return 0;
}
int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave)
{
clear_fpu(tsk);
if (!fsave) {
if (__copy_from_user(&tsk->thread.i387.fxsave,
&buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct)))
return -1;
tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
set_stopped_child_used_math(tsk);
}
return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
}
int save_i387_ia32(struct task_struct *tsk,
struct _fpstate_ia32 __user *buf,
struct pt_regs *regs,
int fsave)
{
int err = 0;
init_fpu(tsk);
if (convert_fxsr_to_user(buf, &tsk->thread.i387.fxsave, regs, tsk))
return -1;
if (fsave)
return 0;
err |= __put_user(tsk->thread.i387.fxsave.swd, &buf->status);
if (fsave)
return err ? -1 : 1;
err |= __put_user(X86_FXSR_MAGIC, &buf->magic);
err |= __copy_to_user(&buf->_fxsr_env[0], &tsk->thread.i387.fxsave,
sizeof(struct i387_fxsave_struct));
return err ? -1 : 1;
}
This diff is collapsed.
/*
* Written 2000,2002 by Andi Kleen.
*
* Loosely based on the sparc64 and IA64 32bit emulation loaders.
* This tricks binfmt_elf.c into loading 32bit binaries using lots
* of ugly preprocessor tricks. Talk about very very poor man's inheritance.
*/
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/rwsem.h>
#include <linux/sched.h>
#include <linux/compat.h>
#include <linux/string.h>
#include <linux/binfmts.h>
#include <linux/mm.h>
#include <linux/security.h>
#include <linux/elfcore-compat.h>
#include <asm/segment.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
#include <asm/user32.h>
#include <asm/sigcontext32.h>
#include <asm/fpu32.h>
#include <asm/i387.h>
#include <asm/uaccess.h>
#include <asm/ia32.h>
#include <asm/vsyscall32.h>
#undef ELF_ARCH
#undef ELF_CLASS
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_386
#undef elfhdr
#undef elf_phdr
#undef elf_note
#undef elf_addr_t
#define elfhdr elf32_hdr
#define elf_phdr elf32_phdr
#define elf_note elf32_note
#define elf_addr_t Elf32_Off
#define ELF_NAME "elf/i386"
#define AT_SYSINFO 32
#define AT_SYSINFO_EHDR 33
int sysctl_vsyscall32 = 1;
#undef ARCH_DLINFO
#define ARCH_DLINFO do { \
if (sysctl_vsyscall32) { \
current->mm->context.vdso = (void *)VSYSCALL32_BASE; \
NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
} \
} while(0)
struct file;
#define IA32_EMULATOR 1
#undef ELF_ET_DYN_BASE
#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
#define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
#define _GET_SEG(x) \
({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; })
/* Assumes current==process to be dumped */
#undef ELF_CORE_COPY_REGS
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
pr_reg[0] = regs->rbx; \
pr_reg[1] = regs->rcx; \
pr_reg[2] = regs->rdx; \
pr_reg[3] = regs->rsi; \
pr_reg[4] = regs->rdi; \
pr_reg[5] = regs->rbp; \
pr_reg[6] = regs->rax; \
pr_reg[7] = _GET_SEG(ds); \
pr_reg[8] = _GET_SEG(es); \
pr_reg[9] = _GET_SEG(fs); \
pr_reg[10] = _GET_SEG(gs); \
pr_reg[11] = regs->orig_rax; \
pr_reg[12] = regs->rip; \
pr_reg[13] = regs->cs; \
pr_reg[14] = regs->eflags; \
pr_reg[15] = regs->rsp; \
pr_reg[16] = regs->ss;
#define elf_prstatus compat_elf_prstatus
#define elf_prpsinfo compat_elf_prpsinfo
#define elf_fpregset_t struct user_i387_ia32_struct
#define elf_fpxregset_t struct user32_fxsr_struct
#define user user32
#undef elf_read_implies_exec
#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)
#define elf_core_copy_regs elf32_core_copy_regs
static inline void elf32_core_copy_regs(compat_elf_gregset_t *elfregs,
struct pt_regs *regs)
{
ELF_CORE_COPY_REGS((&elfregs->ebx), regs)
}
#define elf_core_copy_task_regs elf32_core_copy_task_regs
static inline int elf32_core_copy_task_regs(struct task_struct *t,
compat_elf_gregset_t* elfregs)
{
struct pt_regs *pp = task_pt_regs(t);
ELF_CORE_COPY_REGS((&elfregs->ebx), pp);
/* fix wrong segments */
elfregs->ds = t->thread.ds;
elfregs->fs = t->thread.fsindex;
elfregs->gs = t->thread.gsindex;
elfregs->es = t->thread.es;
return 1;
}
#define elf_core_copy_task_fpregs elf32_core_copy_task_fpregs
static inline int
elf32_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs,
elf_fpregset_t *fpu)
{
struct _fpstate_ia32 *fpstate = (void*)fpu;
mm_segment_t oldfs = get_fs();
if (!tsk_used_math(tsk))
return 0;
if (!regs)
regs = task_pt_regs(tsk);
if (tsk == current)
unlazy_fpu(tsk);
set_fs(KERNEL_DS);
save_i387_ia32(tsk, fpstate, regs, 1);
/* Correct for i386 bug. It puts the fop into the upper 16bits of
the tag word (like FXSAVE), not into the fcs*/
fpstate->cssel |= fpstate->tag & 0xffff0000;
set_fs(oldfs);
return 1;
}
#define ELF_CORE_COPY_XFPREGS 1
#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
#define elf_core_copy_task_xfpregs elf32_core_copy_task_xfpregs
static inline int
elf32_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
{
struct pt_regs *regs = task_pt_regs(t);
if (!tsk_used_math(t))
return 0;
if (t == current)
unlazy_fpu(t);
memcpy(xfpu, &t->thread.i387.fxsave, sizeof(elf_fpxregset_t));
xfpu->fcs = regs->cs;
xfpu->fos = t->thread.ds; /* right? */
return 1;
}
#undef elf_check_arch
#define elf_check_arch(x) \
((x)->e_machine == EM_386)
extern int force_personality32;
#undef ELF_EXEC_PAGESIZE
#undef ELF_HWCAP
#undef ELF_PLATFORM
#undef SET_PERSONALITY
#define ELF_EXEC_PAGESIZE PAGE_SIZE
#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
#define ELF_PLATFORM ("i686")
#define SET_PERSONALITY(ex, ibcs2) \
do { \
unsigned long new_flags = 0; \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
new_flags = _TIF_IA32; \
if ((current_thread_info()->flags & _TIF_IA32) \
!= new_flags) \
set_thread_flag(TIF_ABI_PENDING); \
else \
clear_thread_flag(TIF_ABI_PENDING); \
/* XXX This overwrites the user set personality */ \
current->personality |= force_personality32; \
} while (0)
/* Override some function names */
#define elf_format elf32_format
#define init_elf_binfmt init_elf32_binfmt
#define exit_elf_binfmt exit_elf32_binfmt
#define load_elf_binary load_elf32_binary
#undef ELF_PLAT_INIT
#define ELF_PLAT_INIT(r, load_addr) elf32_init(r)
#undef start_thread
#define start_thread(regs,new_rip,new_rsp) do { \
asm volatile("movl %0,%%fs" :: "r" (0)); \
asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); \
load_gs_index(0); \
(regs)->rip = (new_rip); \
(regs)->rsp = (new_rsp); \
(regs)->eflags = 0x200; \
(regs)->cs = __USER32_CS; \
(regs)->ss = __USER32_DS; \
set_fs(USER_DS); \
} while(0)
#include <linux/module.h>
MODULE_DESCRIPTION("Binary format loader for compatibility with IA32 ELF binaries.");
MODULE_AUTHOR("Eric Youngdale, Andi Kleen");
#undef MODULE_DESCRIPTION
#undef MODULE_AUTHOR
static void elf32_init(struct pt_regs *);
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
#define arch_setup_additional_pages syscall32_setup_pages
extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
#include "../../../fs/binfmt_elf.c"
static void elf32_init(struct pt_regs *regs)
{
struct task_struct *me = current;
regs->rdi = 0;
regs->rsi = 0;
regs->rdx = 0;
regs->rcx = 0;
regs->rax = 0;
regs->rbx = 0;
regs->rbp = 0;
regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
regs->r13 = regs->r14 = regs->r15 = 0;
me->thread.fs = 0;
me->thread.gs = 0;
me->thread.fsindex = 0;
me->thread.gsindex = 0;
me->thread.ds = __USER_DS;
me->thread.es = __USER_DS;
}
#ifdef CONFIG_SYSCTL
/* Register vsyscall32 into the ABI table */
#include <linux/sysctl.h>
static ctl_table abi_table2[] = {
{
.procname = "vsyscall32",
.data = &sysctl_vsyscall32,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{}
};
static ctl_table abi_root_table2[] = {
{
.ctl_name = CTL_ABI,
.procname = "abi",
.mode = 0555,
.child = abi_table2
},
{}
};
static __init int ia32_binfmt_init(void)
{
register_sysctl_table(abi_root_table2);
return 0;
}
__initcall(ia32_binfmt_init);
#endif
This diff is collapsed.
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <asm/ia32_unistd.h> #include <asm/ia32_unistd.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/vsyscall32.h>
#include <asm/irqflags.h> #include <asm/irqflags.h>
#include <linux/linkage.h> #include <linux/linkage.h>
...@@ -104,7 +103,7 @@ ENTRY(ia32_sysenter_target) ...@@ -104,7 +103,7 @@ ENTRY(ia32_sysenter_target)
pushfq pushfq
CFI_ADJUST_CFA_OFFSET 8 CFI_ADJUST_CFA_OFFSET 8
/*CFI_REL_OFFSET rflags,0*/ /*CFI_REL_OFFSET rflags,0*/
movl $VSYSCALL32_SYSEXIT, %r10d movl 8*3-THREAD_SIZE+threadinfo_sysenter_return(%rsp), %r10d
CFI_REGISTER rip,r10 CFI_REGISTER rip,r10
pushq $__USER32_CS pushq $__USER32_CS
CFI_ADJUST_CFA_OFFSET 8 CFI_ADJUST_CFA_OFFSET 8
...@@ -142,6 +141,8 @@ sysenter_do_call: ...@@ -142,6 +141,8 @@ sysenter_do_call:
andl $~TS_COMPAT,threadinfo_status(%r10) andl $~TS_COMPAT,threadinfo_status(%r10)
/* clear IF, that popfq doesn't enable interrupts early */ /* clear IF, that popfq doesn't enable interrupts early */
andl $~0x200,EFLAGS-R11(%rsp) andl $~0x200,EFLAGS-R11(%rsp)
movl RIP-R11(%rsp),%edx /* User %eip */
CFI_REGISTER rip,rdx
RESTORE_ARGS 1,24,1,1,1,1 RESTORE_ARGS 1,24,1,1,1,1
popfq popfq
CFI_ADJUST_CFA_OFFSET -8 CFI_ADJUST_CFA_OFFSET -8
...@@ -149,8 +150,6 @@ sysenter_do_call: ...@@ -149,8 +150,6 @@ sysenter_do_call:
popq %rcx /* User %esp */ popq %rcx /* User %esp */
CFI_ADJUST_CFA_OFFSET -8 CFI_ADJUST_CFA_OFFSET -8
CFI_REGISTER rsp,rcx CFI_REGISTER rsp,rcx
movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */
CFI_REGISTER rip,rdx
TRACE_IRQS_ON TRACE_IRQS_ON
swapgs swapgs
sti /* sti only takes effect after the next instruction */ sti /* sti only takes effect after the next instruction */
...@@ -644,8 +643,8 @@ ia32_sys_call_table: ...@@ -644,8 +643,8 @@ ia32_sys_call_table:
.quad compat_sys_futex /* 240 */ .quad compat_sys_futex /* 240 */
.quad compat_sys_sched_setaffinity .quad compat_sys_sched_setaffinity
.quad compat_sys_sched_getaffinity .quad compat_sys_sched_getaffinity
.quad sys32_set_thread_area .quad sys_set_thread_area
.quad sys32_get_thread_area .quad sys_get_thread_area
.quad compat_sys_io_setup /* 245 */ .quad compat_sys_io_setup /* 245 */
.quad sys_io_destroy .quad sys_io_destroy
.quad compat_sys_io_getevents .quad compat_sys_io_getevents
......
...@@ -9,9 +9,8 @@ ...@@ -9,9 +9,8 @@
#include <linux/ipc.h> #include <linux/ipc.h>
#include <linux/compat.h> #include <linux/compat.h>
asmlinkage long asmlinkage long sys32_ipc(u32 call, int first, int second, int third,
sys32_ipc(u32 call, int first, int second, int third, compat_uptr_t ptr, u32 fifth)
compat_uptr_t ptr, u32 fifth)
{ {
int version; int version;
...@@ -19,36 +18,35 @@ sys32_ipc(u32 call, int first, int second, int third, ...@@ -19,36 +18,35 @@ sys32_ipc(u32 call, int first, int second, int third,
call &= 0xffff; call &= 0xffff;
switch (call) { switch (call) {
case SEMOP: case SEMOP:
/* struct sembuf is the same on 32 and 64bit :)) */ /* struct sembuf is the same on 32 and 64bit :)) */
return sys_semtimedop(first, compat_ptr(ptr), second, NULL); return sys_semtimedop(first, compat_ptr(ptr), second, NULL);
case SEMTIMEDOP: case SEMTIMEDOP:
return compat_sys_semtimedop(first, compat_ptr(ptr), second, return compat_sys_semtimedop(first, compat_ptr(ptr), second,
compat_ptr(fifth)); compat_ptr(fifth));
case SEMGET: case SEMGET:
return sys_semget(first, second, third); return sys_semget(first, second, third);
case SEMCTL: case SEMCTL:
return compat_sys_semctl(first, second, third, compat_ptr(ptr)); return compat_sys_semctl(first, second, third, compat_ptr(ptr));
case MSGSND: case MSGSND:
return compat_sys_msgsnd(first, second, third, compat_ptr(ptr)); return compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
case MSGRCV: case MSGRCV:
return compat_sys_msgrcv(first, second, fifth, third, return compat_sys_msgrcv(first, second, fifth, third,
version, compat_ptr(ptr)); version, compat_ptr(ptr));
case MSGGET: case MSGGET:
return sys_msgget((key_t) first, second); return sys_msgget((key_t) first, second);
case MSGCTL: case MSGCTL:
return compat_sys_msgctl(first, second, compat_ptr(ptr)); return compat_sys_msgctl(first, second, compat_ptr(ptr));
case SHMAT: case SHMAT:
return compat_sys_shmat(first, second, third, version, return compat_sys_shmat(first, second, third, version,
compat_ptr(ptr)); compat_ptr(ptr));
break; case SHMDT:
case SHMDT:
return sys_shmdt(compat_ptr(ptr)); return sys_shmdt(compat_ptr(ptr));
case SHMGET: case SHMGET:
return sys_shmget(first, (unsigned)second, third); return sys_shmget(first, (unsigned)second, third);
case SHMCTL: case SHMCTL:
return compat_sys_shmctl(first, second, compat_ptr(ptr)); return compat_sys_shmctl(first, second, compat_ptr(ptr));
} }
return -ENOSYS; return -ENOSYS;
......
/*
* linux/arch/x86_64/ia32/mm/mmap.c
*
* flexible mmap layout support
*
* Based on the i386 version which was
*
* Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* Started by Ingo Molnar <mingo@elte.hu>
*/
#include <linux/personality.h>
#include <linux/mm.h>
#include <linux/random.h>
#include <linux/sched.h>
/*
* Top of mmap area (just below the process stack).
*
* Leave an at least ~128 MB hole.
*/
#define MIN_GAP (128*1024*1024)
#define MAX_GAP (TASK_SIZE/6*5)
static inline unsigned long mmap_base(struct mm_struct *mm)
{
unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
unsigned long random_factor = 0;
if (current->flags & PF_RANDOMIZE)
random_factor = get_random_int() % (1024*1024);
if (gap < MIN_GAP)
gap = MIN_GAP;
else if (gap > MAX_GAP)
gap = MAX_GAP;
return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
}
/*
* This function, called very early during the creation of a new
* process VM image, sets up which VM layout function to use:
*/
void ia32_pick_mmap_layout(struct mm_struct *mm)
{
/*
* Fall back to the standard layout if the personality
* bit is set, or if the expected stack growth is unlimited:
*/
if (sysctl_legacy_va_layout ||
(current->personality & ADDR_COMPAT_LAYOUT) ||
current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
mm->mmap_base = TASK_UNMAPPED_BASE;
mm->get_unmapped_area = arch_get_unmapped_area;
mm->unmap_area = arch_unmap_area;
} else {
mm->mmap_base = mmap_base(mm);
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
mm->unmap_area = arch_unmap_area_topdown;
}
}
This diff is collapsed.
This diff is collapsed.
/* Copyright 2002,2003 Andi Kleen, SuSE Labs */
/* vsyscall handling for 32bit processes. Map a stub page into it
on demand because 32bit cannot reach the kernel's fixmaps */
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/stringify.h>
#include <linux/security.h>
#include <asm/proto.h>
#include <asm/tlbflush.h>
#include <asm/ia32_unistd.h>
#include <asm/vsyscall32.h>
extern unsigned char syscall32_syscall[], syscall32_syscall_end[];
extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
extern int sysctl_vsyscall32;
static struct page *syscall32_pages[1];
static int use_sysenter = -1;
struct linux_binprm;
/* Setup a VMA at program startup for the vsyscall page */
int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
{
struct mm_struct *mm = current->mm;
int ret;
down_write(&mm->mmap_sem);
/*
* MAYWRITE to allow gdb to COW and set breakpoints
*
* Make sure the vDSO gets into every core dump.
* Dumping its contents makes post-mortem fully interpretable later
* without matching up the same kernel and hardware config to see
* what PC values meant.
*/
/* Could randomize here */
ret = install_special_mapping(mm, VSYSCALL32_BASE, PAGE_SIZE,
VM_READ|VM_EXEC|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
VM_ALWAYSDUMP,
syscall32_pages);
up_write(&mm->mmap_sem);
return ret;
}
static int __init init_syscall32(void)
{
char *syscall32_page = (void *)get_zeroed_page(GFP_KERNEL);
if (!syscall32_page)
panic("Cannot allocate syscall32 page");
syscall32_pages[0] = virt_to_page(syscall32_page);
if (use_sysenter > 0) {
memcpy(syscall32_page, syscall32_sysenter,
syscall32_sysenter_end - syscall32_sysenter);
} else {
memcpy(syscall32_page, syscall32_syscall,
syscall32_syscall_end - syscall32_syscall);
}
return 0;
}
__initcall(init_syscall32);
/* May not be __init: called during resume */
void syscall32_cpu_init(void)
{
if (use_sysenter < 0)
use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
/* Load these always in case some future AMD CPU supports
SYSENTER from compat mode too. */
checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
wrmsrl(MSR_CSTAR, ia32_cstar_target);
}
/* 32bit VDSOs mapped into user space. */
.section ".init.data","aw"
.globl syscall32_syscall
.globl syscall32_syscall_end
syscall32_syscall:
.incbin "arch/x86/ia32/vsyscall-syscall.so"
syscall32_syscall_end:
.globl syscall32_sysenter
.globl syscall32_sysenter_end
syscall32_sysenter:
.incbin "arch/x86/ia32/vsyscall-sysenter.so"
syscall32_sysenter_end:
/*
* Common code for the sigreturn entry points on the vsyscall page.
* This code uses SYSCALL_ENTER_KERNEL (either syscall or int $0x80)
* to enter the kernel.
* This file is #include'd by vsyscall-*.S to define them after the
* vsyscall entry point. The addresses we get for these entry points
* by doing ".balign 32" must match in both versions of the page.
*/
.code32
.section .text.sigreturn,"ax"
.balign 32
.globl __kernel_sigreturn
.type __kernel_sigreturn,@function
__kernel_sigreturn:
.LSTART_sigreturn:
popl %eax
movl $__NR_ia32_sigreturn, %eax
SYSCALL_ENTER_KERNEL
.LEND_sigreturn:
.size __kernel_sigreturn,.-.LSTART_sigreturn
.section .text.rtsigreturn,"ax"
.balign 32
.globl __kernel_rt_sigreturn
.type __kernel_rt_sigreturn,@function
__kernel_rt_sigreturn:
.LSTART_rt_sigreturn:
movl $__NR_ia32_rt_sigreturn, %eax
SYSCALL_ENTER_KERNEL
.LEND_rt_sigreturn:
.size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
.section .eh_frame,"a",@progbits
.LSTARTFRAMES:
.long .LENDCIES-.LSTARTCIES
.LSTARTCIES:
.long 0 /* CIE ID */
.byte 1 /* Version number */
.string "zRS" /* NUL-terminated augmentation string */
.uleb128 1 /* Code alignment factor */
.sleb128 -4 /* Data alignment factor */
.byte 8 /* Return address register column */
.uleb128 1 /* Augmentation value length */
.byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
.byte 0x0c /* DW_CFA_def_cfa */
.uleb128 4
.uleb128 4
.byte 0x88 /* DW_CFA_offset, column 0x8 */
.uleb128 1
.align 4
.LENDCIES:
.long .LENDFDE2-.LSTARTFDE2 /* Length FDE */
.LSTARTFDE2:
.long .LSTARTFDE2-.LSTARTFRAMES /* CIE pointer */
/* HACK: The dwarf2 unwind routines will subtract 1 from the
return address to get an address in the middle of the
presumed call instruction. Since we didn't get here via
a call, we need to include the nop before the real start
to make up for it. */
.long .LSTART_sigreturn-1-. /* PC-relative start address */
.long .LEND_sigreturn-.LSTART_sigreturn+1
.uleb128 0 /* Augmentation length */
/* What follows are the instructions for the table generation.
We record the locations of each register saved. This is
complicated by the fact that the "CFA" is always assumed to
be the value of the stack pointer in the caller. This means
that we must define the CFA of this body of code to be the
saved value of the stack pointer in the sigcontext. Which
also means that there is no fixed relation to the other
saved registers, which means that we must use DW_CFA_expression
to compute their addresses. It also means that when we
adjust the stack with the popl, we have to do it all over again. */
#define do_cfa_expr(offset) \
.byte 0x0f; /* DW_CFA_def_cfa_expression */ \
.uleb128 1f-0f; /* length */ \
0: .byte 0x74; /* DW_OP_breg4 */ \
.sleb128 offset; /* offset */ \
.byte 0x06; /* DW_OP_deref */ \
1:
#define do_expr(regno, offset) \
.byte 0x10; /* DW_CFA_expression */ \
.uleb128 regno; /* regno */ \
.uleb128 1f-0f; /* length */ \
0: .byte 0x74; /* DW_OP_breg4 */ \
.sleb128 offset; /* offset */ \
1:
do_cfa_expr(IA32_SIGCONTEXT_esp+4)
do_expr(0, IA32_SIGCONTEXT_eax+4)
do_expr(1, IA32_SIGCONTEXT_ecx+4)
do_expr(2, IA32_SIGCONTEXT_edx+4)
do_expr(3, IA32_SIGCONTEXT_ebx+4)
do_expr(5, IA32_SIGCONTEXT_ebp+4)
do_expr(6, IA32_SIGCONTEXT_esi+4)
do_expr(7, IA32_SIGCONTEXT_edi+4)
do_expr(8, IA32_SIGCONTEXT_eip+4)
.byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */
do_cfa_expr(IA32_SIGCONTEXT_esp)
do_expr(0, IA32_SIGCONTEXT_eax)
do_expr(1, IA32_SIGCONTEXT_ecx)
do_expr(2, IA32_SIGCONTEXT_edx)
do_expr(3, IA32_SIGCONTEXT_ebx)
do_expr(5, IA32_SIGCONTEXT_ebp)
do_expr(6, IA32_SIGCONTEXT_esi)
do_expr(7, IA32_SIGCONTEXT_edi)
do_expr(8, IA32_SIGCONTEXT_eip)
.align 4
.LENDFDE2:
.long .LENDFDE3-.LSTARTFDE3 /* Length FDE */
.LSTARTFDE3:
.long .LSTARTFDE3-.LSTARTFRAMES /* CIE pointer */
/* HACK: See above wrt unwind library assumptions. */
.long .LSTART_rt_sigreturn-1-. /* PC-relative start address */
.long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
.uleb128 0 /* Augmentation */
/* What follows are the instructions for the table generation.
We record the locations of each register saved. This is
slightly less complicated than the above, since we don't
modify the stack pointer in the process. */
do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp)
do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax)
do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx)
do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx)
do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx)
do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp)
do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi)
do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi)
do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip)
.align 4
.LENDFDE3:
#include "../../x86/kernel/vsyscall-note_32.S"
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
obj-$(CONFIG_ACPI) += boot.o obj-$(CONFIG_ACPI) += boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep_$(BITS).o wakeup_$(BITS).o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
ifneq ($(CONFIG_ACPI_PROCESSOR),) ifneq ($(CONFIG_ACPI_PROCESSOR),)
obj-y += cstate.o processor.o obj-y += cstate.o processor.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment