Skip to contentSkip to conversation

nvme: fix 32-bit build warning

PATCH In review Arnd Bergmann 4 participants 8 messages Oct 6, 2015 – Oct 12, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nvme: fix 32-bit build warning

Compiling the nvme driver on 32-bit warns about a cast from a __u64 variable to a pointer:

drivers/block/nvme-core.c: In function 'nvme_submit_io':
drivers/block/nvme-core.c:1847:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

    (void __user *)io.addr, length, NULL, 0);

The cast here is intentional and safe, so we can shut up the gcc warning by adding an intermediate cast to 'unsigned long'.

I had previously submitted a patch to fix this problem in the nvme driver, but it was accepted on the same day that two new warnings got added.

Fixes d29ec8241c10e ("nvme: submit internal commands through the block layer")
drivers/block/nvme-core.c +2 -2
index e917cf304ad0..f9faf276ce74 100644
@@ -1844,7 +1844,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
 	c.rw.metadata = cpu_to_le64(meta_dma);
 
 	status = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
-			(void __user *)io.addr, length, NULL, 0);
+			(void __user *)(unsigned long)io.addr, length, NULL, 0);
  unmap:
 	if (meta) {
 		if (status == NVME_SC_SUCCESS && !write) {
@@ -1886,7 +1886,7 @@ static int nvme_user_cmd(struct nvme_dev *dev, struct nvme_ns *ns,
 		timeout = msecs_to_jiffies(cmd.timeout_ms);
 
 	status = __nvme_submit_sync_cmd(ns ? ns->queue : dev->admin_q, &c,
-			NULL, (void __user *)cmd.addr, cmd.data_len,
+			NULL, (void __user *)(unsigned long)cmd.addr, cmd.data_len,
 			&cmd.result, timeout);
 	if (status >= 0) {
 		if (put_user(cmd.result, &ucmd->result))
#1 lore raw
Quoted 9 lines · Arnd Bergmann

Compiling the nvme driver on 32-bit warns about a cast from a __u64 variable to a pointer:

drivers/block/nvme-core.c: In function 'nvme_submit_io':
drivers/block/nvme-core.c:1847:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

    (void __user *)io.addr, length, NULL, 0);

The cast here is intentional and safe, so we can shut up the gcc warning by adding an intermediate cast to 'unsigned long'.

It really should be a uintptr_t, which would also avoid the > 80 character lines. I wonder if we need a u64_to_ptr helper given these ioctl ABIs that pass pointers as a u64 seems to be everywhere these days.

#2 lore raw
Quoted 8 lines · On Friday 09 October 2015 07:42:21 Christoph Hellwig wrote:
Quoted 7 lines · Arnd Bergmann

Compiling the nvme driver on 32-bit warns about a cast from a __u64 variable to a pointer:

drivers/block/nvme-core.c: In function 'nvme_submit_io':
drivers/block/nvme-core.c:1847:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

    (void __user *)io.addr, length, NULL, 0);
Quoted 7 lines
Quoted 2 lines

The cast here is intentional and safe, so we can shut up the gcc warning by adding an intermediate cast to 'unsigned long'.

It really should be a uintptr_t, which would also avoid the > 80 character lines. I wonder if we need a u64_to_ptr helper given these ioctl ABIs that pass pointers as a u64 seems to be everywhere these days.

I'll send a new version with uintptr_t for now, but having a proper interface for this sounds like a good idea.

I've seen a couple of cases like this, and most but not all actually want a __user pointer like this one. That seems similar to the common ioctl use case where we want a user pointer from an 'unsigned long', so we could use the same function for both, like

static inline void __user *get_uptr(unsigned long arg)

{
	return (void __user *)arg;
}

With this definition, you can pass any scalar type (u64 or unsigned long normally) and get the pointer, and we can put that into include/linux/uaccess.h.

Arnd

#3 lore raw

PATCH v2 1/1 nvme: fix 32-bit build warning

In reply to Christoph Hellwig
Quoted 1 line

From 877a323df080bda54a71e26ecf20b4244b31a180 Mon Sep 17 00:00:00 2001

From: Arnd Bergmann <[email protected]>
Date: Tue, 6 Oct 2015 22:29:48 +0200
Subject: [PATCH] nvme: fix 32-bit build warning

Compiling the nvme driver on 32-bit warns about a cast from a __u64 variable to a pointer:

drivers/block/nvme-core.c: In function 'nvme_submit_io':
drivers/block/nvme-core.c:1847:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

    (void __user *)io.addr, length, NULL, 0);

The cast here is intentional and safe, so we can shut up the gcc warning by adding an intermediate cast to 'uintptr_t'.

I had previously submitted a patch to fix this problem in the nvme driver, but it was accepted on the same day that two new warnings got added.

For clarification, I also change the third instance of this cast to use uintptr_t instead of unsigned long now.

Fixes d29ec8241c10e ("nvme: submit internal commands through the block layer")

---
v2: use uintptr_t for intermediate cast

drivers/block/nvme-core.c +3 -3
index e917cf304ad0..e8ff16c63977 100644
@@ -1804,7 +1804,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
 
 	length = (io.nblocks + 1) << ns->lba_shift;
 	meta_len = (io.nblocks + 1) * ns->ms;
-	metadata = (void __user *)(unsigned long)io.metadata;
+	metadata = (void __user *)(uintptr_t)io.metadata;
 	write = io.opcode & 1;
 
 	if (ns->ext) {
@@ -1844,7 +1844,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
 	c.rw.metadata = cpu_to_le64(meta_dma);
 
 	status = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
-			(void __user *)io.addr, length, NULL, 0);
+			(void __user *)(uintptr_t)io.addr, length, NULL, 0);
  unmap:
 	if (meta) {
 		if (status == NVME_SC_SUCCESS && !write) {
@@ -1886,7 +1886,7 @@ static int nvme_user_cmd(struct nvme_dev *dev, struct nvme_ns *ns,
 		timeout = msecs_to_jiffies(cmd.timeout_ms);
 
 	status = __nvme_submit_sync_cmd(ns ? ns->queue : dev->admin_q, &c,
-			NULL, (void __user *)cmd.addr, cmd.data_len,
+			NULL, (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
 			&cmd.result, timeout);
 	if (status >= 0) {
 		if (put_user(cmd.result, &ucmd->result))
#5 lore raw
Quoted 6 lines · Christoph Hellwig

Looks good,

Note that we're moved the nvme driver to a new directory in the block tree, but I can rebase it for you if you want.

I man handled it on both branches, so we should be good.

Signature · 1 line
Jens Axboe
#6 lore raw
Quoted 9 lines · On Monday 12 October 2015 13:10:17 Jens Axboe wrote:
Quoted 6 lines · Christoph Hellwig

Looks good,

Note that we're moved the nvme driver to a new directory in the block tree, but I can rebase it for you if you want.

I man handled it on both branches, so we should be good.

Thanks! I already saw the move, and it caused another build error when CONFIG_BLOCK is disabled. Do you have this one?

Arnd

drivers/nvme/host/Kconfig +1 -1
index 0089f78b4071..002a94abdbc4 100644
@@ -1,6 +1,6 @@
 config BLK_DEV_NVME
 	tristate "NVM Express block device"
-	depends on PCI
+	depends on PCI && BLOCK
 	---help---
 	  The NVM Express driver is for solid state drives directly
 	  connected to the PCI or PCI Express bus.  If you know you
#7 lore raw
Quoted 6 lines · Arnd Bergmann
Quoted 5 lines · On Monday 12 October 2015 13:10:17 Jens Axboe wrote:
Quoted 4 lines · Christoph Hellwig

Looks good,

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

Note that we're moved the nvme driver to a new directory in the block tree, but I can rebase it for you if you want.

I man handled it on both branches, so we should be good.

Thanks! I already saw the move, and it caused another build error when CONFIG_BLOCK is disabled. Do you have this one?

I do, Keith sent that one in earlier today, it's in the 4.4 branch.

Signature · 1 line
Jens Axboe