* Espen Skoglund <espen.skoglund@netronome.com>
* Francois H. Theron <francois.theron@netronome.com>
*/
+
+#include <asm/unaligned.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
int __nfp_rtsym_read(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
u8 action, u8 token, u64 off, void *buf, size_t len)
{
+ u64 sym_size = nfp_rtsym_size(sym);
u32 cpp_id;
u64 addr;
int err;
+ if (off > sym_size) {
+ nfp_err(cpp, "rtsym '%s': read out of bounds: off: %lld + len: %zd > size: %lld\n",
+ sym->name, off, len, sym_size);
+ return -ENXIO;
+ }
+ len = min_t(size_t, len, sym_size - off);
+
if (sym->type == NFP_RTSYM_TYPE_ABS) {
- __le64 tmp = cpu_to_le64(sym->addr);
+ u8 tmp[8];
- len = min(len, sizeof(tmp));
- memcpy(buf, &tmp, len);
+ put_unaligned_le64(sym->addr, tmp);
+ memcpy(buf, &tmp[off], len);
return len;
}
u64 addr;
int err;
+ if (off + 4 > nfp_rtsym_size(sym)) {
+ nfp_err(cpp, "rtsym '%s': readl out of bounds: off: %lld + 4 > size: %lld\n",
+ sym->name, off, nfp_rtsym_size(sym));
+ return -ENXIO;
+ }
+
err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
if (err)
return err;
u64 addr;
int err;
+ if (off + 8 > nfp_rtsym_size(sym)) {
+ nfp_err(cpp, "rtsym '%s': readq out of bounds: off: %lld + 8 > size: %lld\n",
+ sym->name, off, nfp_rtsym_size(sym));
+ return -ENXIO;
+ }
+
if (sym->type == NFP_RTSYM_TYPE_ABS) {
*value = sym->addr;
return 0;
int __nfp_rtsym_write(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
u8 action, u8 token, u64 off, void *buf, size_t len)
{
+ u64 sym_size = nfp_rtsym_size(sym);
u32 cpp_id;
u64 addr;
int err;
+ if (off > sym_size) {
+ nfp_err(cpp, "rtsym '%s': write out of bounds: off: %lld + len: %zd > size: %lld\n",
+ sym->name, off, len, sym_size);
+ return -ENXIO;
+ }
+ len = min_t(size_t, len, sym_size - off);
+
err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
if (err)
return err;
u64 addr;
int err;
+ if (off + 4 > nfp_rtsym_size(sym)) {
+ nfp_err(cpp, "rtsym '%s': writel out of bounds: off: %lld + 4 > size: %lld\n",
+ sym->name, off, nfp_rtsym_size(sym));
+ return -ENXIO;
+ }
+
err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
if (err)
return err;
u64 addr;
int err;
+ if (off + 8 > nfp_rtsym_size(sym)) {
+ nfp_err(cpp, "rtsym '%s': writeq out of bounds: off: %lld + 8 > size: %lld\n",
+ sym->name, off, nfp_rtsym_size(sym));
+ return -ENXIO;
+ }
+
err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
if (err)
return err;