On Sun, Nov 20, 2005 at 11:07:14PM +0000, Al Viro wrote:And here's another fun one:Gaaack... Old code used to be
evt->size = size;
evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt);
evt->event_indicator = le32_to_cpu(msg->body[0]);
memcpy(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
in i2o_driver_dispatch().
evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC);
if (!evt)
return -ENOMEM;
memset(evt, 0, size * 4 + sizeof(*evt));
evt->size = size;
memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt,
(size + 2) * 4);
Then it became
evt->size = size;
evt->tcntxt = readl(&msg->u.s.tcntxt);
evt->event_indicator = readl(&msg->body[0]);
memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
See the problem with it? The last copy should be from &msg->body[1] to
evt->data. As it is, we do not copy the last 8 bytes (which might or
might not be a problem) *AND* we overwrite tcntxt and event_indicator
with bus-endian values right after having host-endian ones carefully
assigned to them.