* [PATCH] tmscsim: Fix big left-shifts of unsigned char @ 2009-06-18 12:14 Roel Kluin 2009-06-18 13:03 ` James Bottomley 2009-06-18 14:40 ` Roel Kluin 0 siblings, 2 replies; 8+ messages in thread From: Roel Kluin @ 2009-06-18 12:14 UTC (permalink / raw) To: garloff, linux-scsi, Andrew Morton Shifting of u8 causes promotion to signed 'int' Signed-off-by: Roel Kluin <roel.kluin@gmail.com> --- I believe this was not intentionally? see http://osdir.com/ml/git/2009-06/msg01347.html diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 9a42734..09a3c12 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -894,7 +894,7 @@ din_1: if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n"); //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); dc390_laststatus &= ~0xff000000; - dc390_laststatus |= bval << 24; + dc390_laststatus |= (unsigned)bval << 24; DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval)); ResidCnt = (((u32) DC390_read8 (CtcReg_High) << 16) | ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] tmscsim: Fix big left-shifts of unsigned char 2009-06-18 12:14 [PATCH] tmscsim: Fix big left-shifts of unsigned char Roel Kluin @ 2009-06-18 13:03 ` James Bottomley 2009-06-18 13:16 ` Matthew Wilcox 2009-06-18 14:40 ` Roel Kluin 1 sibling, 1 reply; 8+ messages in thread From: James Bottomley @ 2009-06-18 13:03 UTC (permalink / raw) To: Roel Kluin; +Cc: garloff, linux-scsi, Andrew Morton On Thu, 2009-06-18 at 14:14 +0200, Roel Kluin wrote: > - dc390_laststatus |= bval << 24; > + dc390_laststatus |= (unsigned)bval << 24; bval is already u8, thus unsigned, so the cast is a nop. James ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] tmscsim: Fix big left-shifts of unsigned char 2009-06-18 13:03 ` James Bottomley @ 2009-06-18 13:16 ` Matthew Wilcox 2009-06-18 13:27 ` Boaz Harrosh 0 siblings, 1 reply; 8+ messages in thread From: Matthew Wilcox @ 2009-06-18 13:16 UTC (permalink / raw) To: James Bottomley; +Cc: Roel Kluin, garloff, linux-scsi, Andrew Morton On Thu, Jun 18, 2009 at 09:03:24AM -0400, James Bottomley wrote: > On Thu, 2009-06-18 at 14:14 +0200, Roel Kluin wrote: > > - dc390_laststatus |= bval << 24; > > + dc390_laststatus |= (unsigned)bval << 24; > > bval is already u8, thus unsigned, so the cast is a nop. Err ... I believe you're pedantically uncorrect, though right in practice. The (unsigned) cast is short for (unsigned int) -- it doesn't mean 'cast to an unsigned version of the type that it already has'. Now, in practice what happens is: 6.5.7: The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. so bval would be promoted from an unsigned char to a signed int, and then shifted left by 24 bits, resulting in a potentially negative number. But dc390_laststatus is an u32, so the |= converts this negative number into a positive one, leading to the same answer that would have been carried out in unsigned arithmetic. So you're right (the cast isn't needed) for the wrong reason ;-) -- Matthew Wilcox Intel Open Source Technology Centre "Bill, look, we understand that you're interested in selling us this operating system, but compare it to ours. We can't possibly take such a retrograde step." ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] tmscsim: Fix big left-shifts of unsigned char 2009-06-18 13:16 ` Matthew Wilcox @ 2009-06-18 13:27 ` Boaz Harrosh 2009-06-18 13:36 ` Matthew Wilcox 0 siblings, 1 reply; 8+ messages in thread From: Boaz Harrosh @ 2009-06-18 13:27 UTC (permalink / raw) To: Matthew Wilcox Cc: James Bottomley, Roel Kluin, garloff, linux-scsi, Andrew Morton On 06/18/2009 04:16 PM, Matthew Wilcox wrote: > On Thu, Jun 18, 2009 at 09:03:24AM -0400, James Bottomley wrote: >> On Thu, 2009-06-18 at 14:14 +0200, Roel Kluin wrote: >>> - dc390_laststatus |= bval << 24; >>> + dc390_laststatus |= (unsigned)bval << 24; >> bval is already u8, thus unsigned, so the cast is a nop. > > Err ... I believe you're pedantically uncorrect, though right in practice. > > The (unsigned) cast is short for (unsigned int) -- it doesn't mean > 'cast to an unsigned version of the type that it already has'. > > Now, in practice what happens is: > > 6.5.7: > > The integer promotions are performed on each of the operands. The type > of the result is that of the promoted left operand. > Note the left operand, not the lvalue. > so bval would be promoted from an unsigned char to a signed int, and > then shifted left by 24 bits, resulting in a potentially negative number. > But dc390_laststatus is an u32, so the |= converts this negative number > into a positive one, leading to the same answer that would have been > carried out in unsigned arithmetic. > It could get dangerous in 64bit integer machines if the negative number gets truncated to 32bit while converted. So if the bval was > 127 and we get a 64bit signed negative number what will happen then? > So you're right (the cast isn't needed) for the wrong reason ;-) > Are you sure. It looks we need the cast Boaz ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] tmscsim: Fix big left-shifts of unsigned char 2009-06-18 13:27 ` Boaz Harrosh @ 2009-06-18 13:36 ` Matthew Wilcox 2009-06-18 14:45 ` James Bottomley 0 siblings, 1 reply; 8+ messages in thread From: Matthew Wilcox @ 2009-06-18 13:36 UTC (permalink / raw) To: Boaz Harrosh Cc: James Bottomley, Roel Kluin, garloff, linux-scsi, Andrew Morton On Thu, Jun 18, 2009 at 04:27:37PM +0300, Boaz Harrosh wrote: > > The (unsigned) cast is short for (unsigned int) -- it doesn't mean > > 'cast to an unsigned version of the type that it already has'. > > > > Now, in practice what happens is: > > > > 6.5.7: > > > > The integer promotions are performed on each of the operands. The type > > of the result is that of the promoted left operand. > > > > Note the left operand, not the lvalue. Yes, but the *promoted* left operand. Look at 6.3.1 again, and you'll see an unsigned char is promoted to int. > > so bval would be promoted from an unsigned char to a signed int, and > > then shifted left by 24 bits, resulting in a potentially negative number. > > But dc390_laststatus is an u32, so the |= converts this negative number > > into a positive one, leading to the same answer that would have been > > carried out in unsigned arithmetic. > > It could get dangerous in 64bit integer machines if the negative number > gets truncated to 32bit while converted. So if the bval was > 127 > and we get a 64bit signed negative number what will happen then? For one, Linux doesn't support an ILP64 model. I32LP64 and ILP32 are the only two models supported. If we assume support for I64, then the value 255 gets promoted to be a 64-bit signed integer, and then shifted left by 24 bits. The sign bit is way up at 63, so it doesn't become negative. Then it'll be ORed with the u32. The u32 gets promoted to an s64 for the operation, the OR is done in 64-bit arithmetic, then truncated back down to u32 for the assignment. Again, I don't see the problem. > > So you're right (the cast isn't needed) for the wrong reason ;-) > > Are you sure. It looks we need the cast I'm going to need to see a better argument than that before I'm convinced ;-) -- Matthew Wilcox Intel Open Source Technology Centre "Bill, look, we understand that you're interested in selling us this operating system, but compare it to ours. We can't possibly take such a retrograde step." ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] tmscsim: Fix big left-shifts of unsigned char 2009-06-18 13:36 ` Matthew Wilcox @ 2009-06-18 14:45 ` James Bottomley 2009-06-18 14:55 ` Matthew Wilcox 0 siblings, 1 reply; 8+ messages in thread From: James Bottomley @ 2009-06-18 14:45 UTC (permalink / raw) To: Matthew Wilcox Cc: Boaz Harrosh, Roel Kluin, garloff, linux-scsi, Andrew Morton On Thu, 2009-06-18 at 07:36 -0600, Matthew Wilcox wrote: > For one, Linux doesn't support an ILP64 model. I32LP64 and ILP32 are > the only two models supported. Heh ... embedded is easy to forget. I believe, for reasons I have had explained at length but understandably don't wish to go through again, Sony has an IP32L64 model for the PS3 which causes all sorts of erm problems. James ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] tmscsim: Fix big left-shifts of unsigned char 2009-06-18 14:45 ` James Bottomley @ 2009-06-18 14:55 ` Matthew Wilcox 0 siblings, 0 replies; 8+ messages in thread From: Matthew Wilcox @ 2009-06-18 14:55 UTC (permalink / raw) To: James Bottomley Cc: Boaz Harrosh, Roel Kluin, garloff, linux-scsi, Andrew Morton On Thu, Jun 18, 2009 at 02:45:42PM +0000, James Bottomley wrote: > On Thu, 2009-06-18 at 07:36 -0600, Matthew Wilcox wrote: > > For one, Linux doesn't support an ILP64 model. I32LP64 and ILP32 are > > the only two models supported. > > Heh ... embedded is easy to forget. I believe, for reasons I have had > explained at length but understandably don't wish to go through again, > Sony has an IP32L64 model for the PS3 which causes all sorts of erm > problems. And they compile the kernel in that mode? I'd not heard of that before. Not that it makes any difference to this case ... but I suppose we mostly assume that a pointer fits in an unsigned long, and rarely assume vice-versa. I know Windows supports an IL32P64 mode, and IRIX had an ILP64 mode, but this is the first I've heard of an IP32L64 mode. There's no limits to the craziness some people will do, I suppose. -- Matthew Wilcox Intel Open Source Technology Centre "Bill, look, we understand that you're interested in selling us this operating system, but compare it to ours. We can't possibly take such a retrograde step." ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] tmscsim: Fix big left-shifts of unsigned char 2009-06-18 12:14 [PATCH] tmscsim: Fix big left-shifts of unsigned char Roel Kluin 2009-06-18 13:03 ` James Bottomley @ 2009-06-18 14:40 ` Roel Kluin 1 sibling, 0 replies; 8+ messages in thread From: Roel Kluin @ 2009-06-18 14:40 UTC (permalink / raw) To: Roel Kluin; +Cc: garloff, linux-scsi, Andrew Morton Op 18-06-09 14:14, Roel Kluin schreef: > Shifting of u8 causes promotion to signed 'int' > > Signed-off-by: Roel Kluin <roel.kluin@gmail.com> > --- > I believe this was not intentionally? > see http://osdir.com/ml/git/2009-06/msg01347.html ResidCnt = (((u32) DC390_read8 (CtcReg_High) << 16) | Maybe my patch is not right. I cannot reproduce it with: #include <stdio.h> int main() { unsigned long size = 0; unsigned char c = 1; size += c << 24; printf("%lu\n", size); printf("%lu\n", 1 << 24); printf("%u\n", c); return 0; } [roel@zoinx linux-git]$ ./a.out 16777216 16777216 1 Roel ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-06-18 14:55 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-06-18 12:14 [PATCH] tmscsim: Fix big left-shifts of unsigned char Roel Kluin 2009-06-18 13:03 ` James Bottomley 2009-06-18 13:16 ` Matthew Wilcox 2009-06-18 13:27 ` Boaz Harrosh 2009-06-18 13:36 ` Matthew Wilcox 2009-06-18 14:45 ` James Bottomley 2009-06-18 14:55 ` Matthew Wilcox 2009-06-18 14:40 ` Roel Kluin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).