Message ID | 20211027103352.8879-3-sshivamurthy@micron.com |
---|---|
State | Changes Requested |
Delegated to: | Ambarus Tudor |
Headers | show |
Series | enabling Advanced protection and security features | expand |
Hi, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on mtd/mtd/next] [also build test WARNING on mtd/mtd/fixes v5.15-rc7 next-20211027] [cannot apply to mtd/spi-nor/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/shiva-linuxworks-gmail-com/enabling-Advanced-protection-and-security-features/20211027-183458 base: https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next config: arc-randconfig-r043-20211027 (attached as .config) compiler: arc-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/d26eac1611c4409954b4d0c44215e1a53aa7605a git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review shiva-linuxworks-gmail-com/enabling-Advanced-protection-and-security-features/20211027-183458 git checkout d26eac1611c4409954b4d0c44215e1a53aa7605a # 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 <lkp@intel.com> All warnings (new ones prefixed by >>): >> drivers/mtd/spi-nor/advprotsec.c:192:6: warning: no previous prototype for 'spi_nor_register_security_ops' [-Wmissing-prototypes] 192 | void spi_nor_register_security_ops(struct spi_nor *nor) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/spi_nor_register_security_ops +192 drivers/mtd/spi-nor/advprotsec.c 191 > 192 void spi_nor_register_security_ops(struct spi_nor *nor) --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi, Thank you for the patch! Yet something to improve: [auto build test ERROR on mtd/mtd/next] [also build test ERROR on mtd/mtd/fixes v5.15-rc7 next-20211027] [cannot apply to mtd/spi-nor/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/shiva-linuxworks-gmail-com/enabling-Advanced-protection-and-security-features/20211027-183458 base: https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next config: i386-randconfig-a002-20211027 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 5db7568a6a1fcb408eb8988abdaff2a225a8eb72) 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/d26eac1611c4409954b4d0c44215e1a53aa7605a git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review shiva-linuxworks-gmail-com/enabling-Advanced-protection-and-security-features/20211027-183458 git checkout d26eac1611c4409954b4d0c44215e1a53aa7605a # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All error/warnings (new ones prefixed by >>): >> drivers/mtd/spi-nor/core.c:3202:2: error: implicit declaration of function 'spi_nor_register_security_ops' [-Werror,-Wimplicit-function-declaration] spi_nor_register_security_ops(nor); ^ drivers/mtd/spi-nor/core.c:3202:2: note: did you mean 'spi_nor_register_locking_ops'? drivers/mtd/spi-nor/core.h:572:6: note: 'spi_nor_register_locking_ops' declared here void spi_nor_register_locking_ops(struct spi_nor *nor); ^ 1 error generated. -- >> drivers/mtd/spi-nor/advprotsec.c:192:6: warning: no previous prototype for function 'spi_nor_register_security_ops' [-Wmissing-prototypes] void spi_nor_register_security_ops(struct spi_nor *nor) ^ drivers/mtd/spi-nor/advprotsec.c:192:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void spi_nor_register_security_ops(struct spi_nor *nor) ^ static 1 warning generated. vim +/spi_nor_register_security_ops +3202 drivers/mtd/spi-nor/core.c 3073 3074 int spi_nor_scan(struct spi_nor *nor, const char *name, 3075 const struct spi_nor_hwcaps *hwcaps) 3076 { 3077 const struct flash_info *info; 3078 struct device *dev = nor->dev; 3079 struct mtd_info *mtd = &nor->mtd; 3080 struct device_node *np = spi_nor_get_flash_node(nor); 3081 int ret; 3082 int i; 3083 3084 ret = spi_nor_check(nor); 3085 if (ret) 3086 return ret; 3087 3088 /* Reset SPI protocol for all commands. */ 3089 nor->reg_proto = SNOR_PROTO_1_1_1; 3090 nor->read_proto = SNOR_PROTO_1_1_1; 3091 nor->write_proto = SNOR_PROTO_1_1_1; 3092 3093 /* 3094 * We need the bounce buffer early to read/write registers when going 3095 * through the spi-mem layer (buffers have to be DMA-able). 3096 * For spi-mem drivers, we'll reallocate a new buffer if 3097 * nor->page_size turns out to be greater than PAGE_SIZE (which 3098 * shouldn't happen before long since NOR pages are usually less 3099 * than 1KB) after spi_nor_scan() returns. 3100 */ 3101 nor->bouncebuf_size = PAGE_SIZE; 3102 nor->bouncebuf = devm_kmalloc(dev, nor->bouncebuf_size, 3103 GFP_KERNEL); 3104 if (!nor->bouncebuf) 3105 return -ENOMEM; 3106 3107 info = spi_nor_get_flash_info(nor, name); 3108 if (IS_ERR(info)) 3109 return PTR_ERR(info); 3110 3111 nor->info = info; 3112 3113 spi_nor_debugfs_init(nor, info); 3114 3115 mutex_init(&nor->lock); 3116 3117 /* 3118 * Make sure the XSR_RDY flag is set before calling 3119 * spi_nor_wait_till_ready(). Xilinx S3AN share MFR 3120 * with Atmel SPI NOR. 3121 */ 3122 if (info->flags & SPI_NOR_XSR_RDY) 3123 nor->flags |= SNOR_F_READY_XSR_RDY; 3124 3125 if (info->flags & SPI_NOR_HAS_LOCK) 3126 nor->flags |= SNOR_F_HAS_LOCK; 3127 3128 mtd->_write = spi_nor_write; 3129 3130 /* Init flash parameters based on flash_info struct and SFDP */ 3131 ret = spi_nor_init_params(nor); 3132 if (ret) 3133 return ret; 3134 3135 if (!mtd->name) 3136 mtd->name = dev_name(dev); 3137 mtd->priv = nor; 3138 mtd->type = MTD_NORFLASH; 3139 mtd->writesize = nor->params->writesize; 3140 mtd->flags = MTD_CAP_NORFLASH; 3141 mtd->size = nor->params->size; 3142 mtd->_erase = spi_nor_erase; 3143 mtd->_read = spi_nor_read; 3144 mtd->_suspend = spi_nor_suspend; 3145 mtd->_resume = spi_nor_resume; 3146 mtd->_get_device = spi_nor_get_device; 3147 mtd->_put_device = spi_nor_put_device; 3148 3149 if (info->flags & USE_FSR) 3150 nor->flags |= SNOR_F_USE_FSR; 3151 if (info->flags & SPI_NOR_HAS_TB) { 3152 nor->flags |= SNOR_F_HAS_SR_TB; 3153 if (info->flags & SPI_NOR_TB_SR_BIT6) 3154 nor->flags |= SNOR_F_HAS_SR_TB_BIT6; 3155 } 3156 3157 if (info->flags & NO_CHIP_ERASE) 3158 nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; 3159 if (info->flags & USE_CLSR) 3160 nor->flags |= SNOR_F_USE_CLSR; 3161 if (info->flags & SPI_NOR_SWP_IS_VOLATILE) 3162 nor->flags |= SNOR_F_SWP_IS_VOLATILE; 3163 3164 if (info->flags & SPI_NOR_4BIT_BP) { 3165 nor->flags |= SNOR_F_HAS_4BIT_BP; 3166 if (info->flags & SPI_NOR_BP3_SR_BIT6) 3167 nor->flags |= SNOR_F_HAS_SR_BP3_BIT6; 3168 } 3169 3170 if (info->flags & SPI_NOR_NO_ERASE) 3171 mtd->flags |= MTD_NO_ERASE; 3172 3173 mtd->dev.parent = dev; 3174 nor->page_size = nor->params->page_size; 3175 mtd->writebufsize = nor->page_size; 3176 3177 if (of_property_read_bool(np, "broken-flash-reset")) 3178 nor->flags |= SNOR_F_BROKEN_RESET; 3179 3180 /* 3181 * Configure the SPI memory: 3182 * - select op codes for (Fast) Read, Page Program and Sector Erase. 3183 * - set the number of dummy cycles (mode cycles + wait states). 3184 * - set the SPI protocols for register and memory accesses. 3185 */ 3186 ret = spi_nor_setup(nor, hwcaps); 3187 if (ret) 3188 return ret; 3189 3190 if (info->flags & SPI_NOR_4B_OPCODES) 3191 nor->flags |= SNOR_F_4B_OPCODES; 3192 3193 if (info->flags & SPI_NOR_IO_MODE_EN_VOLATILE) 3194 nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE; 3195 3196 ret = spi_nor_set_addr_width(nor); 3197 if (ret) 3198 return ret; 3199 3200 spi_nor_register_locking_ops(nor); 3201 > 3202 spi_nor_register_security_ops(nor); 3203 3204 /* Send all the required SPI flash commands to initialize device */ 3205 ret = spi_nor_init(nor); 3206 if (ret) 3207 return ret; 3208 3209 /* Configure OTP parameters and ops */ 3210 spi_nor_otp_init(nor); 3211 3212 dev_info(dev, "%s (%lld Kbytes)\n", info->name, 3213 (long long)mtd->size >> 10); 3214 3215 dev_dbg(dev, 3216 "mtd .name = %s, .size = 0x%llx (%lldMiB), " 3217 ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", 3218 mtd->name, (long long)mtd->size, (long long)(mtd->size >> 20), 3219 mtd->erasesize, mtd->erasesize / 1024, mtd->numeraseregions); 3220 3221 if (mtd->numeraseregions) 3222 for (i = 0; i < mtd->numeraseregions; i++) 3223 dev_dbg(dev, 3224 "mtd.eraseregions[%d] = { .offset = 0x%llx, " 3225 ".erasesize = 0x%.8x (%uKiB), " 3226 ".numblocks = %d }\n", 3227 i, (long long)mtd->eraseregions[i].offset, 3228 mtd->eraseregions[i].erasesize, 3229 mtd->eraseregions[i].erasesize / 1024, 3230 mtd->eraseregions[i].numblocks); 3231 return 0; 3232 } 3233 EXPORT_SYMBOL_GPL(spi_nor_scan); 3234 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi, Thank you for the patch! Yet something to improve: [auto build test ERROR on mtd/mtd/next] [also build test ERROR on mtd/mtd/fixes v5.15-rc7 next-20211027] [cannot apply to mtd/spi-nor/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/shiva-linuxworks-gmail-com/enabling-Advanced-protection-and-security-features/20211027-183458 base: https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next config: i386-buildonly-randconfig-r005-20211027 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 5db7568a6a1fcb408eb8988abdaff2a225a8eb72) 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/d26eac1611c4409954b4d0c44215e1a53aa7605a git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review shiva-linuxworks-gmail-com/enabling-Advanced-protection-and-security-features/20211027-183458 git checkout d26eac1611c4409954b4d0c44215e1a53aa7605a # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> drivers/mtd/spi-nor/core.c:3202:2: error: implicit declaration of function 'spi_nor_register_security_ops' [-Werror,-Wimplicit-function-declaration] spi_nor_register_security_ops(nor); ^ drivers/mtd/spi-nor/core.c:3202:2: note: did you mean 'spi_nor_register_locking_ops'? drivers/mtd/spi-nor/core.h:572:6: note: 'spi_nor_register_locking_ops' declared here void spi_nor_register_locking_ops(struct spi_nor *nor); ^ 1 error generated. -- >> drivers/mtd/spi-nor/advprotsec.c:192:6: error: no previous prototype for function 'spi_nor_register_security_ops' [-Werror,-Wmissing-prototypes] void spi_nor_register_security_ops(struct spi_nor *nor) ^ drivers/mtd/spi-nor/advprotsec.c:192:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void spi_nor_register_security_ops(struct spi_nor *nor) ^ static 1 error generated. vim +/spi_nor_register_security_ops +3202 drivers/mtd/spi-nor/core.c 3073 3074 int spi_nor_scan(struct spi_nor *nor, const char *name, 3075 const struct spi_nor_hwcaps *hwcaps) 3076 { 3077 const struct flash_info *info; 3078 struct device *dev = nor->dev; 3079 struct mtd_info *mtd = &nor->mtd; 3080 struct device_node *np = spi_nor_get_flash_node(nor); 3081 int ret; 3082 int i; 3083 3084 ret = spi_nor_check(nor); 3085 if (ret) 3086 return ret; 3087 3088 /* Reset SPI protocol for all commands. */ 3089 nor->reg_proto = SNOR_PROTO_1_1_1; 3090 nor->read_proto = SNOR_PROTO_1_1_1; 3091 nor->write_proto = SNOR_PROTO_1_1_1; 3092 3093 /* 3094 * We need the bounce buffer early to read/write registers when going 3095 * through the spi-mem layer (buffers have to be DMA-able). 3096 * For spi-mem drivers, we'll reallocate a new buffer if 3097 * nor->page_size turns out to be greater than PAGE_SIZE (which 3098 * shouldn't happen before long since NOR pages are usually less 3099 * than 1KB) after spi_nor_scan() returns. 3100 */ 3101 nor->bouncebuf_size = PAGE_SIZE; 3102 nor->bouncebuf = devm_kmalloc(dev, nor->bouncebuf_size, 3103 GFP_KERNEL); 3104 if (!nor->bouncebuf) 3105 return -ENOMEM; 3106 3107 info = spi_nor_get_flash_info(nor, name); 3108 if (IS_ERR(info)) 3109 return PTR_ERR(info); 3110 3111 nor->info = info; 3112 3113 spi_nor_debugfs_init(nor, info); 3114 3115 mutex_init(&nor->lock); 3116 3117 /* 3118 * Make sure the XSR_RDY flag is set before calling 3119 * spi_nor_wait_till_ready(). Xilinx S3AN share MFR 3120 * with Atmel SPI NOR. 3121 */ 3122 if (info->flags & SPI_NOR_XSR_RDY) 3123 nor->flags |= SNOR_F_READY_XSR_RDY; 3124 3125 if (info->flags & SPI_NOR_HAS_LOCK) 3126 nor->flags |= SNOR_F_HAS_LOCK; 3127 3128 mtd->_write = spi_nor_write; 3129 3130 /* Init flash parameters based on flash_info struct and SFDP */ 3131 ret = spi_nor_init_params(nor); 3132 if (ret) 3133 return ret; 3134 3135 if (!mtd->name) 3136 mtd->name = dev_name(dev); 3137 mtd->priv = nor; 3138 mtd->type = MTD_NORFLASH; 3139 mtd->writesize = nor->params->writesize; 3140 mtd->flags = MTD_CAP_NORFLASH; 3141 mtd->size = nor->params->size; 3142 mtd->_erase = spi_nor_erase; 3143 mtd->_read = spi_nor_read; 3144 mtd->_suspend = spi_nor_suspend; 3145 mtd->_resume = spi_nor_resume; 3146 mtd->_get_device = spi_nor_get_device; 3147 mtd->_put_device = spi_nor_put_device; 3148 3149 if (info->flags & USE_FSR) 3150 nor->flags |= SNOR_F_USE_FSR; 3151 if (info->flags & SPI_NOR_HAS_TB) { 3152 nor->flags |= SNOR_F_HAS_SR_TB; 3153 if (info->flags & SPI_NOR_TB_SR_BIT6) 3154 nor->flags |= SNOR_F_HAS_SR_TB_BIT6; 3155 } 3156 3157 if (info->flags & NO_CHIP_ERASE) 3158 nor->flags |= SNOR_F_NO_OP_CHIP_ERASE; 3159 if (info->flags & USE_CLSR) 3160 nor->flags |= SNOR_F_USE_CLSR; 3161 if (info->flags & SPI_NOR_SWP_IS_VOLATILE) 3162 nor->flags |= SNOR_F_SWP_IS_VOLATILE; 3163 3164 if (info->flags & SPI_NOR_4BIT_BP) { 3165 nor->flags |= SNOR_F_HAS_4BIT_BP; 3166 if (info->flags & SPI_NOR_BP3_SR_BIT6) 3167 nor->flags |= SNOR_F_HAS_SR_BP3_BIT6; 3168 } 3169 3170 if (info->flags & SPI_NOR_NO_ERASE) 3171 mtd->flags |= MTD_NO_ERASE; 3172 3173 mtd->dev.parent = dev; 3174 nor->page_size = nor->params->page_size; 3175 mtd->writebufsize = nor->page_size; 3176 3177 if (of_property_read_bool(np, "broken-flash-reset")) 3178 nor->flags |= SNOR_F_BROKEN_RESET; 3179 3180 /* 3181 * Configure the SPI memory: 3182 * - select op codes for (Fast) Read, Page Program and Sector Erase. 3183 * - set the number of dummy cycles (mode cycles + wait states). 3184 * - set the SPI protocols for register and memory accesses. 3185 */ 3186 ret = spi_nor_setup(nor, hwcaps); 3187 if (ret) 3188 return ret; 3189 3190 if (info->flags & SPI_NOR_4B_OPCODES) 3191 nor->flags |= SNOR_F_4B_OPCODES; 3192 3193 if (info->flags & SPI_NOR_IO_MODE_EN_VOLATILE) 3194 nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE; 3195 3196 ret = spi_nor_set_addr_width(nor); 3197 if (ret) 3198 return ret; 3199 3200 spi_nor_register_locking_ops(nor); 3201 > 3202 spi_nor_register_security_ops(nor); 3203 3204 /* Send all the required SPI flash commands to initialize device */ 3205 ret = spi_nor_init(nor); 3206 if (ret) 3207 return ret; 3208 3209 /* Configure OTP parameters and ops */ 3210 spi_nor_otp_init(nor); 3211 3212 dev_info(dev, "%s (%lld Kbytes)\n", info->name, 3213 (long long)mtd->size >> 10); 3214 3215 dev_dbg(dev, 3216 "mtd .name = %s, .size = 0x%llx (%lldMiB), " 3217 ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", 3218 mtd->name, (long long)mtd->size, (long long)(mtd->size >> 20), 3219 mtd->erasesize, mtd->erasesize / 1024, mtd->numeraseregions); 3220 3221 if (mtd->numeraseregions) 3222 for (i = 0; i < mtd->numeraseregions; i++) 3223 dev_dbg(dev, 3224 "mtd.eraseregions[%d] = { .offset = 0x%llx, " 3225 ".erasesize = 0x%.8x (%uKiB), " 3226 ".numblocks = %d }\n", 3227 i, (long long)mtd->eraseregions[i].offset, 3228 mtd->eraseregions[i].erasesize, 3229 mtd->eraseregions[i].erasesize / 1024, 3230 mtd->eraseregions[i].numblocks); 3231 return 0; 3232 } 3233 EXPORT_SYMBOL_GPL(spi_nor_scan); 3234 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On 27/10/2021 11:33, shiva.linuxworks@gmail.com wrote: > From: Shivamurthy Shastri <sshivamurthy@micron.com> > > Added functionalities to support advanced securtiy and protection > features in new SPI NOR flashes. > > Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com> > --- > drivers/mtd/spi-nor/Makefile | 2 +- > drivers/mtd/spi-nor/advprotsec.c | 209 +++++++++++++++++++++++++++++++ > drivers/mtd/spi-nor/core.c | 2 + > include/linux/mtd/mtd.h | 19 +++ > 4 files changed, 231 insertions(+), 1 deletion(-) > create mode 100644 drivers/mtd/spi-nor/advprotsec.c The changes to drivers/mtd/spi-nor/core.h in patch 1 of this series can be merged into this patch, with the series re-ordered so this patch is first. > > diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile > index 6b904e439372..8e96e2c65c7a 100644 > --- a/drivers/mtd/spi-nor/Makefile > +++ b/drivers/mtd/spi-nor/Makefile > @@ -1,6 +1,6 @@ > # SPDX-License-Identifier: GPL-2.0 > > -spi-nor-objs := core.o sfdp.o swp.o otp.o sysfs.o > +spi-nor-objs := core.o sfdp.o swp.o otp.o advprotsec.o sysfs.o > spi-nor-objs += atmel.o > spi-nor-objs += catalyst.o > spi-nor-objs += eon.o > diff --git a/drivers/mtd/spi-nor/advprotsec.c b/drivers/mtd/spi-nor/advprotsec.c > new file mode 100644 > index 000000000000..4dc8e67b16ef > --- /dev/null > +++ b/drivers/mtd/spi-nor/advprotsec.c > @@ -0,0 +1,209 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * SPI NOR Advanced Sector Protection and Security Features > + * > + * Copyright (C) 2021 Micron Technology, Inc. > + */ > + > +#include <linux/mtd/mtd.h> > +#include <linux/mtd/spi-nor.h> > + > +#include "core.h" > + > +static int spi_nor_secure_read(struct mtd_info *mtd, size_t len, u8 *buf) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->secure_read(nor, len, buf); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_secure_write(struct mtd_info *mtd, size_t len, u8 *buf) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->secure_write(nor, len, buf); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_read_vlock_bits(struct mtd_info *mtd, u32 addr, size_t len, > + u8 *buf) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->read_vlock_bits(nor, addr, len, buf); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_write_vlock_bits(struct mtd_info *mtd, u32 addr, size_t len, > + u8 *buf) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = spi_nor_write_enable(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->write_vlock_bits(nor, addr, len, buf); > + if (ret) > + return ret; > + > + ret = spi_nor_write_disable(nor); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_read_nvlock_bits(struct mtd_info *mtd, u32 addr, size_t len, > + u8 *buf) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->read_nvlock_bits(nor, addr, len, buf); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_write_nvlock_bits(struct mtd_info *mtd, u32 addr) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = spi_nor_write_enable(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->write_nvlock_bits(nor, addr); > + if (ret) > + return ret; > + > + ret = spi_nor_write_disable(nor); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_erase_nvlock_bits(struct mtd_info *mtd) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = spi_nor_write_enable(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->erase_nvlock_bits(nor); > + if (ret) > + return ret; > + > + ret = spi_nor_write_disable(nor); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_read_global_freeze_bits(struct mtd_info *mtd, size_t len, > + u8 *buf) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->read_global_freeze_bits(nor, len, buf); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_write_global_freeze_bits(struct mtd_info *mtd, size_t len, > + u8 *buf) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->write_global_freeze_bits(nor, len, buf); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +static int spi_nor_read_password(struct mtd_info *mtd, size_t len, u8 *buf) > +{ > + struct spi_nor *nor = mtd_to_spi_nor(mtd); > + int ret; > + > + ret = spi_nor_lock_and_prep(nor); > + if (ret) > + return ret; > + > + ret = nor->params->sec_ops->read_password(nor, len, buf); > + > + spi_nor_unlock_and_unprep(nor); > + return ret; > +} > + > +void spi_nor_register_security_ops(struct spi_nor *nor) > +{ > + struct mtd_info *mtd = &nor->mtd; > + > + if (!nor->params->sec_ops) > + return; > + > + mtd->_secure_packet_read = spi_nor_secure_read; > + mtd->_secure_packet_write = spi_nor_secure_write; > + mtd->_read_vlock_bits = spi_nor_read_vlock_bits; > + mtd->_write_vlock_bits = spi_nor_write_vlock_bits; > + mtd->_read_nvlock_bits = spi_nor_read_nvlock_bits; > + mtd->_write_nvlock_bits = spi_nor_write_nvlock_bits; > + mtd->_erase_nvlock_bits = spi_nor_erase_nvlock_bits; > + mtd->_read_global_freeze_bits = spi_nor_read_global_freeze_bits; > + mtd->_write_global_freeze_bits = spi_nor_write_global_freeze_bits; > + mtd->_read_password = spi_nor_read_password; This approach requires all or none of the sec_ops functions to be implemented. It doesn't consider other drivers which may be able to implement a subset of the sec_ops functions. I also think it would be better not to use extra function pointers here and just let other code call the functions defined above directly. The caller of these functions will need to check that the pointers aren't NULL before calling them anyway, so I think we may as well call the functions directly and have each of them check that the corresponding sec_ops field is non-NULL before calling it. > +} > diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c > index cc08bd707378..864f3c7783b3 100644 > --- a/drivers/mtd/spi-nor/core.c > +++ b/drivers/mtd/spi-nor/core.c > @@ -3199,6 +3199,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, > > spi_nor_register_locking_ops(nor); > > + spi_nor_register_security_ops(nor); > + > /* Send all the required SPI flash commands to initialize device */ > ret = spi_nor_init(nor); > if (ret) > diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h > index 88227044fc86..bce358c9fb94 100644 > --- a/include/linux/mtd/mtd.h > +++ b/include/linux/mtd/mtd.h > @@ -360,6 +360,25 @@ struct mtd_info { > int (*_get_device) (struct mtd_info *mtd); > void (*_put_device) (struct mtd_info *mtd); > > + /* > + * Security Operations > + */ > + int (*_secure_packet_read)(struct mtd_info *mtd, size_t len, u8 *buf); > + int (*_secure_packet_write)(struct mtd_info *mtd, size_t len, u8 *buf); > + int (*_read_vlock_bits)(struct mtd_info *mtd, u32 addr, size_t len, > + u8 *buf); > + int (*_write_vlock_bits)(struct mtd_info *mtd, u32 addr, size_t len, > + u8 *buf); > + int (*_read_nvlock_bits)(struct mtd_info *mtd, u32 addr, size_t len, > + u8 *buf); > + int (*_write_nvlock_bits)(struct mtd_info *mtd, u32 addr); > + int (*_erase_nvlock_bits)(struct mtd_info *mtd); > + int (*_read_global_freeze_bits)(struct mtd_info *mtd, size_t len, > + u8 *buf); > + int (*_write_global_freeze_bits)(struct mtd_info *mtd, size_t len, > + u8 *buf); > + int (*_read_password)(struct mtd_info *mtd, size_t len, u8 *buf); > + > /* > * flag indicates a panic write, low level drivers can take appropriate > * action if required to ensure writes go through > Thanks,
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index 6b904e439372..8e96e2c65c7a 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -spi-nor-objs := core.o sfdp.o swp.o otp.o sysfs.o +spi-nor-objs := core.o sfdp.o swp.o otp.o advprotsec.o sysfs.o spi-nor-objs += atmel.o spi-nor-objs += catalyst.o spi-nor-objs += eon.o diff --git a/drivers/mtd/spi-nor/advprotsec.c b/drivers/mtd/spi-nor/advprotsec.c new file mode 100644 index 000000000000..4dc8e67b16ef --- /dev/null +++ b/drivers/mtd/spi-nor/advprotsec.c @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SPI NOR Advanced Sector Protection and Security Features + * + * Copyright (C) 2021 Micron Technology, Inc. + */ + +#include <linux/mtd/mtd.h> +#include <linux/mtd/spi-nor.h> + +#include "core.h" + +static int spi_nor_secure_read(struct mtd_info *mtd, size_t len, u8 *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->secure_read(nor, len, buf); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_secure_write(struct mtd_info *mtd, size_t len, u8 *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->secure_write(nor, len, buf); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_read_vlock_bits(struct mtd_info *mtd, u32 addr, size_t len, + u8 *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->read_vlock_bits(nor, addr, len, buf); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_write_vlock_bits(struct mtd_info *mtd, u32 addr, size_t len, + u8 *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = spi_nor_write_enable(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->write_vlock_bits(nor, addr, len, buf); + if (ret) + return ret; + + ret = spi_nor_write_disable(nor); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_read_nvlock_bits(struct mtd_info *mtd, u32 addr, size_t len, + u8 *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->read_nvlock_bits(nor, addr, len, buf); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_write_nvlock_bits(struct mtd_info *mtd, u32 addr) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = spi_nor_write_enable(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->write_nvlock_bits(nor, addr); + if (ret) + return ret; + + ret = spi_nor_write_disable(nor); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_erase_nvlock_bits(struct mtd_info *mtd) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = spi_nor_write_enable(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->erase_nvlock_bits(nor); + if (ret) + return ret; + + ret = spi_nor_write_disable(nor); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_read_global_freeze_bits(struct mtd_info *mtd, size_t len, + u8 *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->read_global_freeze_bits(nor, len, buf); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_write_global_freeze_bits(struct mtd_info *mtd, size_t len, + u8 *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->write_global_freeze_bits(nor, len, buf); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +static int spi_nor_read_password(struct mtd_info *mtd, size_t len, u8 *buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); + int ret; + + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + + ret = nor->params->sec_ops->read_password(nor, len, buf); + + spi_nor_unlock_and_unprep(nor); + return ret; +} + +void spi_nor_register_security_ops(struct spi_nor *nor) +{ + struct mtd_info *mtd = &nor->mtd; + + if (!nor->params->sec_ops) + return; + + mtd->_secure_packet_read = spi_nor_secure_read; + mtd->_secure_packet_write = spi_nor_secure_write; + mtd->_read_vlock_bits = spi_nor_read_vlock_bits; + mtd->_write_vlock_bits = spi_nor_write_vlock_bits; + mtd->_read_nvlock_bits = spi_nor_read_nvlock_bits; + mtd->_write_nvlock_bits = spi_nor_write_nvlock_bits; + mtd->_erase_nvlock_bits = spi_nor_erase_nvlock_bits; + mtd->_read_global_freeze_bits = spi_nor_read_global_freeze_bits; + mtd->_write_global_freeze_bits = spi_nor_write_global_freeze_bits; + mtd->_read_password = spi_nor_read_password; +} diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index cc08bd707378..864f3c7783b3 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -3199,6 +3199,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, spi_nor_register_locking_ops(nor); + spi_nor_register_security_ops(nor); + /* Send all the required SPI flash commands to initialize device */ ret = spi_nor_init(nor); if (ret) diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 88227044fc86..bce358c9fb94 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -360,6 +360,25 @@ struct mtd_info { int (*_get_device) (struct mtd_info *mtd); void (*_put_device) (struct mtd_info *mtd); + /* + * Security Operations + */ + int (*_secure_packet_read)(struct mtd_info *mtd, size_t len, u8 *buf); + int (*_secure_packet_write)(struct mtd_info *mtd, size_t len, u8 *buf); + int (*_read_vlock_bits)(struct mtd_info *mtd, u32 addr, size_t len, + u8 *buf); + int (*_write_vlock_bits)(struct mtd_info *mtd, u32 addr, size_t len, + u8 *buf); + int (*_read_nvlock_bits)(struct mtd_info *mtd, u32 addr, size_t len, + u8 *buf); + int (*_write_nvlock_bits)(struct mtd_info *mtd, u32 addr); + int (*_erase_nvlock_bits)(struct mtd_info *mtd); + int (*_read_global_freeze_bits)(struct mtd_info *mtd, size_t len, + u8 *buf); + int (*_write_global_freeze_bits)(struct mtd_info *mtd, size_t len, + u8 *buf); + int (*_read_password)(struct mtd_info *mtd, size_t len, u8 *buf); + /* * flag indicates a panic write, low level drivers can take appropriate * action if required to ensure writes go through