On Sat, Feb 03, 2018 at 10:40:08PM +0100, Andrew Lunn wrote: > +static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) > +{ > + struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); > + int neg_adj = 0; > + u32 diff, mult; > + u64 adj; > + > + if (scaled_ppm < 0) { > + neg_adj = 1; > + scaled_ppm = -scaled_ppm; > + } > + mult = CC_MULT; > + adj = scaled_ppm * CC_MULT_NUM; ^^^^^^^^^^^^^^^^^^^^^^^^ This easily overflows on 32 bit platforms. My bad. Fix below...
> + diff = div_u64(adj, CC_MULT_DEM); > + > + mutex_lock(&chip->reg_lock); > + > + timecounter_read(&chip->tstamp_tc); > + chip->tstamp_cc.mult = neg_adj ? mult - diff : mult + diff; > + > + mutex_unlock(&chip->reg_lock); > + > + return 0; > +} Thanks, Richard --- diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c index 92f318743bd4..bd85e2c390e1 100644 --- a/drivers/net/dsa/mv88e6xxx/ptp.c +++ b/drivers/net/dsa/mv88e6xxx/ptp.c @@ -177,7 +177,8 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) scaled_ppm = -scaled_ppm; } mult = CC_MULT; - adj = scaled_ppm * CC_MULT_NUM; + adj = CC_MULT_NUM; + adj *= scaled_ppm; diff = div_u64(adj, CC_MULT_DEM); mutex_lock(&chip->reg_lock);