2021-09-27 15:37:50

by Keith Busch

[permalink] [raw]
Subject: [PATCH] nvme: add command id quirk for apple controllers

Some apple controllers use the command id as an index to implementation
specific data structures and will fail if the value is out of bounds.
The nvme driver's recently introduced command sequence number breaks
this controller.

Provide a quirk so these spec incompliant controllers can function as
before. The driver will not have the ability to detect bad completions
when this quirk is used, but we weren't previously checking this anyway.

The quirk bit was selected so that it can readily apply to stable.

Fixes: e7006de6c2380 ("nvme: code command_id with a genctr for use-after-free validation")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=214509
Cc: Sven Peter <[email protected]>
Reported-by: Orlando Chamberlain <[email protected]>
Reported-by: Aditya Garg <[email protected]>
Signed-off-by: Keith Busch <[email protected]>
---
drivers/nvme/host/core.c | 4 +++-
drivers/nvme/host/nvme.h | 6 ++++++
drivers/nvme/host/pci.c | 3 ++-
3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index e486845d2c7e..afbd47e16293 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -978,6 +978,7 @@ EXPORT_SYMBOL_GPL(nvme_cleanup_cmd);
blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
{
struct nvme_command *cmd = nvme_req(req)->cmd;
+ struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
blk_status_t ret = BLK_STS_OK;

if (!(req->rq_flags & RQF_DONTPREP)) {
@@ -1026,7 +1027,8 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
return BLK_STS_IOERR;
}

- nvme_req(req)->genctr++;
+ if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
+ nvme_req(req)->genctr++;
cmd->common.command_id = nvme_cid(req);
trace_nvme_setup_cmd(req, cmd);
return ret;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 9871c0c9374c..ed79a6c7e804 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -138,6 +138,12 @@ enum nvme_quirks {
* 48 bits.
*/
NVME_QUIRK_DMA_ADDRESS_BITS_48 = (1 << 16),
+
+ /*
+ * The controller requires the command_id value be be limited, so skip
+ * encoding the generation sequence number.
+ */
+ NVME_QUIRK_SKIP_CID_GEN = (1 << 17),
};

/*
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index b82492cd7503..456a0e8a5718 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -3369,7 +3369,8 @@ static const struct pci_device_id nvme_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005),
.driver_data = NVME_QUIRK_SINGLE_VECTOR |
NVME_QUIRK_128_BYTES_SQES |
- NVME_QUIRK_SHARED_TAGS },
+ NVME_QUIRK_SHARED_TAGS |
+ NVME_QUIRK_SKIP_CID_GEN },

{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
{ 0, }
--
2.25.4


2021-09-27 15:42:35

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] nvme: add command id quirk for apple controllers

On 9/27/21 9:35 AM, Keith Busch wrote:
> @@ -1026,7 +1027,8 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
> return BLK_STS_IOERR;
> }
>
> - nvme_req(req)->genctr++;
> + if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
> + nvme_req(req)->genctr++;

This doesn't look right, as it'll never be true...

--
Jens Axboe

2021-09-29 15:07:20

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] nvme: add command id quirk for apple controllers

Hi Keith,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.15-rc3 next-20210922]
[cannot apply to hch-configfs/for-next linux-nvme/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Keith-Busch/nvme-add-command-id-quirk-for-apple-controllers/20210929-191053
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a4e6f95a891ac08bd09d62e3e6dae239b150f4c1
config: hexagon-randconfig-r045-20210929 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project dc6e8dfdfe7efecfda318d43a06fae18b40eb498)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/c62c81f7de2ecd19bd3f85afe63d0040401bce0c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Keith-Busch/nvme-add-command-id-quirk-for-apple-controllers/20210929-191053
git checkout c62c81f7de2ecd19bd3f85afe63d0040401bce0c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=hexagon

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> drivers/nvme/host/core.c:1030:6: warning: logical not is only applied to the left hand side of this bitwise operator [-Wlogical-not-parentheses]
if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
^ ~
drivers/nvme/host/core.c:1030:6: note: add parentheses after the '!' to evaluate the bitwise operator first
if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
^
( )
drivers/nvme/host/core.c:1030:6: note: add parentheses around left hand side expression to silence this warning
if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
^
( )
1 warning generated.


vim +1030 drivers/nvme/host/core.c

977
978 blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
979 {
980 struct nvme_command *cmd = nvme_req(req)->cmd;
981 struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
982 blk_status_t ret = BLK_STS_OK;
983
984 if (!(req->rq_flags & RQF_DONTPREP)) {
985 nvme_clear_nvme_request(req);
986 memset(cmd, 0, sizeof(*cmd));
987 }
988
989 switch (req_op(req)) {
990 case REQ_OP_DRV_IN:
991 case REQ_OP_DRV_OUT:
992 /* these are setup prior to execution in nvme_init_request() */
993 break;
994 case REQ_OP_FLUSH:
995 nvme_setup_flush(ns, cmd);
996 break;
997 case REQ_OP_ZONE_RESET_ALL:
998 case REQ_OP_ZONE_RESET:
999 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_RESET);
1000 break;
1001 case REQ_OP_ZONE_OPEN:
1002 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_OPEN);
1003 break;
1004 case REQ_OP_ZONE_CLOSE:
1005 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_CLOSE);
1006 break;
1007 case REQ_OP_ZONE_FINISH:
1008 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_FINISH);
1009 break;
1010 case REQ_OP_WRITE_ZEROES:
1011 ret = nvme_setup_write_zeroes(ns, req, cmd);
1012 break;
1013 case REQ_OP_DISCARD:
1014 ret = nvme_setup_discard(ns, req, cmd);
1015 break;
1016 case REQ_OP_READ:
1017 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_read);
1018 break;
1019 case REQ_OP_WRITE:
1020 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_write);
1021 break;
1022 case REQ_OP_ZONE_APPEND:
1023 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_zone_append);
1024 break;
1025 default:
1026 WARN_ON_ONCE(1);
1027 return BLK_STS_IOERR;
1028 }
1029
> 1030 if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
1031 nvme_req(req)->genctr++;
1032 cmd->common.command_id = nvme_cid(req);
1033 trace_nvme_setup_cmd(req, cmd);
1034 return ret;
1035 }
1036 EXPORT_SYMBOL_GPL(nvme_setup_cmd);
1037

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (4.53 kB)
.config.gz (31.02 kB)
Download all attachments

2021-09-29 15:17:51

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] nvme: add command id quirk for apple controllers

Hi Keith,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.15-rc3 next-20210922]
[cannot apply to hch-configfs/for-next linux-nvme/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Keith-Busch/nvme-add-command-id-quirk-for-apple-controllers/20210929-191053
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a4e6f95a891ac08bd09d62e3e6dae239b150f4c1
config: arc-randconfig-r043-20210929 (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/c62c81f7de2ecd19bd3f85afe63d0040401bce0c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Keith-Busch/nvme-add-command-id-quirk-for-apple-controllers/20210929-191053
git checkout c62c81f7de2ecd19bd3f85afe63d0040401bce0c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

In file included from include/linux/kernel.h:11,
from include/linux/list.h:9,
from include/linux/rculist.h:10,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from include/linux/blkdev.h:5,
from drivers/nvme/host/core.c:7:
drivers/nvme/host/core.c: In function 'nvme_setup_cmd':
>> drivers/nvme/host/core.c:1030:13: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses]
1030 | if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
| ^~~~~~~~~~~~~
include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
58 | #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
| ^~~~
drivers/nvme/host/core.c:1030:9: note: in expansion of macro 'if'
1030 | if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
| ^~
>> drivers/nvme/host/core.c:1030:13: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses]
1030 | if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
| ^~~~~~~~~~~~~
include/linux/compiler.h:58:61: note: in definition of macro '__trace_if_var'
58 | #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
| ^~~~
drivers/nvme/host/core.c:1030:9: note: in expansion of macro 'if'
1030 | if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
| ^~
>> drivers/nvme/host/core.c:1030:13: warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses]
1030 | if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
| ^~~~~~~~~~~~~
include/linux/compiler.h:69:10: note: in definition of macro '__trace_if_value'
69 | (cond) ? \
| ^~~~
include/linux/compiler.h:56:28: note: in expansion of macro '__trace_if_var'
56 | #define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
| ^~~~~~~~~~~~~~
drivers/nvme/host/core.c:1030:9: note: in expansion of macro 'if'
1030 | if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
| ^~
In file included from include/linux/perf_event.h:25,
from include/linux/trace_events.h:10,
from include/trace/trace_events.h:21,
from include/trace/define_trace.h:102,
from drivers/nvme/host/trace.h:175,
from drivers/nvme/host/core.c:28:
At top level:
arch/arc/include/asm/perf_event.h:126:27: warning: 'arc_pmu_cache_map' defined but not used [-Wunused-const-variable=]
126 | static const unsigned int arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
| ^~~~~~~~~~~~~~~~~
arch/arc/include/asm/perf_event.h:91:27: warning: 'arc_pmu_ev_hw_map' defined but not used [-Wunused-const-variable=]
91 | static const char * const arc_pmu_ev_hw_map[] = {
| ^~~~~~~~~~~~~~~~~


vim +1030 drivers/nvme/host/core.c

977
978 blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
979 {
980 struct nvme_command *cmd = nvme_req(req)->cmd;
981 struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
982 blk_status_t ret = BLK_STS_OK;
983
984 if (!(req->rq_flags & RQF_DONTPREP)) {
985 nvme_clear_nvme_request(req);
986 memset(cmd, 0, sizeof(*cmd));
987 }
988
989 switch (req_op(req)) {
990 case REQ_OP_DRV_IN:
991 case REQ_OP_DRV_OUT:
992 /* these are setup prior to execution in nvme_init_request() */
993 break;
994 case REQ_OP_FLUSH:
995 nvme_setup_flush(ns, cmd);
996 break;
997 case REQ_OP_ZONE_RESET_ALL:
998 case REQ_OP_ZONE_RESET:
999 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_RESET);
1000 break;
1001 case REQ_OP_ZONE_OPEN:
1002 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_OPEN);
1003 break;
1004 case REQ_OP_ZONE_CLOSE:
1005 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_CLOSE);
1006 break;
1007 case REQ_OP_ZONE_FINISH:
1008 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_FINISH);
1009 break;
1010 case REQ_OP_WRITE_ZEROES:
1011 ret = nvme_setup_write_zeroes(ns, req, cmd);
1012 break;
1013 case REQ_OP_DISCARD:
1014 ret = nvme_setup_discard(ns, req, cmd);
1015 break;
1016 case REQ_OP_READ:
1017 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_read);
1018 break;
1019 case REQ_OP_WRITE:
1020 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_write);
1021 break;
1022 case REQ_OP_ZONE_APPEND:
1023 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_zone_append);
1024 break;
1025 default:
1026 WARN_ON_ONCE(1);
1027 return BLK_STS_IOERR;
1028 }
1029
> 1030 if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
1031 nvme_req(req)->genctr++;
1032 cmd->common.command_id = nvme_cid(req);
1033 trace_nvme_setup_cmd(req, cmd);
1034 return ret;
1035 }
1036 EXPORT_SYMBOL_GPL(nvme_setup_cmd);
1037

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (7.08 kB)
.config.gz (34.25 kB)
Download all attachments

2021-09-29 15:22:09

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] nvme: add command id quirk for apple controllers

Hi Keith,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.15-rc3 next-20210922]
[cannot apply to hch-configfs/for-next linux-nvme/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Keith-Busch/nvme-add-command-id-quirk-for-apple-controllers/20210929-191053
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a4e6f95a891ac08bd09d62e3e6dae239b150f4c1
config: riscv-buildonly-randconfig-r003-20210929 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project dc6e8dfdfe7efecfda318d43a06fae18b40eb498)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install riscv cross compiling tool for clang build
# apt-get install binutils-riscv64-linux-gnu
# https://github.com/0day-ci/linux/commit/c62c81f7de2ecd19bd3f85afe63d0040401bce0c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Keith-Busch/nvme-add-command-id-quirk-for-apple-controllers/20210929-191053
git checkout c62c81f7de2ecd19bd3f85afe63d0040401bce0c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=riscv

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

>> drivers/nvme/host/core.c:1030:6: error: logical not is only applied to the left hand side of this bitwise operator [-Werror,-Wlogical-not-parentheses]
if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
^ ~
drivers/nvme/host/core.c:1030:6: note: add parentheses after the '!' to evaluate the bitwise operator first
if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
^
( )
drivers/nvme/host/core.c:1030:6: note: add parentheses around left hand side expression to silence this warning
if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
^
( )
1 error generated.


vim +1030 drivers/nvme/host/core.c

977
978 blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
979 {
980 struct nvme_command *cmd = nvme_req(req)->cmd;
981 struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
982 blk_status_t ret = BLK_STS_OK;
983
984 if (!(req->rq_flags & RQF_DONTPREP)) {
985 nvme_clear_nvme_request(req);
986 memset(cmd, 0, sizeof(*cmd));
987 }
988
989 switch (req_op(req)) {
990 case REQ_OP_DRV_IN:
991 case REQ_OP_DRV_OUT:
992 /* these are setup prior to execution in nvme_init_request() */
993 break;
994 case REQ_OP_FLUSH:
995 nvme_setup_flush(ns, cmd);
996 break;
997 case REQ_OP_ZONE_RESET_ALL:
998 case REQ_OP_ZONE_RESET:
999 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_RESET);
1000 break;
1001 case REQ_OP_ZONE_OPEN:
1002 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_OPEN);
1003 break;
1004 case REQ_OP_ZONE_CLOSE:
1005 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_CLOSE);
1006 break;
1007 case REQ_OP_ZONE_FINISH:
1008 ret = nvme_setup_zone_mgmt_send(ns, req, cmd, NVME_ZONE_FINISH);
1009 break;
1010 case REQ_OP_WRITE_ZEROES:
1011 ret = nvme_setup_write_zeroes(ns, req, cmd);
1012 break;
1013 case REQ_OP_DISCARD:
1014 ret = nvme_setup_discard(ns, req, cmd);
1015 break;
1016 case REQ_OP_READ:
1017 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_read);
1018 break;
1019 case REQ_OP_WRITE:
1020 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_write);
1021 break;
1022 case REQ_OP_ZONE_APPEND:
1023 ret = nvme_setup_rw(ns, req, cmd, nvme_cmd_zone_append);
1024 break;
1025 default:
1026 WARN_ON_ONCE(1);
1027 return BLK_STS_IOERR;
1028 }
1029
> 1030 if (!ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN)
1031 nvme_req(req)->genctr++;
1032 cmd->common.command_id = nvme_cid(req);
1033 trace_nvme_setup_cmd(req, cmd);
1034 return ret;
1035 }
1036 EXPORT_SYMBOL_GPL(nvme_setup_cmd);
1037

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (4.64 kB)
.config.gz (37.80 kB)
Download all attachments