Messages in this thread Patch in this message |  | | | Date | Fri, 23 Jan 1998 23:54:17 +0100 | | From | Pavel Machek <> | | Subject | Volatile magic |
| |
Hi!
2.0.33 kernel broke when compiled with gcc 2.8.0. Everyone saw that. Then, simple fix for single procedure appeared, and now it seems like everything is right.
*IT PROBABLY IS NOT*
There are more pieces like that *(type *)& in sys_iopl(). I did a bit of grep for such constructs, and it seems to me like pretty much code may be broken. [I probably included too many situations. I just can not judge that].
Patch to scheduler is attached, it kills comment duplication, and adds one volatile, which is IMO needed.
Please note that if you want to know if long is 64bit, #if ((~0UL) == 0xffffffff) is not good way - what about crosscompiling? I already posted one patch to solve this, it was later superceeded by mj's patch. --- clean/kernel/sched.c Wed Jan 14 21:46:09 1998 +++ linux/kernel/sched.c Fri Jan 23 20:03:15 1998 @@ -435,11 +435,6 @@ prev->has_cpu = 0; #endif -/* - * Note! there may appear new tasks on the run-queue during this, as - * interrupts are enabled. However, they will be put on front of the - * list, so our list starting at "p" is essentially fixed. - */ /* this is the scheduler proper: */ { int c = -1000; @@ -761,10 +758,7 @@ struct timer_struct timer_table[32]; /* - * Hmm.. Changed this, as the GNU make sources (load.c) seems to - * imply that avenrun[] is the standard name for this kind of thing. - * Nothing else seems to be standardized: the fractional size etc - * all seem to differ on different machines. + * This is famous 'load average' */ unsigned long avenrun[3] = { 0,0,0 }; @@ -1094,16 +1088,16 @@ static void timer_bh(void) { update_times(); run_old_timers(); run_timer_list(); } void do_timer(struct pt_regs * regs) { - (*(unsigned long *)&jiffies)++; + (*(unsigned long * volatile)&jiffies)++; lost_ticks++; mark_bh(TIMER_BH); if (!user_mode(regs)) lost_ticks_system++; if (tq_timer) @@ -1480,6 +1476,7 @@ printk(stat_nam[p->state]); else printk(" "); +/* This is broken! What about crosscompiling?! */ #if ((~0UL) == 0xffffffff) if (p == current) printk(" current ");
./fs/binfmt_elf.c: *(struct pt_regs *)&prstatus.pr_reg = *regs; ./fs/ufs/ufs_inode.c: inode->i_rdev = (kdev_t)SWAB64(*(__u64*)&ufsip->ui_db); ./net/core/filter.c: A = ntohl(*(long*)&data[k]); (more) ./net/ipv4/icmp.c: mask = *(u32*)&icmph[1]; ./net/ipv4/ip_forward.c: unsigned h = ((*(u8*)&rt->key.dst)^(*(u8*)&rt->key.src))&NETDEV_FASTROUTE_HMASK; ./net/ipv4/fib_hash.c: return *(fn_hash_idx_t*)&h; ./net/wanrouter/wanmain.c: *((unsigned short*)&skb->data[4]) = htons(skb->protocol); ./net/wanrouter/wanmain.c: ethertype = *((unsigned short*)&skb->data[cnt+4]); ./drivers/net/zlib.c: if (*(ush*)&buf != 0) return buf; (more) ./drivers/net/de4x5.c: if ((*(s32 *)&buf[0] == -1) && (*(s16 *)&buf[4] == -1)) { (more occurences in de4x5.c...) ./drivers/net/seeq8005.c: printk("%02x ",*(p++)&0xff); ./drivers/net/strip.c: *(MetricomAddress*)&strip_info->true_dev_addr = zero_address; ./drivers/net/strip.c: *(MetricomAddress*)&dev->broadcast = broadcast_address; ./drivers/net/sdladrv.c: *(short*)&data[0x0D] = 128; /* default X.25 data size */ ./drivers/net/sdladrv.c: *(short*)&data[0x0F] = 128; /* maximum X.25 data size */ ./drivers/block/ide-cd.c: *(int *)&devinfo->speed = CDROM_CONFIG_FLAGS (drive)->max_speed; ./drivers/block/ide-cd.c: *(int *)&devinfo->capacity = nslots; ./drivers/block/amiflop.c: *(ulong *)&hdr.labels[0], *(ulong *)&hdr.labels[4], ./drivers/block/amiflop.c: *(ulong *)&hdr.labels[8], *(ulong *)&hdr.labels[12], ./drivers/char/rocket.c: sOutDW(ChP->IndexAddr,*((DWord_t *)&R[0])); (more occurences in rocket.c) ./drivers/scsi/ultrastor.c: *(char *)&config_1 = inb(CONFIG(config.port_address + 0)); ./drivers/scsi/ultrastor.c: *(char *)&config_2 = inb(CONFIG(config.port_address + 1)); ./drivers/scsi/u14-34f.c: *(char *)&config_1 = inb(port_base + REG_CONFIG1); ./drivers/scsi/u14-34f.c: *(char *)&config_2 = inb(port_base + REG_CONFIG2); ./drivers/scsi/advansys.c:#define LO_BYTE(x) (*((__u8 *)&x)) ./drivers/scsi/advansys.c:#define LO_WORD(x) (*((__u16 *)&x)) ./drivers/scsi/gdth.c: cmdp->u.cache.BlockNo = ntohl(*(ulong*)&scp->cmnd[2]); (...) ./drivers/sound/lowlevel/awe_wave.c: drum_flags = *(unsigned int*)&event[4]; ./drivers/fc4/fc.c: FCD(("Dest WWN %08x%08x\n", *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo)) ./drivers/fc4/fc.c: *(u32 *)&plogi[1].node_wwn, plogi[1].node_wwn.lo, ./drivers/fc4/fc.c: *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo); ./drivers/fc4/soc.c: *(u32 *)&s->port[0].fc.wwn_nport, s->port[0].fc.wwn_nport.lo, ./drivers/fc4/soc.c: *(u32 *)&s->port[0].fc.wwn_nport, s->port[0].fc.wwn_nport.lo, ./drivers/fc4/soc.c: *(u32 *)&s->port[1].fc.wwn_nport, s->port[1].fc.wwn_nport.lo)) ./arch/i386/math-emu/reg_convert.c: *(long long *)&(x->sigl) = *(const long long *)&(a->sigl); ./arch/i386/kernel/vm86.c:#define IP(regs) (*(unsigned short *)&((regs)->eip)) ./arch/i386/kernel/vm86.c:#define SP(regs) (*(unsigned short *)&((regs)->esp)) ./arch/i386/kernel/vm86.c:#define VFLAGS (*(unsigned short *)&(current->tss.v86flags)) ./arch/i386/kernel/io_apic.c: *(((int *)&entry)+0) = io_apic_read(0x10+irq*2); (*many* occurences in io_apic.c) ./arch/sparc/kernel/irq.c: if (*((unsigned char *)&global_irq_lock)) ./arch/sparc/kernel/irq.c: } while (*((unsigned char *)&global_irq_lock)); ./arch/sparc/kernel/irq.c: while (*((unsigned char *)&global_irq_lock)) { (hey, this is almost certainly broken on sparc - leading to ..?) ./arch/sparc/kernel/setup.c: *((unsigned char *)&global_irq_lock) = 0; ./arch/sparc/kernel/setup.c: *((unsigned char *)&global_bh_lock) = 0; ./arch/sparc/lib/debuglocks.c: (*((unsigned short *)&rw->lock))++; (more) ./arch/sparc/ap1000/apmmu.c: *(((unsigned long long *)MC_MMU_TLB4K) + ((vaddr>>12)&0xFF)) = 0; ./arch/mips/kernel/irixelf.c: *(struct pt_regs *)&prstatus.pr_reg = *regs; ./arch/ppc/mm/fault.c: *((unsigned long *)(&p)), *((long *)&p+1), ./arch/ppc/kernel/irq.c: if (*((unsigned char *)&global_irq_lock)) ./arch/ppc/kernel/irq.c: } while (*((unsigned char *)&global_irq_lock)); ./arch/sparc64/kernel/unaligned.c: first = *(u64 *)&f->regs[freg]; ./arch/sparc64/kernel/unaligned.c: second = *(u64 *)&f->regs[freg+2]; ./arch/sparc64/kernel/unaligned.c: value = *(u64 *)&f->regs[freg];
-- I'm really pavel@atrey.karlin.mff.cuni.cz. Pavel Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).
|  |