• Maxime Ripard's avatar
    clk: Enforce that disjoints limits are invalid · 10c46f2e
    Maxime Ripard authored
    
    
    If we were to have two users of the same clock, doing something like:
    
    clk_set_rate_range(user1, 1000, 2000);
    clk_set_rate_range(user2, 3000, 4000);
    
    The second call would fail with -EINVAL, preventing from getting in a
    situation where we end up with impossible limits.
    
    However, this is never explicitly checked against and enforced, and
    works by relying on an undocumented behaviour of clk_set_rate().
    
    Indeed, on the first clk_set_rate_range will make sure the current clock
    rate is within the new range, so it will be between 1000 and 2000Hz. On
    the second clk_set_rate_range(), it will consider (rightfully), that our
    current clock is outside of the 3000-4000Hz range, and will call
    clk_core_set_rate_nolock() to set it to 3000Hz.
    
    clk_core_set_rate_nolock() will then call clk_calc_new_rates() that will
    eventually check that our rate 3000Hz rate is outside the min 3000Hz max
    2000Hz range, will bail out, the error will propagate and we'll
    eventually return -EINVAL.
    
    This solely relies on the fact that clk_calc_new_rates(), and in
    particular clk_core_determine_round_nolock(), won't modify the new rate
    allowing the error to be reported. That assumption won't be true for all
    drivers, and most importantly we'll break that assumption in a later
    patch.
    
    It can also be argued that we shouldn't even reach the point where we're
    calling clk_core_set_rate_nolock().
    
    Let's make an explicit check for disjoints range before we're doing
    anything.
    Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
    Link: https://lore.kernel.org/r/20220225143534.405820-4-maxime@cerno.tech
    
    Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
    10c46f2e
clk.c 130 KB