[bug report] regmap: Support accelerated noinc operations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Linus Walleij,

The patch c20cc099b30a: "regmap: Support accelerated noinc
operations" from Aug 16, 2022, leads to the following Smatch static
checker warning:

	drivers/base/regmap/regmap.c:2202 regmap_noinc_readwrite()
	warn: potential pointer math issue ('u16p' is a 16 bit pointer)

drivers/base/regmap/regmap.c
    2132 static int regmap_noinc_readwrite(struct regmap *map, unsigned int reg,
    2133                                   void *val, unsigned int val_len, bool write)
    2134 {
    2135         size_t val_bytes = map->format.val_bytes;
    2136         size_t val_count = val_len / val_bytes;

val_len is bytes.  val_count is elements.

    2137         unsigned int lastval;
    2138         u8 *u8p;
    2139         u16 *u16p;
    2140         u32 *u32p;
    2141 #ifdef CONFIG_64BIT
    2142         u64 *u64p;
    2143 #endif
    2144         int ret;
    2145         int i;
    2146 
    2147         switch (val_bytes) {
    2148         case 1:
    2149                 u8p = val;
    2150                 if (write)
    2151                         lastval = (unsigned int)u8p[val_count - 1];
    2152                 break;
    2153         case 2:
    2154                 u16p = val;
    2155                 if (write)
    2156                         lastval = (unsigned int)u16p[val_count - 1];
    2157                 break;
    2158         case 4:
    2159                 u32p = val;
    2160                 if (write)
    2161                         lastval = (unsigned int)u32p[val_count - 1];
    2162                 break;
    2163 #ifdef CONFIG_64BIT
    2164         case 8:
    2165                 u64p = val;
    2166                 if (write)
    2167                         lastval = (unsigned int)u64p[val_count - 1];
    2168                 break;
    2169 #endif
    2170         default:
    2171                 return -EINVAL;
    2172         }
    2173 
    2174         /*
    2175          * Update the cache with the last value we write, the rest is just
    2176          * gone down in the hardware FIFO. We can't cache FIFOs. This makes
    2177          * sure a single read from the cache will work.
    2178          */
    2179         if (write) {
    2180                 if (!map->cache_bypass && !map->defer_caching) {
    2181                         ret = regcache_write(map, reg, lastval);
    2182                         if (ret != 0)
    2183                                 return ret;
    2184                         if (map->cache_only) {
    2185                                 map->cache_dirty = true;
    2186                                 return 0;
    2187                         }
    2188                 }
    2189                 ret = map->bus->reg_noinc_write(map->bus_context, reg, val, val_count);
    2190         } else {
    2191                 ret = map->bus->reg_noinc_read(map->bus_context, reg, val, val_count);
    2192         }
    2193 
    2194         if (!ret && regmap_should_log(map)) {
    2195                 dev_info(map->dev, "%x %s [", reg, write ? "<=" : "=>");
    2196                 for (i = 0; i < val_len; i++) {
                                         ^^^^^^^
This should be val_count or it will beyond the end of the arrays.

    2197                         switch (val_bytes) {
    2198                         case 1:
    2199                                 pr_cont("%x", u8p[i]);
    2200                                 break;
    2201                         case 2:
--> 2202                                 pr_cont("%x", u16p[i]);
    2203                                 break;
    2204                         case 4:
    2205                                 pr_cont("%x", u32p[i]);
    2206                                 break;
    2207 #ifdef CONFIG_64BIT
    2208                         case 8:
    2209                                 pr_cont("%llx", u64p[i]);
    2210                                 break;
    2211 #endif
    2212                         default:
    2213                                 break;
    2214                         }
    2215                         if (i == (val_len - 1))
                                           ^^^^^^^
val_count as well probably?

    2216                                 pr_cont("]\n");
    2217                         else
    2218                                 pr_cont(",");
    2219                 }
    2220         }
    2221 
    2222         return 0;
    2223 }

regards,
dan carpenter



[Index of Archives]     [Kernel Development]     [Kernel Announce]     [Kernel Newbies]     [Linux Networking Development]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Device Mapper]

  Powered by Linux