diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/config.in | 31 | ||||
-rw-r--r-- | arch/i386/defconfig | 6 | ||||
-rw-r--r-- | arch/i386/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/i386/kernel/acpi.c | 25 | ||||
-rw-r--r-- | arch/i386/kernel/i8259.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/irq.c | 50 | ||||
-rw-r--r-- | arch/i386/kernel/microcode.c | 97 | ||||
-rw-r--r-- | arch/i386/kernel/pci-pc.c | 43 | ||||
-rw-r--r-- | arch/i386/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/signal.c | 10 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 1 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 3 |
13 files changed, 169 insertions, 106 deletions
diff --git a/arch/i386/config.in b/arch/i386/config.in index e074ea81d..1d5c0d5f7 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -49,8 +49,8 @@ if [ "$CONFIG_MK7" = "y" ]; then define_bool CONFIG_X86_USE_3DNOW y fi -if [ "$CONFIG_PROC_FS" = "y" ]; then - tristate '/proc/driver/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE +if [ "$CONFIG_DEVFS_FS" = "y" ]; then + tristate '/dev/cpu/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE fi choice 'High Memory Support' \ @@ -139,30 +139,31 @@ tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC -source drivers/parport/Config.in +bool 'Power Management support' CONFIG_PM -bool 'ACPI support' CONFIG_ACPI +dep_bool ' ACPI support' CONFIG_ACPI $CONFIG_PM if [ "$CONFIG_ACPI" != "n" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP + bool ' Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP fi fi -tristate 'Advanced Power Management BIOS support' CONFIG_APM +dep_tristate ' Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM if [ "$CONFIG_APM" != "n" ]; then - bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND - bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE - bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE - bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK - bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND - bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE - bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT - bool ' Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS - bool ' Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF + bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND + bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE + bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE + bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK + bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE + bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT + bool ' Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS + bool ' Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF fi endmenu +source drivers/parport/Config.in source drivers/pnp/Config.in diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 34b453c2c..f2517c27d 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -27,7 +27,6 @@ CONFIG_X86_POPAD_OK=y CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_PGE=y -# CONFIG_MICROCODE is not set CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set @@ -74,9 +73,10 @@ CONFIG_KCORE_ELF=y CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y -# CONFIG_PARPORT is not set +CONFIG_PM=y CONFIG_ACPI=y # CONFIG_APM is not set +# CONFIG_PARPORT is not set # # Plug and Play configuration @@ -96,6 +96,7 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_HD_IDE is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -264,6 +265,7 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set CONFIG_DUMMY=m +# CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_NET_SB1000 is not set diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 3b7bb1258..6671bb35b 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -40,7 +40,6 @@ else endif endif -ifeq ($(CONFIG_PROC_FS),y) ifeq ($(CONFIG_MICROCODE),y) OX_OBJS += microcode.o else @@ -48,7 +47,6 @@ else MX_OBJS += microcode.o endif endif -endif ifeq ($(CONFIG_ACPI),y) O_OBJS += acpi.o diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c index 6228805db..b19097420 100644 --- a/arch/i386/kernel/acpi.c +++ b/arch/i386/kernel/acpi.c @@ -977,11 +977,9 @@ static void acpi_enter_sx(acpi_sstate_t state) typa = ((typa << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK); typb = ((typb << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK); - if (state != ACPI_S0) { - acpi_sleep_start = get_cmos_time(); - acpi_enter_dx(ACPI_D3); - acpi_sleep_state = state; - } + acpi_sleep_start = get_cmos_time(); + acpi_enter_dx(ACPI_D3); + acpi_sleep_state = state; // clear wake status acpi_write_pm1_status(acpi_facp, ACPI_WAK); @@ -996,17 +994,11 @@ static void acpi_enter_sx(acpi_sstate_t state) outw(value | typb | ACPI_SLP_EN, acpi_facp->pm1b_cnt); } - if (state == ACPI_S0) { - acpi_sleep_state = state; - acpi_enter_dx(ACPI_D0); - acpi_sleep_start = 0; - } - else if (state == ACPI_S1) { - // wait until S1 is entered - while (!(acpi_read_pm1_status(acpi_facp) & ACPI_WAK)) ; - // finished sleeping, update system time - acpi_update_clock(); - } + // wait until S1 is entered + while (!(acpi_read_pm1_status(acpi_facp) & ACPI_WAK)) ; + // finished sleeping, update system time + acpi_update_clock(); + acpi_enter_dx(ACPI_D0); } } @@ -1292,7 +1284,6 @@ static int acpi_do_sleep(ctl_table *ctl, { #ifdef CONFIG_ACPI_S1_SLEEP acpi_enter_sx(ACPI_S1); - acpi_enter_sx(ACPI_S0); #endif } file->f_pos += *len; diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index ec33f2269..b14f8caf3 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -131,7 +131,7 @@ static spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; static void end_8259A_irq (unsigned int irq) { - if (!(irq_desc[irq].status & IRQ_DISABLED)) + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_8259A_irq(irq); } diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 129a587f0..02669540f 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -18,6 +18,7 @@ #include <linux/mm.h> #include <linux/irq.h> +#include <linux/interrupt.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/sched.h> @@ -1160,7 +1161,7 @@ static void end_level_ioapic_irq (unsigned int i) static void mask_and_ack_level_ioapic_irq (unsigned int i) { /* nothing */ } -static void set_ioapic_affinity (unsigned int irq, unsigned int mask) +static void set_ioapic_affinity (unsigned int irq, unsigned long mask) { unsigned long flags; /* diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 7054249e6..4163626f4 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -32,7 +32,6 @@ #include <linux/kernel_stat.h> #include <linux/irq.h> #include <linux/proc_fs.h> -#include <linux/irq.h> #include <asm/io.h> #include <asm/smp.h> @@ -184,24 +183,43 @@ int get_irq_list(char *buf) unsigned char global_irq_holder = NO_PROC_ID; unsigned volatile int global_irq_lock; +extern void show_stack(unsigned long* esp); + static void show(char * str) { int i; - unsigned long *stack; int cpu = smp_processor_id(); printk("\n%s, CPU %d:\n", str, cpu); - printk("irq: %d [%d %d]\n", - irqs_running(), local_irq_count(0), local_irq_count(1)); - printk("bh: %d [%d %d]\n", - spin_is_locked(&global_bh_lock) ? 1 : 0, local_bh_count(0), local_bh_count(1)); - stack = (unsigned long *) &stack; - for (i = 40; i ; i--) { - unsigned long x = *++stack; - if (x > (unsigned long) &get_option && x < (unsigned long) &vsprintf) { - printk("<[%08lx]> ", x); + printk("irq: %d [",irqs_running()); + for(i=0;i < smp_num_cpus;i++) + printk(" %d",local_irq_count(i)); + printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0); + for(i=0;i < smp_num_cpus;i++) + printk(" %d",local_bh_count(i)); + + printk(" ]\nStack dumps:"); + for(i=0;i< smp_num_cpus;i++) { + unsigned long esp; + if(i==cpu) + continue; + printk("\nCPU %d:",i); + esp = init_tss[i].esp0; + if(esp==NULL) { + /* tss->esp0 is set to NULL in cpu_init(), + * it's initialized when the cpu returns to user + * space. -- manfreds + */ + printk(" <unknown> "); + continue; } - } + esp &= ~(THREAD_SIZE-1); + esp += sizeof(struct task_struct); + show_stack((void*)esp); + } + printk("\nCPU %d:",cpu); + show_stack(NULL); + printk("\n"); } #define MAXCOUNT 100000000 @@ -874,7 +892,7 @@ static struct proc_dir_entry * root_irq_dir; static struct proc_dir_entry * irq_dir [NR_IRQS]; static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; -unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff}; +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; #define HEX_DIGITS 8 @@ -883,7 +901,7 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, { if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08x\n", irq_affinity[(int)data]); + return sprintf (page, "%08lx\n", irq_affinity[(long)data]); } static unsigned int parse_hex_value (const char *buffer, @@ -926,7 +944,7 @@ out: static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - int irq = (int) data, full_count = count, err; + int irq = (long) data, full_count = count, err; unsigned long new_value; if (!irq_desc[irq].handler->set_affinity) @@ -993,7 +1011,7 @@ static void register_irq_proc (unsigned int irq) entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]); entry->nlink = 1; - entry->data = (void *)irq; + entry->data = (void *)(long)irq; entry->read_proc = irq_affinity_read_proc; entry->write_proc = irq_affinity_write_proc; diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 84490b40b..f858d7da9 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -23,20 +23,23 @@ * 1.02 21 February 2000, Tigran Aivazian <tigran@sco.com> * Added 'device trimming' support. open(O_WRONLY) zeroes * and frees the saved copy of applied microcode. + * 1.03 29 February 2000, Tigran Aivazian <tigran@sco.com> + * Made to use devfs (/dev/cpu/microcode) + cleanups. */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/module.h> #include <linux/vmalloc.h> #include <linux/smp_lock.h> -#include <linux/proc_fs.h> +#include <linux/devfs_fs_kernel.h> #include <asm/msr.h> #include <asm/uaccess.h> #include <asm/processor.h> -#define MICROCODE_VERSION "1.02" +#define MICROCODE_VERSION "1.03" MODULE_DESCRIPTION("CPU (P6) microcode update driver"); MODULE_AUTHOR("Tigran Aivazian <tigran@ocston.org>"); @@ -60,9 +63,10 @@ static void do_update_one(void *); static unsigned long microcode_status = 0; /* the actual array of microcode blocks, each 2048 bytes */ -static struct microcode * microcode = NULL; +static struct microcode *microcode = NULL; static unsigned int microcode_num = 0; static char *mc_applied = NULL; /* holds an array of applied microcode blocks */ +static unsigned int mc_fsize; /* used often, so compute once at microcode_init() */ static struct file_operations microcode_fops = { read: microcode_read, @@ -71,23 +75,25 @@ static struct file_operations microcode_fops = { release: microcode_release, }; -static struct proc_dir_entry *proc_microcode; +static devfs_handle_t devfs_handle; static int __init microcode_init(void) { - proc_microcode = create_proc_entry("microcode", S_IWUSR|S_IRUSR, proc_root_driver); - if (!proc_microcode) { - printk(KERN_ERR "microcode: can't create /proc/driver/microcode\n"); - return -ENOMEM; - } - proc_microcode->proc_fops = µcode_fops; + devfs_handle = devfs_register(NULL, "cpu/microcode", 0, DEVFS_FL_DEFAULT, 0, 0, + S_IFREG | S_IRUSR | S_IWUSR, 0, 0, µcode_fops, NULL); + if (!devfs_handle) { + printk(KERN_ERR "microcode: can't create /dev/cpu/microcode\n"); + return -ENOMEM; + } + /* XXX assume no hotplug CPUs so smp_num_cpus does not change */ + mc_fsize = smp_num_cpus * sizeof(struct microcode); printk(KERN_INFO "P6 Microcode Update Driver v%s registered\n", MICROCODE_VERSION); return 0; } static void __exit microcode_exit(void) { - remove_proc_entry("microcode", proc_root_driver); + devfs_unregister(devfs_handle); if (mc_applied) kfree(mc_applied); printk(KERN_INFO "P6 Microcode Update Driver v%s unregistered\n", MICROCODE_VERSION); @@ -108,25 +114,21 @@ static int microcode_open(struct inode *inode, struct file *file) if (test_and_set_bit(MICROCODE_IS_OPEN, µcode_status)) return -EBUSY; - if ((file->f_flags & O_ACCMODE) == O_WRONLY) { - proc_microcode->size = 0; - if (mc_applied) { - memset(mc_applied, 0, smp_num_cpus * sizeof(struct microcode)); - kfree(mc_applied); - mc_applied = NULL; - } + if ((file->f_flags & O_ACCMODE) == O_WRONLY && mc_applied) { + devfs_set_file_size(devfs_handle, 0); + memset(mc_applied, 0, mc_fsize); + kfree(mc_applied); + mc_applied = NULL; } MOD_INC_USE_COUNT; - return 0; } static int microcode_release(struct inode *inode, struct file *file) { - MOD_DEC_USE_COUNT; - clear_bit(MICROCODE_IS_OPEN, µcode_status); + MOD_DEC_USE_COUNT; return 0; } @@ -156,19 +158,17 @@ static int do_microcode_update(void) memcpy(m, µcode[update_req[i].slot], sizeof(struct microcode)); } } - return error ? -EIO : 0; + return error; } static void do_update_one(void *arg) { - struct update_req *req; - struct cpuinfo_x86 * c; + int cpu_num = smp_processor_id(); + struct cpuinfo_x86 *c = cpu_data + cpu_num; + struct update_req *req = (struct update_req *)arg + cpu_num; unsigned int pf = 0, val[2], rev, sig; - int i, cpu_num; + int i; - cpu_num = smp_processor_id(); - c = cpu_data + cpu_num; - req = (struct update_req *)arg + cpu_num; req->err = 1; /* be pessimistic */ if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6) @@ -210,8 +210,8 @@ static void do_update_one(void *arg) req->err = 0; req->slot = i; - printk(KERN_ERR "microcode: CPU%d microcode updated " - "from revision %d to %d, date=%08x\n", + printk(KERN_ERR "microcode: CPU%d updated from revision " + "%d to %d, date=%08x\n", cpu_num, rev, val[1], m->date); } break; @@ -220,12 +220,10 @@ static void do_update_one(void *arg) static ssize_t microcode_read(struct file *file, char *buf, size_t len, loff_t *ppos) { - size_t fsize = smp_num_cpus * sizeof(struct microcode); - - if (!proc_microcode->size || *ppos >= fsize) - return 0; /* EOF */ - if (*ppos + len > fsize) - len = fsize - *ppos; + if (*ppos >= mc_fsize) + return 0; + if (*ppos + len > mc_fsize) + len = mc_fsize - *ppos; if (copy_to_user(buf, mc_applied + *ppos, len)) return -EFAULT; *ppos += len; @@ -242,33 +240,34 @@ static ssize_t microcode_write(struct file *file, const char *buf, size_t len, l return -EINVAL; } if (!mc_applied) { - int size = smp_num_cpus * sizeof(struct microcode); - mc_applied = kmalloc(size, GFP_KERNEL); + mc_applied = kmalloc(mc_fsize, GFP_KERNEL); if (!mc_applied) { - printk(KERN_ERR "microcode: can't allocate memory for saved microcode\n"); + printk(KERN_ERR "microcode: out of memory for saved microcode\n"); return -ENOMEM; } - memset(mc_applied, 0, size); + memset(mc_applied, 0, mc_fsize); } lock_kernel(); microcode_num = len/sizeof(struct microcode); microcode = vmalloc(len); if (!microcode) { - unlock_kernel(); - return -ENOMEM; + ret = -ENOMEM; + goto out_unlock; } if (copy_from_user(microcode, buf, len)) { - vfree(microcode); - unlock_kernel(); - return -EFAULT; + ret = -EFAULT; + goto out_vfree; } - ret = do_microcode_update(); - if (!ret) { - proc_microcode->size = smp_num_cpus * sizeof(struct microcode); - ret = (ssize_t)len; + if(do_microcode_update()) { + ret = -EIO; + goto out_vfree; } + devfs_set_file_size(devfs_handle, mc_fsize); + ret = (ssize_t)len; +out_vfree: vfree(microcode); +out_unlock: unlock_kernel(); return ret; } diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c index d5b2b0062..a76c92d25 100644 --- a/arch/i386/kernel/pci-pc.c +++ b/arch/i386/kernel/pci-pc.c @@ -1044,6 +1044,45 @@ static void __init pcibios_irq_peer_trick(struct irq_routing_table *rt) printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i); } +static void set_level_irq(unsigned irq) +{ + unsigned char mask = 1 << (irq & 7); + unsigned int port = 0x4d0 + (irq >> 3); + unsigned char val = inb(port); + + if (val & mask) { + printk("PCI irq %d was level\n", irq); + return; + } + printk("PCI irq %d was edge, turning into level-triggered\n", irq); + outb(val | mask, port); +} + +static int ali_set_irq(struct pci_dev *router, unsigned pirq, unsigned irq) +{ + if (irq < 15) { + static unsigned char irqmap[16] = { + 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 + }; + unsigned char val = irqmap[irq]; + if (val && pirq < 8) { + u8 byte; + unsigned offset = 0x48 + (pirq >> 1); + unsigned shift = (pirq & 1) << 2; + pci_read_config_byte(router, offset, &byte); + printk("ALI: old %04x=%02x\n", offset, byte); + byte &= ~(0xf << shift); + byte |= val << shift; + printk("ALI: new %04x=%02x\n", offset, byte); + pci_write_config_byte(router, offset, byte); + set_level_irq(irq); + return irq; + } + } + return 0; +} + + /* * In case BIOS forgets to tell us about IRQ, we try to look it up in the routing * table, but unfortunately we have to know the interrupt router chip. @@ -1135,6 +1174,10 @@ static char *pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *r DBG(" -> [PIIX] sink\n"); break; case ID(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533): + newirq = ali_set_irq(router, pirq-1, newirq); + if (newirq) + msg = "ALI"; + break; default: DBG(" -> unknown router %04x/%04x\n", rt->rtr_vendor, rt->rtr_device); if (newirq && mask == (1 << newirq)) { diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 19f7022a4..a043b4cfe 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -693,7 +693,6 @@ asmlinkage int sys_execve(struct pt_regs regs) int error; char * filename; - lock_kernel(); filename = getname((char *) regs.ebx); error = PTR_ERR(filename); if (IS_ERR(filename)) @@ -703,7 +702,6 @@ asmlinkage int sys_execve(struct pt_regs regs) current->flags &= ~PF_DTRACE; putname(filename); out: - unlock_kernel(); return error; } diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index a973746b9..d9af88d82 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -419,13 +419,19 @@ static void setup_frame(int sig, struct k_sigaction *ka, ? current->exec_domain->signal_invmap[sig] : sig), &frame->sig); + if (err) + goto give_sigsegv; err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]); + if (err) + goto give_sigsegv; if (_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask)); } + if (err) + goto give_sigsegv; /* Set up to return from userspace. If provided, use a stub already in userspace. */ @@ -486,6 +492,8 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->uc, &frame->puc); err |= __copy_to_user(&frame->info, info, sizeof(*info)); + if (err) + goto give_sigsegv; /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); @@ -497,6 +505,8 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + if (err) + goto give_sigsegv; /* Set up to return from userspace. If provided, use a stub already in userspace. */ diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 7400b628b..3a7004970 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/spinlock.h> +#include <linux/interrupt.h> #ifdef CONFIG_MCA #include <linux/mca.h> diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 8b1324520..b9e535a71 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -631,13 +631,14 @@ void free_initmem(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { + if (start < end) + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { ClearPageReserved(mem_map + MAP_NR(start)); set_page_count(mem_map+MAP_NR(start), 1); free_page(start); totalram_pages++; } - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif |