mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 14:24:11 +08:00
cxlflash: Fix AFU version access/storage and add check
The AFU version is stored as a non-terminated string of bytes within a 64-bit little-endian register. Presently the value is read directly (no MMIO accessor) and is stored in a buffer that is not big enough to contain a NULL terminator. Additionally the version obtained is not evaluated against a known value to prevent usage with unsupported AFUs. All of these deficiencies can lead to a variety of problems. To remedy, use the correct MMIO accessor to read the version value into a null-terminated buffer and add a check to prevent an incompatible AFU from being used with this driver. Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com> Signed-off-by: Manoj N. Kumar <manoj@linux.vnet.ibm.com> Reviewed-by: Brian King <brking@linux.vnet.ibm.com> Reviewed-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
This commit is contained in:
parent
964497b3bf
commit
e5ce067b7b
@ -179,7 +179,7 @@ struct afu {
|
||||
u32 cmd_couts; /* Number of command checkouts */
|
||||
u32 internal_lun; /* User-desired LUN mode for this AFU */
|
||||
|
||||
char version[8];
|
||||
char version[16];
|
||||
u64 interface_version;
|
||||
|
||||
struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */
|
||||
|
@ -1751,14 +1751,20 @@ static int init_afu(struct cxlflash_cfg *cfg)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
/* don't byte reverse on reading afu_version, else the string form */
|
||||
/* will be backwards */
|
||||
reg = afu->afu_map->global.regs.afu_version;
|
||||
memcpy(afu->version, ®, 8);
|
||||
/* No byte reverse on reading afu_version or string will be backwards */
|
||||
reg = readq(&afu->afu_map->global.regs.afu_version);
|
||||
memcpy(afu->version, ®, sizeof(reg));
|
||||
afu->interface_version =
|
||||
readq_be(&afu->afu_map->global.regs.interface_version);
|
||||
pr_debug("%s: afu version %s, interface version 0x%llX\n",
|
||||
__func__, afu->version, afu->interface_version);
|
||||
if ((afu->interface_version + 1) == 0) {
|
||||
pr_err("Back level AFU, please upgrade. AFU version %s "
|
||||
"interface version 0x%llx\n", afu->version,
|
||||
afu->interface_version);
|
||||
rc = -EINVAL;
|
||||
goto err1;
|
||||
} else
|
||||
pr_debug("%s: afu version %s, interface version 0x%llX\n",
|
||||
__func__, afu->version, afu->interface_version);
|
||||
|
||||
rc = start_afu(cfg);
|
||||
if (rc) {
|
||||
|
@ -340,7 +340,7 @@ struct sisl_global_regs {
|
||||
#define SISL_AFUCONF_MBOX_CLR_READ 0x0010ULL
|
||||
__be64 afu_config;
|
||||
__be64 rsvd[0xf8];
|
||||
__be64 afu_version;
|
||||
__le64 afu_version;
|
||||
__be64 interface_version;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user