Fix pointer cast for 32 bits arch
Subsystems (2)
PATCH 1/1 Fix pointer cast for 32 bits arch
Sparse compalins about casting void * to u64 on i386. Change the cast to resource_size_t.
---
Tested by compilation only. Tested for x86 and x86_64.
drivers/staging/goldfish/goldfish_nand.c | 3 ++- include/linux/goldfish.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/staging/goldfish/goldfish_nand.c +2 -1
@@ -87,7 +87,8 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((resource_size_t )ptr, base +NAND_DATA , + base +NAND_DATA_HIGH );writel (cmd, base +NAND_COMMAND ); rv =readl (base +NAND_RESULT ); }
include/linux/goldfish.h +1 -1
@@ -3,7 +3,7 @@/* Helpers for Goldfish virtual platform */ -static inline void gf_write64 (unsigned long data, +static inline void gf_write64 (resource_size_t data,void __iomem *portl,void __iomem *porth) {writel ((u32 )data, portl);
Signature · 1 line
2.1.0
Quoted 17 lines · Peter Senna Tschudin
Sparse compalins about casting void * to u64 on i386. Change the cast to
resource_size_t.Signed-off-by Peter Senna Tschudin <[email protected]>---
Tested by compilation only. Tested for x86 and
x86_64.drivers/staging/goldfish/goldfish_nand.c | 3 ++- include/linux/goldfish.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)drivers/staging/goldfish/goldfish_nand.c +0
-0
drivers/staging/goldfish/goldfish_nand.c static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, · line 91
Quoted 6 lines
drivers/staging/goldfish/goldfish_nand.c +2
-1@@ -87,7 +87,8 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((resource_size_t )ptr, base +NAND_DATA , + base +NAND_DATA_HIGH );
I guess sparse still complains if CONFIG_X86_PAE=y, which makes resource_size_t u64?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Quoted 14 lines · Geert Uytterhoeven
Quoted 12 lines · Peter Senna Tschudin
Sparse compalins about casting void * to u64 on i386. Change the cast to
resource_size_t.Signed-off-by Peter Senna Tschudin <[email protected]>---
Tested by compilation only. Tested for x86 and
x86_64.drivers/staging/goldfish/goldfish_nand.c | 3 ++- include/linux/goldfish.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)
Quoted 14 lines
drivers/staging/goldfish/goldfish_nand.c static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, · line 91
Quoted 11 lines
drivers/staging/goldfish/goldfish_nand.c +2
-1@@ -87,7 +87,8 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((resource_size_t )ptr, base +NAND_DATA , + base +NAND_DATA_HIGH );I guess sparse still complains if
CONFIG_X86_PAE=y, which makesresource_size_tu64?
Yes, when CONFIG_X86_PAE=y the patch doesn't fix the warning(gcc warning). What is the correct/portable way of fixing this?
Quoted 11 lines
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Signature · 1 line
Peter
Quoted 31 lines · Peter Senna Tschudin
Quoted 14 lines · Geert Uytterhoeven
Quoted 12 lines · Peter Senna Tschudin
Sparse compalins about casting void * to u64 on i386. Change the cast to
resource_size_t.Signed-off-by Peter Senna Tschudin <[email protected]>---
Tested by compilation only. Tested for x86 and
x86_64.drivers/staging/goldfish/goldfish_nand.c | 3 ++- include/linux/goldfish.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)Quoted 14 lines
drivers/staging/goldfish/goldfish_nand.c static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, · line 91
Quoted 11 lines
drivers/staging/goldfish/goldfish_nand.c +2
-1@@ -87,7 +87,8 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((resource_size_t )ptr, base +NAND_DATA , + base +NAND_DATA_HIGH );I guess sparse still complains if
CONFIG_X86_PAE=y, which makesresource_size_tu64?
Quoted 2 lines
Yes, when
CONFIG_X86_PAE=ythe patch doesn't fix the warning(gcc warning). What is the correct/portable way of fixing this?
As gf_write64() takes "unsigned long data" for its first argument, why not simply cast ptr to "unsigned long"? "void *" and "unsigned long" have the same size on all Linux platforms.
Seems like there a several silly casting tricks being done in the goldfish drivers:
$ git grep -w gf_write64drivers/platform/goldfish/goldfish_pipe.c: gf_write64((u64)(unsigned long)p drivers/platform/goldfish/goldfish_pipe.c: gf_write64((u64)(unsigned long)p drivers/platform/goldfish/goldfish_pipe.c: gf_write64((u64) drivers/platform/goldfish/goldfish_pipe.c: gf_write64(addre drivers/staging/goldfish/goldfish_audio.c: (gf_write64((u64)(x), data->reg_ drivers/staging/goldfish/goldfish_nand.c: gf_write64((u64)ptr, bas drivers/tty/goldfish.c: gf_write64((u64)buf, base + GOLDFISH_TTY_DATA_PTR, drivers/tty/goldfish.c: gf_write64((u64)buf, base + GOLDFISH_TTY_DATA_PTR, include/linux/goldfish.h:static inline void gf_write64(unsigned long data,
with interesting history showing one wrong cast being "fixed" using another wrong cast:
commit f4e131dc38d34469b9fee1840ad237324831bce3
Author: Octavian Purdila <[email protected]> Date: Fri May 16 08:24:59 2014 +0300
goldfish: pipe: fix warnings for 32bit builds
- gf_write64((u64)pipe, dev->base + PIPE_REG_CHANNEL,
+ gf_write64((u64)(unsigned long)pipe, dev->base + PIPE_REG_CHANNEL,
As in general casts don't belong in drivers[*], what about creating an inline helper gf_set_pipe() that converts the pointer to unsigned long and calls gf_write64()?
Perhaps checkpatch should complain about casts outside header files?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Quoted 1 line · Geert Uytterhoeven
Perhaps checkpatch should complain about casts outside header files?
I think that's not feasible/desirable.
type casting is pretty common and necessary.
There are 50k+ casts in drivers/ alone.
Quoted 7 lines · Joe Perches
Quoted 1 line · Geert Uytterhoeven
Perhaps checkpatch should complain about casts outside header files?
I think that's not feasible/desirable.
type casting is pretty common and necessary.
There are 50k+ casts indrivers/alone.
What a pity.... How many of those are wrong? ;-)
If there's one thing I like about C++, it's the new-style casts, and how easy they are to grep for, unlike their C counterparts.
It would help if gcc offered -Wcast, so we could at least identify all newly introduced casts by comparing build logs, and audit them manually (like with other warnings).
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Quoted 66 lines · Geert Uytterhoeven
Quoted 31 lines · Peter Senna Tschudin
Quoted 14 lines · Geert Uytterhoeven
Quoted 12 lines · Peter Senna Tschudin
Sparse compalins about casting void * to u64 on i386. Change the cast to
resource_size_t.Signed-off-by Peter Senna Tschudin <[email protected]>---
Tested by compilation only. Tested for x86 and
x86_64.drivers/staging/goldfish/goldfish_nand.c | 3 ++- include/linux/goldfish.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)Quoted 14 lines
drivers/staging/goldfish/goldfish_nand.c static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, · line 91
Quoted 11 lines
drivers/staging/goldfish/goldfish_nand.c +2
-1@@ -87,7 +87,8 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((resource_size_t )ptr, base +NAND_DATA , + base +NAND_DATA_HIGH );I guess sparse still complains if
CONFIG_X86_PAE=y, which makesresource_size_tu64?Quoted 2 lines
Yes, when
CONFIG_X86_PAE=ythe patch doesn't fix the warning(gcc warning). What is the correct/portable way of fixing this?As
gf_write64()takes "unsigned long data" for its first argument, why not simply cast ptr to "unsigned long"? "void *" and "unsigned long" have the same size on all Linux platforms.Seems like there a several silly casting tricks being done in the goldfish drivers:
$ git grep -w gf_write64drivers/platform/goldfish/goldfish_pipe.c: gf_write64((u64)(unsigned long)p drivers/platform/goldfish/goldfish_pipe.c: gf_write64((u64)(unsigned long)p drivers/platform/goldfish/goldfish_pipe.c: gf_write64((u64) drivers/platform/goldfish/goldfish_pipe.c: gf_write64(addre drivers/staging/goldfish/goldfish_audio.c: (gf_write64((u64)(x), data->reg_ drivers/staging/goldfish/goldfish_nand.c: gf_write64((u64)ptr, bas drivers/tty/goldfish.c: gf_write64((u64)buf, base + GOLDFISH_TTY_DATA_PTR, drivers/tty/goldfish.c: gf_write64((u64)buf, base + GOLDFISH_TTY_DATA_PTR, include/linux/goldfish.h:static inline void gf_write64(unsigned long data,with interesting history showing one wrong cast being "fixed" using another wrong cast:
commit
f4e131dc38d34469b9fee1840ad237324831bce3Author: Octavian Purdila <[email protected]> Date: Fri May 16 08:24:59 2014 +0300goldfish: pipe: fix warnings for 32bit builds
(quoted diff) +1
-1- gf_write64((u64)pipe, dev->base + PIPE_REG_CHANNEL, + gf_write64((u64)(unsigned long)pipe, dev->base + PIPE_REG_CHANNEL,
Quoted 5 lines
As in general casts don't belong in drivers[*], what about creating an inline helper
gf_set_pipe()that converts the pointer to unsigned long and callsgf_write64()?Perhaps checkpatch should complain about casts outside header files?
Cocinelle found 664 double casts:
http://pastebin.com/2bi9Dg7k
and 9 triple casts:
http://pastebin.com/RkJhPTTV
Those are 'not' patches, just the output of Coccinelle for analysis. The .cocci for triple cast:
@@
expression e1, e2;
type t1, t2, t3;
@@
e1 =
- (t1)(t2)(t3)
e2
So if there are cast patterns known to be wrong, it is easy to find and probably fix them with Coccinelle.
Quoted 11 lines
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Signature · 1 line
Peter
Hi Peter,
Quoted 6 lines · Peter Senna Tschudin
Quoted 1 line
Perhaps checkpatch should complain about casts outside header files?
Cocinelle found 664 double casts:
http://pastebin.com/2bi9Dg7kand 9 triple casts:
http://pastebin.com/RkJhPTTV
I think double casts are only needed when casting between integers and pointers of different sizes:
1. One cast to make the sizes match,
2. One cast to convert between pointer and integer.
I think triple casts can always be simplified.
Or am I missing some use cases?
Quoted 10 lines
Those are 'not' patches, just the output of Coccinelle for analysis. The .cocci for triple cast:
@@
expression e1, e2;
type t1, t2, t3;
@@
e1 =
- (t1)(t2)(t3)
e2
Quoted 2 lines
So if there are cast patterns known to be wrong, it is easy to find and probably fix them with Coccinelle.
It depends on the original type and on the destination type.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Line 4677 of http://pastebin.com/2bi9Dg7k looks like a bug
diff -u -p a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
- regs->nip = (unsigned long) (unsigned long)ksig->ka.sa.sa_handler;
Quoted 44 lines · Geert Uytterhoeven
Hi Peter,
Quoted 6 lines · Peter Senna Tschudin
Quoted 1 line
Perhaps checkpatch should complain about casts outside header files?
Cocinelle found 664 double casts:
http://pastebin.com/2bi9Dg7kand 9 triple casts:
http://pastebin.com/RkJhPTTVI think double casts are only needed when casting between integers and pointers of different sizes:
1. One cast to make the sizes match,
2. One cast to convert between pointer and integer.I think triple casts can always be simplified.
Or am I missing some use cases?Quoted 10 lines
Those are 'not' patches, just the output of Coccinelle for analysis. The .cocci for triple cast:
@@
expression e1, e2;
type t1, t2, t3;
@@
e1 =
- (t1)(t2)(t3)
e2Quoted 2 lines
So if there are cast patterns known to be wrong, it is easy to find and probably fix them with Coccinelle.
It depends on the original type and on the destination type.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Signature · 1 line
Peter
Quoted 4 lines · Peter Senna Tschudin
Line 4677 of http://pastebin.com/2bi9Dg7k looks like a bug
diff -u -p
a/arch/powerpc/kernel/signal_32.cb/arch/powerpc/kernel/signal_32.c
-regs->nip= (unsigned long) (unsigned long)ksig->ka.sa.sa_handler;
I don't know about "bug" but it does look uninentional, yes.
Double casting is probably a good thing to print a static checker warning about.
Other static checkers complain about:
1) ~(char)foo;
(char)foo is type promoted to an int before the bitwise NOT.
2) (long *)&some_int
3) some_function((struct foo *)ptr);
Casting function arguments is almost always wrong. I check this with Smatch. I don't remember the details.
4) (long long)(x + y)
Probably it should be (long long)x + y
regards,
dan carpenter
PATCH v4 1/1 Fix pointer cast for 32 bits arch
As the first argument of gf_write64() was of type unsigned long, and as some calls to gf_write64() were casting the first argument from void * to u64 the compiler and/or sparse were printing warnings for casts of wrong sizes when compiling for i386.
This patch changes the type of the first argument of gf_write64() to void *, and update all calls to the function. This change fixed the warings and allowed to remove casts from 3 calls to gf_write64().
In addition gf_write64() was renamed to gf_write_ptr() as the name was misleading because it only writes 32 bits on 32 bit systems.
---
Tested by compilation only for x86, x86 with CONFIG_X86_PAE=y, and for x86_64.
Changes from V3:
- Changed type of first argument of gf_write64
- Renamed from gf_write64 to gf_write_ptr
- Updated all calls to gf_write_ptr
Changes from V2:
- Fixed spelling of complains
- Updated commit message
Changes from V1:
- Updated commit message
drivers/platform/goldfish/goldfish_pipe.c | 18 +++++++++--------- drivers/staging/goldfish/goldfish_audio.c | 2 +- drivers/staging/goldfish/goldfish_nand.c | 2 +- drivers/tty/goldfish.c | 8 ++++---- include/linux/goldfish.h | 8 ++++---- 5 files changed, 19 insertions(+), 19 deletions(-)
drivers/platform/goldfish/goldfish_pipe.c +9 -9
@@ -158,8 +158,8 @@ static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd)struct goldfish_pipe_dev *dev = pipe->dev;spin_lock_irqsave (&dev->lock, flags); -gf_write64 ((u64 )(unsigned long )pipe, dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (cmd, dev->base +PIPE_REG_COMMAND ); status =readl (dev->base +PIPE_REG_STATUS );spin_unlock_irqrestore (&dev->lock, flags);
@@ -172,8 +172,8 @@ static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd)struct goldfish_pipe_dev *dev = pipe->dev;spin_lock_irqsave (&dev->lock, flags); -gf_write64 ((u64 )(unsigned long )pipe, dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (cmd, dev->base +PIPE_REG_COMMAND );spin_unlock_irqrestore (&dev->lock, flags); }
@@ -327,12 +327,12 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,spin_lock_irqsave (&dev->lock, irq_flags);if (access_with_param (dev,CMD_WRITE_BUFFER + cmd_offset, address, avail, pipe, &status)) { -gf_write64 ((u64 )(unsigned long )pipe, - dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (avail, dev->base +PIPE_REG_SIZE ); -gf_write64 (address, dev->base +PIPE_REG_ADDRESS , - dev->base +PIPE_REG_ADDRESS_HIGH ); +gf_write_ptr ((void *)address, + dev->base +PIPE_REG_ADDRESS , + dev->base +PIPE_REG_ADDRESS_HIGH );writel (CMD_WRITE_BUFFER + cmd_offset, dev->base +PIPE_REG_COMMAND ); status =readl (dev->base +PIPE_REG_STATUS );
drivers/staging/goldfish/goldfish_audio.c +1 -1
@@ -63,7 +63,7 @@ struct goldfish_audio {#define AUDIO_READ (data, addr) (readl(data->reg_base + addr))#define AUDIO_WRITE (data, addr, x) (writel(x, data->reg_base + addr))#define AUDIO_WRITE64 (data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_ptr((void *)(x), data->reg_base + addr, data->reg_base+addr2))/* * temporary variable used between goldfish_audio_probe() and
drivers/staging/goldfish/goldfish_nand.c +1 -1
@@ -87,7 +87,7 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write_ptr (ptr, base +NAND_DATA , base +NAND_DATA_HIGH );writel (cmd, base +NAND_COMMAND ); rv =readl (base +NAND_RESULT ); }
drivers/tty/goldfish.c +4 -4
@@ -59,8 +59,8 @@ static void goldfish_tty_do_write(int line, const char *buf, unsigned count)struct goldfish_tty *qtty = &goldfish_ttys[line];void __iomem *base = qtty->base;spin_lock_irqsave (&qtty->lock, irq_flags); -gf_write64 ((u64 )buf, base +GOLDFISH_TTY_DATA_PTR , - base +GOLDFISH_TTY_DATA_PTR_HIGH ); +gf_write_ptr ((void *)buf, base +GOLDFISH_TTY_DATA_PTR , + base +GOLDFISH_TTY_DATA_PTR_HIGH );writel (count, base +GOLDFISH_TTY_DATA_LEN );writel (GOLDFISH_TTY_CMD_WRITE_BUFFER , base +GOLDFISH_TTY_CMD );spin_unlock_irqrestore (&qtty->lock, irq_flags);
@@ -81,8 +81,8 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) count =tty_prepare_flip_string (&qtty->port, &buf, count);spin_lock_irqsave (&qtty->lock, irq_flags); -gf_write64 ((u64 )buf, base +GOLDFISH_TTY_DATA_PTR , - base +GOLDFISH_TTY_DATA_PTR_HIGH ); +gf_write_ptr ((void *)buf, base +GOLDFISH_TTY_DATA_PTR , + base +GOLDFISH_TTY_DATA_PTR_HIGH );writel (count, base +GOLDFISH_TTY_DATA_LEN );writel (GOLDFISH_TTY_CMD_READ_BUFFER , base +GOLDFISH_TTY_CMD );spin_unlock_irqrestore (&qtty->lock, irq_flags);
include/linux/goldfish.h +4 -4
@@ -3,12 +3,12 @@/* Helpers for Goldfish virtual platform */ -static inline void gf_write64 (unsigned long data, -void __iomem *portl,void __iomem *porth) +static inline void gf_write_ptr (void *data,void __iomem *portl, +void __iomem *porth) { -writel ((u32 )data, portl); +writel ((u32 )(unsigned long )data, portl);#ifdef CONFIG_64BIT -writel (data>>32 , porth); +writel ((unsigned long )data >>32 , porth);#endif }
Signature · 1 line
2.1.0
drivers/staging/goldfish/goldfish_audio.c struct goldfish_audio { · line 66
Quoted 8 lines · Peter Senna Tschudin
drivers/staging/goldfish/goldfish_audio.c +1
-1@@ -63,7 +63,7 @@ struct goldfish_audio {#define AUDIO_READ (data, addr) (readl(data->reg_base + addr))#define AUDIO_WRITE (data, addr, x) (writel(x, data->reg_base + addr))#define AUDIO_WRITE64 (data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_ptr((void *)(x), data->reg_base + addr, data->reg_base+addr2))
This one should not be converted, as all callers pass a dma_addr_t, which may be 64-bit on 32-bit systems, i.e. larger than void *.
drivers/tty/goldfish.c static void goldfish_tty_do_write(int line, const char *buf, unsigned count) · line 62
Quoted 11 lines
drivers/tty/goldfish.c +1
-2@@ -59,8 +59,8 @@ static void goldfish_tty_do_write(int line, const char *buf, unsigned count)struct goldfish_tty *qtty = &goldfish_ttys[line];void __iomem *base = qtty->base;spin_lock_irqsave (&qtty->lock, irq_flags); -gf_write64 ((u64 )buf, base +GOLDFISH_TTY_DATA_PTR , - base +GOLDFISH_TTY_DATA_PTR_HIGH ); + gf_write_ptr((void *)buf, base + GOLDFISH_TTY_DATA_PTR,
Please drop the unneeded "void *" cast, as it will hide warnings if a type is changed some future time.
drivers/tty/goldfish.c static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) · line 84
Quoted 11 lines
drivers/tty/goldfish.c +2
-2+ base + GOLDFISH_TTY_DATA_PTR_HIGH);writel (count, base +GOLDFISH_TTY_DATA_LEN );writel (GOLDFISH_TTY_CMD_WRITE_BUFFER , base +GOLDFISH_TTY_CMD );spin_unlock_irqrestore (&qtty->lock, irq_flags);@@ -81,8 +81,8 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) count =tty_prepare_flip_string (&qtty->port, &buf, count);spin_lock_irqsave (&qtty->lock, irq_flags); -gf_write64 ((u64 )buf, base +GOLDFISH_TTY_DATA_PTR , - base +GOLDFISH_TTY_DATA_PTR_HIGH ); + gf_write_ptr((void *)buf, base + GOLDFISH_TTY_DATA_PTR,
Idem.
drivers/tty/goldfish.c static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) · line 88
Quoted 4 lines
drivers/tty/goldfish.c +1
-0+ base + GOLDFISH_TTY_DATA_PTR_HIGH);writel (count, base +GOLDFISH_TTY_DATA_LEN );writel (GOLDFISH_TTY_CMD_READ_BUFFER , base +GOLDFISH_TTY_CMD );spin_unlock_irqrestore (&qtty->lock, irq_flags);
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Quoted 13 lines · Geert Uytterhoeven
drivers/staging/goldfish/goldfish_audio.c struct goldfish_audio { · line 66
Quoted 8 lines · Peter Senna Tschudin
drivers/staging/goldfish/goldfish_audio.c +1
-1@@ -63,7 +63,7 @@ struct goldfish_audio {#define AUDIO_READ (data, addr) (readl(data->reg_base + addr))#define AUDIO_WRITE (data, addr, x) (writel(x, data->reg_base + addr))#define AUDIO_WRITE64 (data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_ptr((void *)(x), data->reg_base + addr, data->reg_base+addr2))This one should not be converted, as all callers pass a
dma_addr_t, which may be 64-bit on 32-bit systems, i.e. larger than void *.
Ugh... You're right.
I've been avoiding asking this but I can't any longer. What is gf_write64() actually doing? We are writing dma addresses, user space pointers and kernel space pointers to this hardware?
This stuff doesn't seem to make any kind of sense and I can easily imagine a situation where it wrote a 64 bit pointer. Then we partially write over it with a 32 bit userspace pointer. Then it writes somewhere totally unintended.
This thing doesn't make any sort of sense to me.
regards,
dan carpenter
Quoted 21 lines · Dan Carpenter
Quoted 13 lines · Geert Uytterhoeven
drivers/staging/goldfish/goldfish_audio.c struct goldfish_audio { · line 66
Quoted 8 lines · Peter Senna Tschudin
drivers/staging/goldfish/goldfish_audio.c +1
-1@@ -63,7 +63,7 @@ struct goldfish_audio {#define AUDIO_READ (data, addr) (readl(data->reg_base + addr))#define AUDIO_WRITE (data, addr, x) (writel(x, data->reg_base + addr))#define AUDIO_WRITE64 (data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_ptr((void *)(x), data->reg_base + addr, data->reg_base+addr2))This one should not be converted, as all callers pass a
dma_addr_t, which may be 64-bit on 32-bit systems, i.e. larger than void *.Ugh... You're right.
I've been avoiding asking this but I can't any longer. What is
gf_write64()actually doing? We are writing dma addresses, user space pointers and kernel space pointers to this hardware?
Quoted 6 lines
This stuff doesn't seem to make any kind of sense and I can easily imagine a situation where it wrote a 64 bit pointer. Then we partially write over it with a 32 bit userspace pointer. Then it writes somewhere totally unintended.
This thing doesn't make any sort of sense to me.
Its a 64 on 64 or 32 on 32 virtual machine. Goldfish is used for Android emulation for all the system level phone emulation tools. On the emulation side it provides an interface for the emulated OS but makes no effort to emulate it as if it was a real hardware. If you think of it as a funky emulator interface all is good. If you think about it as "hardware" you've got the wrong model and chunks of Goldfish make less sense.
Alan
Quoted 29 lines · Alan Cox
Quoted 21 lines · Dan Carpenter
Quoted 13 lines · Geert Uytterhoeven
drivers/staging/goldfish/goldfish_audio.c struct goldfish_audio { · line 66
Quoted 8 lines · Peter Senna Tschudin
drivers/staging/goldfish/goldfish_audio.c +1
-1@@ -63,7 +63,7 @@ struct goldfish_audio {#define AUDIO_READ (data, addr) (readl(data->reg_base + addr))#define AUDIO_WRITE (data, addr, x) (writel(x, data->reg_base + addr))#define AUDIO_WRITE64 (data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_ptr((void *)(x), data->reg_base + addr, data->reg_base+addr2))This one should not be converted, as all callers pass a
dma_addr_t, which may be 64-bit on 32-bit systems, i.e. larger than void *.Ugh... You're right.
I've been avoiding asking this but I can't any longer. What is
gf_write64()actually doing? We are writing dma addresses, user space pointers and kernel space pointers to this hardware?Quoted 6 lines
This stuff doesn't seem to make any kind of sense and I can easily imagine a situation where it wrote a 64 bit pointer. Then we partially write over it with a 32 bit userspace pointer. Then it writes somewhere totally unintended.
This thing doesn't make any sort of sense to me.
Quoted 7 lines
Its a 64 on 64 or 32 on 32 virtual machine. Goldfish is used for Android emulation for all the system level phone emulation tools. On the emulation side it provides an interface for the emulated OS but makes no effort to emulate it as if it was a real hardware. If you think of it as a funky emulator interface all is good. If you think about it as "hardware" you've got the wrong model and chunks of Goldfish make less sense.
Is is better to leave the code as is, and ignore the compiler / sparse warnings for i386? Or is the proposal welcome if done correctly? And if so what would be correctly?
Signature · 1 line
Peter
Greg Kroah-Hartman
maintainerQuoted 38 lines · Peter Senna Tschudin
Quoted 29 lines · Alan Cox
Quoted 21 lines · Dan Carpenter
Quoted 13 lines · Geert Uytterhoeven
drivers/staging/goldfish/goldfish_audio.c struct goldfish_audio { · line 66
Quoted 8 lines · Peter Senna Tschudin
drivers/staging/goldfish/goldfish_audio.c +1
-1@@ -63,7 +63,7 @@ struct goldfish_audio {#define AUDIO_READ (data, addr) (readl(data->reg_base + addr))#define AUDIO_WRITE (data, addr, x) (writel(x, data->reg_base + addr))#define AUDIO_WRITE64 (data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_ptr((void *)(x), data->reg_base + addr, data->reg_base+addr2))This one should not be converted, as all callers pass a
dma_addr_t, which may be 64-bit on 32-bit systems, i.e. larger than void *.Ugh... You're right.
I've been avoiding asking this but I can't any longer. What is
gf_write64()actually doing? We are writing dma addresses, user space pointers and kernel space pointers to this hardware?Quoted 6 lines
This stuff doesn't seem to make any kind of sense and I can easily imagine a situation where it wrote a 64 bit pointer. Then we partially write over it with a 32 bit userspace pointer. Then it writes somewhere totally unintended.
This thing doesn't make any sort of sense to me.
Quoted 7 lines
Its a 64 on 64 or 32 on 32 virtual machine. Goldfish is used for Android emulation for all the system level phone emulation tools. On the emulation side it provides an interface for the emulated OS but makes no effort to emulate it as if it was a real hardware. If you think of it as a funky emulator interface all is good. If you think about it as "hardware" you've got the wrong model and chunks of Goldfish make less sense.
Quoted 3 lines
Is is better to leave the code as is, and ignore the compiler / sparse warnings for i386? Or is the proposal welcome if done correctly? And if so what would be correctly?
What's the status with this mess?
Oh, and please, put a "staging: goldfish:" at the front of your subject line in the future so I know to look at it, otherwise it gets lost at times...
thanks,
greg k-h
PATCH v5 1/1 staging: goldfish: Fix pointer cast for 32 bits
As the first argument of gf_write64() was of type unsigned long, and as some calls to gf_write64() were casting the first argument from void * to u64 the compiler and/or sparse were printing warnings for casts of wrong sizes when compiling for i386.
This patch changes the type of the first argument of gf_write64() to void *, and update calls to the function. This change fixed the warnings and allowed to remove casts from 6 calls to gf_write64().
In addition gf_write64() was renamed to gf_write_ptr() as the name was misleading because it only writes 32 bits on 32 bit systems.
gf_write_dma_addr() was added to handle dma_addr_t values which is used at drivers/staging/goldfish/goldfish_audio.c.
---
Tested by compilation only for x86 and for x86_64.
Changes from V4:
- Added the function gf_write_dma_addr()
- Changed the subject line
Changes from V3:
- Changed type of first argument of gf_write64
- Renamed from gf_write64 to gf_write_ptr
- Updated all calls to gf_write_ptr
Changes from V2:
- Fixed spelling of complains
- Updated commit message
Changes from V1:
- Updated commit message
drivers/platform/goldfish/goldfish_pipe.c | 18 +++++++++--------- drivers/staging/goldfish/goldfish_audio.c | 2 +- drivers/staging/goldfish/goldfish_nand.c | 2 +- drivers/tty/goldfish.c | 4 ++-- include/linux/goldfish.h | 18 ++++++++++++++---- 5 files changed, 27 insertions(+), 17 deletions(-)
drivers/platform/goldfish/goldfish_pipe.c +9 -9
@@ -158,8 +158,8 @@ static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd)struct goldfish_pipe_dev *dev = pipe->dev;spin_lock_irqsave (&dev->lock, flags); -gf_write64 ((u64 )(unsigned long )pipe, dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (cmd, dev->base +PIPE_REG_COMMAND ); status =readl (dev->base +PIPE_REG_STATUS );spin_unlock_irqrestore (&dev->lock, flags);
@@ -172,8 +172,8 @@ static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd)struct goldfish_pipe_dev *dev = pipe->dev;spin_lock_irqsave (&dev->lock, flags); -gf_write64 ((u64 )(unsigned long )pipe, dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (cmd, dev->base +PIPE_REG_COMMAND );spin_unlock_irqrestore (&dev->lock, flags); }
@@ -327,12 +327,12 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,spin_lock_irqsave (&dev->lock, irq_flags);if (access_with_param (dev,CMD_WRITE_BUFFER + cmd_offset, address, avail, pipe, &status)) { -gf_write64 ((u64 )(unsigned long )pipe, - dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (avail, dev->base +PIPE_REG_SIZE ); -gf_write64 (address, dev->base +PIPE_REG_ADDRESS , - dev->base +PIPE_REG_ADDRESS_HIGH ); +gf_write_ptr ((void *)address, + dev->base +PIPE_REG_ADDRESS , + dev->base +PIPE_REG_ADDRESS_HIGH );writel (CMD_WRITE_BUFFER + cmd_offset, dev->base +PIPE_REG_COMMAND ); status =readl (dev->base +PIPE_REG_STATUS );
drivers/staging/goldfish/goldfish_audio.c +1 -1
@@ -63,7 +63,7 @@ struct goldfish_audio {#define AUDIO_READ (data, addr) (readl(data->reg_base + addr))#define AUDIO_WRITE (data, addr, x) (writel(x, data->reg_base + addr))#define AUDIO_WRITE64 (data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_dma_addr((x), data->reg_base + addr, data->reg_base+addr2))/* * temporary variable used between goldfish_audio_probe() and
drivers/staging/goldfish/goldfish_nand.c +1 -1
@@ -87,7 +87,7 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write_ptr (ptr, base +NAND_DATA , base +NAND_DATA_HIGH );writel (cmd, base +NAND_COMMAND ); rv =readl (base +NAND_RESULT ); }
drivers/tty/goldfish.c +2 -2
@@ -59,7 +59,7 @@ static void goldfish_tty_do_write(int line, const char *buf, unsigned count)struct goldfish_tty *qtty = &goldfish_ttys[line];void __iomem *base = qtty->base;spin_lock_irqsave (&qtty->lock, irq_flags); -gf_write64 ((u64 )buf, base +GOLDFISH_TTY_DATA_PTR , +gf_write_ptr (buf, base +GOLDFISH_TTY_DATA_PTR , base +GOLDFISH_TTY_DATA_PTR_HIGH );writel (count, base +GOLDFISH_TTY_DATA_LEN );writel (GOLDFISH_TTY_CMD_WRITE_BUFFER , base +GOLDFISH_TTY_CMD );
@@ -81,7 +81,7 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) count =tty_prepare_flip_string (&qtty->port, &buf, count);spin_lock_irqsave (&qtty->lock, irq_flags); -gf_write64 ((u64 )buf, base +GOLDFISH_TTY_DATA_PTR , +gf_write_ptr (buf, base +GOLDFISH_TTY_DATA_PTR , base +GOLDFISH_TTY_DATA_PTR_HIGH );writel (count, base +GOLDFISH_TTY_DATA_LEN );writel (GOLDFISH_TTY_CMD_READ_BUFFER , base +GOLDFISH_TTY_CMD );
include/linux/goldfish.h +14 -4
@@ -3,13 +3,23 @@/* Helpers for Goldfish virtual platform */ -static inline void gf_write64 (unsigned long data, -void __iomem *portl,void __iomem *porth) +static inline void gf_write_ptr (void *ptr,void __iomem *portl, +void __iomem *porth) { -writel ((u32 )data, portl); +writel ((u32 )(unsigned long )ptr, portl);#ifdef CONFIG_64BIT -writel (data>>32 , porth); +writel ((unsigned long )ptr >>32 , porth);#endif } +static inline void gf_write_dma_addr (dma_addr_t addr,void __iomem *portl, +void __iomem *porth) +{ +writel ((u32 )addr, portl); +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT +writel (addr >>32 , porth); +#endif +} + +#endif /* __LINUX_GOLDFISH_H */
Signature · 1 line
2.1.0
Re: [PATCH V5] staging: goldfish: Fix pointer cast for 32 bits
Looks good.
regards,
dan carpenter
Greg KH
maintainerRe: [PATCH V5] staging: goldfish: Fix pointer cast for 32 bits
In reply to Peter Senna TschudinQuoted 12 lines · Peter Senna Tschudin
As the first argument of
gf_write64()was of type unsigned long, and as some calls togf_write64()were casting the first argument from void * to u64 the compiler and/or sparse were printing warnings for casts of wrong sizes when compiling for i386.This patch changes the type of the first argument of
gf_write64()to void *, and update calls to the function. This change fixed the warnings and allowed to remove casts from 6 calls togf_write64().In addition
gf_write64()was renamed togf_write_ptr()as the name was misleading because it only writes 32 bits on 32 bit systems.
Quoted 7 lines
gf_write_dma_addr()was added to handledma_addr_tvalues which is used atdrivers/staging/goldfish/goldfish_audio.c.Signed-off-by Dan Carpenter <[email protected]>Signed-off-by Peter Senna Tschudin <[email protected]>---
Tested by compilation only for x86 and forx86_64.
This adds two build warnings:
drivers/tty/goldfish.c: In function ‘goldfish_tty_do_write’:drivers/tty/goldfish.c:62:15: warning: passing argument 1 of ‘gf_write_ptr’ discards ‘const’ qualifier from pointer target type
gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR,
^
In file included from drivers/tty/goldfish.c:24:0:
include/linux/goldfish.h:6:20: note: expected ‘void *’ but argument is of type ‘const char *’
static inline void gf_write_ptr(void *ptr, void __iomem *portl,
^So I can't take this. Please fix up and resend, and always test build your patches...
thanks,
greg k-h
PATCH v6 1/1 staging: goldfish: Fix pointer cast for 32 bits
As the first argument of gf_write64() was of type unsigned long, and as some calls to gf_write64() were casting the first argument from void * to u64 the compiler and/or sparse were printing warnings for casts of wrong sizes when compiling for i386.
This patch changes the type of the first argument of gf_write64() to const void *, and update calls to the function. This change fixed the warnings and allowed to remove casts from 3 calls to gf_write64().
In addition gf_write64() was renamed to gf_write_ptr() as the name was misleading because it only writes 32 bits on 32 bit systems.
gf_write_dma_addr() was added to handle dma_addr_t values which is used at drivers/staging/goldfish/goldfish_audio.c.
---
When submiting V5, I havent tested the patch properly. It was my fault. Tested by compilation only for i386 and for x86_64.
Changes from v5:
- Added const to first argument of both gf_write_ptr() and gf_write_dma_addr()
Changes from V4:
- Added the function gf_write_dma_addr()
- Changed the subject line
Changes from V3:
- Changed type of first argument of gf_write64
- Renamed from gf_write64 to gf_write_ptr
- Updated all calls to gf_write_ptr
Changes from V2:
- Fixed spelling of complains
- Updated commit message
Changes from V1:
- Updated commit message
drivers/platform/goldfish/goldfish_pipe.c | 18 +++++++++--------- drivers/staging/goldfish/goldfish_audio.c | 2 +- drivers/staging/goldfish/goldfish_nand.c | 2 +- drivers/tty/goldfish.c | 4 ++-- include/linux/goldfish.h | 19 +++++++++++++++---- 5 files changed, 28 insertions(+), 17 deletions(-)
drivers/platform/goldfish/goldfish_pipe.c +9 -9
@@ -158,8 +158,8 @@ static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd)struct goldfish_pipe_dev *dev = pipe->dev;spin_lock_irqsave (&dev->lock, flags); -gf_write64 ((u64 )(unsigned long )pipe, dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (cmd, dev->base +PIPE_REG_COMMAND ); status =readl (dev->base +PIPE_REG_STATUS );spin_unlock_irqrestore (&dev->lock, flags);
@@ -172,8 +172,8 @@ static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd)struct goldfish_pipe_dev *dev = pipe->dev;spin_lock_irqsave (&dev->lock, flags); -gf_write64 ((u64 )(unsigned long )pipe, dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (cmd, dev->base +PIPE_REG_COMMAND );spin_unlock_irqrestore (&dev->lock, flags); }
@@ -327,12 +327,12 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,spin_lock_irqsave (&dev->lock, irq_flags);if (access_with_param (dev,CMD_WRITE_BUFFER + cmd_offset, address, avail, pipe, &status)) { -gf_write64 ((u64 )(unsigned long )pipe, - dev->base +PIPE_REG_CHANNEL , - dev->base +PIPE_REG_CHANNEL_HIGH ); +gf_write_ptr (pipe, dev->base +PIPE_REG_CHANNEL , + dev->base +PIPE_REG_CHANNEL_HIGH );writel (avail, dev->base +PIPE_REG_SIZE ); -gf_write64 (address, dev->base +PIPE_REG_ADDRESS , - dev->base +PIPE_REG_ADDRESS_HIGH ); +gf_write_ptr ((void *)address, + dev->base +PIPE_REG_ADDRESS , + dev->base +PIPE_REG_ADDRESS_HIGH );writel (CMD_WRITE_BUFFER + cmd_offset, dev->base +PIPE_REG_COMMAND ); status =readl (dev->base +PIPE_REG_STATUS );
drivers/staging/goldfish/goldfish_audio.c +1 -1
@@ -63,7 +63,7 @@ struct goldfish_audio {#define AUDIO_READ (data, addr) (readl(data->reg_base + addr))#define AUDIO_WRITE (data, addr, x) (writel(x, data->reg_base + addr))#define AUDIO_WRITE64 (data, addr, addr2, x) \ - (gf_write64((u64)(x), data->reg_base + addr, data->reg_base+addr2)) + (gf_write_dma_addr((x), data->reg_base + addr, data->reg_base+addr2))/* * temporary variable used between goldfish_audio_probe() and
drivers/staging/goldfish/goldfish_nand.c +1 -1
@@ -87,7 +87,7 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write_ptr (ptr, base +NAND_DATA , base +NAND_DATA_HIGH );writel (cmd, base +NAND_COMMAND ); rv =readl (base +NAND_RESULT ); }
drivers/tty/goldfish.c +2 -2
@@ -59,7 +59,7 @@ static void goldfish_tty_do_write(int line, const char *buf, unsigned count)struct goldfish_tty *qtty = &goldfish_ttys[line];void __iomem *base = qtty->base;spin_lock_irqsave (&qtty->lock, irq_flags); -gf_write64 ((u64 )buf, base +GOLDFISH_TTY_DATA_PTR , +gf_write_ptr (buf, base +GOLDFISH_TTY_DATA_PTR , base +GOLDFISH_TTY_DATA_PTR_HIGH );writel (count, base +GOLDFISH_TTY_DATA_LEN );writel (GOLDFISH_TTY_CMD_WRITE_BUFFER , base +GOLDFISH_TTY_CMD );
@@ -81,7 +81,7 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) count =tty_prepare_flip_string (&qtty->port, &buf, count);spin_lock_irqsave (&qtty->lock, irq_flags); -gf_write64 ((u64 )buf, base +GOLDFISH_TTY_DATA_PTR , +gf_write_ptr (buf, base +GOLDFISH_TTY_DATA_PTR , base +GOLDFISH_TTY_DATA_PTR_HIGH );writel (count, base +GOLDFISH_TTY_DATA_LEN );writel (GOLDFISH_TTY_CMD_READ_BUFFER , base +GOLDFISH_TTY_CMD );
include/linux/goldfish.h +15 -4
@@ -3,13 +3,24 @@/* Helpers for Goldfish virtual platform */ -static inline void gf_write64 (unsigned long data, -void __iomem *portl,void __iomem *porth) +static inline void gf_write_ptr (const void *ptr,void __iomem *portl, +void __iomem *porth) { -writel ((u32 )data, portl); +writel ((u32 )(unsigned long )ptr, portl);#ifdef CONFIG_64BIT -writel (data>>32 , porth); +writel ((unsigned long )ptr >>32 , porth);#endif } +static inline void gf_write_dma_addr (const dma_addr_t addr, +void __iomem *portl, +void __iomem *porth) +{ +writel ((u32 )addr, portl); +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT +writel (addr >>32 , porth); +#endif +} + +#endif /* __LINUX_GOLDFISH_H */
Signature · 1 line
2.1.0
Quoted 8 lines · Alan Cox
Its a 64 on 64 or 32 on 32 virtual machine. Goldfish is used for Android emulation for all the system level phone emulation tools. On the emulation side it provides an interface for the emulated OS but makes no effort to emulate it as if it was a real hardware. If you think of it as a funky emulator interface all is good. If you think about it as "hardware" you've got the wrong model and chunks of Goldfish make less sense.
Ah. Ok. That makes sense.
Peter maybe the fix is to make a different function:
static inline void gf_write_dma_addr(dma_addr_t addr, void __iomem *portl,
void __iomem *porth)
{
writel((u32)data, portl);
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
writel(data >> 32, porth);#endif
}
Something like that.
The gf_write_ptr() function patch you wrote preserves the current behavior, but the current behavior is buggy, (I think) so we need both gf_write_dma_addr() and gf_write_ptr().
regards,
dan carpenter
Actually, my patch seems like a good idea to me but it's one of those things that someone should probably test. Unless someone can test goldfish on a 32 bit system with 64 bit dma addresses then maybe the thing to is to write the new function but preserve the current behavior.
static inline void gf_write_dma_addr(dma_addr_t addr, void __iomem *portl,
void __iomem *porth)
{
writel((u32)data, portl);
/*
* This should be CONFIG_ARCH_DMA_ADDR_T_64BIT but someone needs to
* test it.
*/
#ifdef CONFIG_64BIT
writel(data >> 32, porth);#endif
}
regards,
dan carpenter
Quoted 3 lines · Dan Carpenter
Actually, my patch seems like a good idea to me but it's one of those things that someone should probably test. Unless someone can test goldfish on a 32 bit system with 64 bit dma addresses
No such "system" exists.
Alan
Quoted 6 lines · Alan Cox
Quoted 3 lines · Dan Carpenter
Actually, my patch seems like a good idea to me but it's one of those things that someone should probably test. Unless someone can test goldfish on a 32 bit system with 64 bit dma addresses
No such "system" exists.
I don't understand. We definitely can have 64bit dma addresses on x86_32.
regards,
dan carpenter
Quoted 10 lines · Dan Carpenter
Quoted 6 lines · Alan Cox
Quoted 3 lines · Dan Carpenter
Actually, my patch seems like a good idea to me but it's one of those things that someone should probably test. Unless someone can test goldfish on a 32 bit system with 64 bit dma addresses
No such "system" exists.
I don't understand. We definitely can have 64bit dma addresses on
x86_32.
Yes but no actual Goldfish environment is built that way
Quoted 7 lines · Alan Cox
Quoted 6 lines · Dan Carpenter
Quoted 5 lines · Alan Cox
Quoted 3 lines · Dan Carpenter
Actually, my patch seems like a good idea to me but it's one of those things that someone should probably test. Unless someone can test goldfish on a 32 bit system with 64 bit dma addresses
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
No such "system" exists.
I don't understand. We definitely can have 64bit dma addresses on
x86_32.Yes but no actual Goldfish environment is built that way
Isn't this a simpler fix?
drivers/staging/goldfish/goldfish_nand.c +1 -1
@@ -87,7 +87,7 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((unsigned long )ptr, base +NAND_DATA , base +NAND_DATA_HIGH );writel (cmd, base +NAND_COMMAND ); rv =readl (base +NAND_RESULT ); }
Signature · 1 line
Peter
Quoted 10 lines · Peter Senna Tschudin
Quoted 7 lines · Alan Cox
Quoted 6 lines · Dan Carpenter
Quoted 5 lines · Alan Cox
Quoted 3 lines · Dan Carpenter
Actually, my patch seems like a good idea to me but it's one of those things that someone should probably test. Unless someone can test goldfish on a 32 bit system with 64 bit dma addresses
Quoted 8 lines
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
No such "system" exists.
I don't understand. We definitely can have 64bit dma addresses on
x86_32.Yes but no actual Goldfish environment is built that way
Isn't this a simpler fix?
I still think my fix is cleanest even though dma_addr_t and size_t are always the same. It just means that we can commit it without worrying about testing.
regards,
dan carpenter
Quoted 17 lines · Peter Senna Tschudin
Sparse compalins about casting void * to u64 on i386. Change the cast to
resource_size_t.Signed-off-by Peter Senna Tschudin <[email protected]>---
Tested by compilation only. Tested for x86 and
x86_64.drivers/staging/goldfish/goldfish_nand.c | 3 ++- include/linux/goldfish.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)drivers/staging/goldfish/goldfish_nand.c +0
-0
drivers/staging/goldfish/goldfish_nand.c static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, · line 91
Quoted 6 lines
drivers/staging/goldfish/goldfish_nand.c +2
-1@@ -87,7 +87,8 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((resource_size_t )ptr, base +NAND_DATA , + base +NAND_DATA_HIGH );
write64 is a misleading name because it only writes 32 bits on 32 bit systems.
Are you sure it's a resource_size_t? If that's really true then this code needs a lot more work. The ifdef in gf_write64() should be CONFIG_PHYS_ADDR_T_64BIT and ops->datbuf needs to updated. It would be a lot of changes...
I *think* but I'm not positive that gf_write64 should just take a void pointer like this:
drivers/staging/goldfish/goldfish_nand.c +1 -1
@@ -87,7 +87,7 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 (ptr, base +NAND_DATA , base +NAND_DATA_HIGH );writel (cmd, base +NAND_COMMAND ); rv =readl (base +NAND_RESULT ); }
include/linux/goldfish.h +3 -3
@@ -3,12 +3,12 @@/* Helpers for Goldfish virtual platform */ -static inline void gf_write64 (unsigned long data, +static inline void gf_write64 (void *data,void __iomem *portl,void __iomem *porth) { -writel ((u32 )data, portl); +writel ((u32 )(unsigned long )data, portl);#ifdef CONFIG_64BIT -writel (data>>32 , porth); +writel ((unsigned long )data >>32 , porth);#endif }
Quoted 59 lines · Dan Carpenter
Quoted 17 lines · Peter Senna Tschudin
Sparse compalins about casting void * to u64 on i386. Change the cast to
resource_size_t.Signed-off-by Peter Senna Tschudin <[email protected]>---
Tested by compilation only. Tested for x86 and
x86_64.drivers/staging/goldfish/goldfish_nand.c | 3 ++- include/linux/goldfish.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)drivers/staging/goldfish/goldfish_nand.c +0
-0drivers/staging/goldfish/goldfish_nand.c static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, · line 91
Quoted 6 lines
drivers/staging/goldfish/goldfish_nand.c +2
-1@@ -87,7 +87,8 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((resource_size_t )ptr, base +NAND_DATA , + base +NAND_DATA_HIGH );write64 is a misleading name because it only writes 32 bits on 32 bit systems.
Are you sure it's a
resource_size_t? If that's really true then this code needs a lot more work. The ifdef ingf_write64()should beCONFIG_PHYS_ADDR_T_64BITandops->datbufneeds to updated. It would be a lot of changes...I *think* but I'm not positive that
gf_write64should just take a void pointer like this:drivers/staging/goldfish/goldfish_nand.c +1
-1@@ -87,7 +87,7 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 (ptr, base +NAND_DATA , base +NAND_DATA_HIGH );writel (cmd, base +NAND_COMMAND ); rv =readl (base +NAND_RESULT ); }include/linux/goldfish.h +1
-1@@ -3,12 +3,12 @@/* Helpers for Goldfish virtual platform */ -static inline void gf_write64(unsigned long data, +static inline void gf_write64(void *data,
include/linux/goldfish.h line 14
Quoted 10 lines
include/linux/goldfish.h +2
-2void __iomem *portl, void __iomem *porth) { - writel((u32)data, portl); + writel((u32)(unsigned long)data, portl);#ifdef CONFIG_64BIT -writel (data>>32 , porth); +writel ((unsigned long )data >>32 , porth);#endif }
I like this solution. Should I send a single patch changing gf_write64() and removing all casts when calling the gf_write64(), or if to split, how to split the patch?
Signature · 1 line
Peter
Quoted 59 lines · Peter Senna Tschudin
Quoted 57 lines · Dan Carpenter
Quoted 17 lines · Peter Senna Tschudin
Sparse compalins about casting void * to u64 on i386. Change the cast to
resource_size_t.Signed-off-by Peter Senna Tschudin <[email protected]>---
Tested by compilation only. Tested for x86 and
x86_64.drivers/staging/goldfish/goldfish_nand.c | 3 ++- include/linux/goldfish.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)drivers/staging/goldfish/goldfish_nand.c +0
-0drivers/staging/goldfish/goldfish_nand.c static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd, · line 91
Quoted 6 lines
drivers/staging/goldfish/goldfish_nand.c +2
-1@@ -87,7 +87,8 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 ((resource_size_t )ptr, base +NAND_DATA , + base +NAND_DATA_HIGH );write64 is a misleading name because it only writes 32 bits on 32 bit systems.
Are you sure it's a
resource_size_t? If that's really true then this code needs a lot more work. The ifdef ingf_write64()should beCONFIG_PHYS_ADDR_T_64BITandops->datbufneeds to updated. It would be a lot of changes...I *think* but I'm not positive that
gf_write64should just take a void pointer like this:drivers/staging/goldfish/goldfish_nand.c +1
-1@@ -87,7 +87,7 @@ static u32 goldfish_nand_cmd(struct mtd_info *mtd, enum nand_cmd cmd,writel ((u32)(addr >>32 ), base +NAND_ADDR_HIGH );writel ((u32 )addr, base +NAND_ADDR_LOW );writel (len, base +NAND_TRANSFER_SIZE ); -gf_write64 ((u64 )ptr, base +NAND_DATA , base +NAND_DATA_HIGH ); +gf_write64 (ptr, base +NAND_DATA , base +NAND_DATA_HIGH );writel (cmd, base +NAND_COMMAND ); rv =readl (base +NAND_RESULT ); }include/linux/goldfish.h +0
-0@@ -3,12 +3,12 @@/* Helpers for Goldfish virtual platform */
Quoted 16 lines
include/linux/goldfish.h line 14
Quoted 12 lines
include/linux/goldfish.h +3
-3-static inline void gf_write64 (unsigned long data, +static inline void gf_write64 (void *data,void __iomem *portl,void __iomem *porth) { -writel ((u32 )data, portl); +writel ((u32 )(unsigned long )data, portl);#ifdef CONFIG_64BIT -writel (data>>32 , porth); +writel ((unsigned long )data >>32 , porth);#endif }I like this solution. Should I send a single patch changing
gf_write64()and removing all casts when calling thegf_write64(), or if to split, how to split the patch?
Single patch, please. Maybe rename the function to gf_write_ptr() or something similar.
regards,
dan carpenter