{
        unsigned int idx;
 
-       target_freq = clamp_val(target_freq, policy->min, policy->max);
-
        if (!policy->freq_table)
                return target_freq;
 
 unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
                                         unsigned int target_freq)
 {
-       return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_LE);
+       unsigned int min = READ_ONCE(policy->min);
+       unsigned int max = READ_ONCE(policy->max);
+
+       /*
+        * If this function runs in parallel with cpufreq_set_policy(), it may
+        * read policy->min before the update and policy->max after the update
+        * or the other way around, so there is no ordering guarantee.
+        *
+        * Resolve this by always honoring the max (in case it comes from
+        * thermal throttling or similar).
+        */
+       if (unlikely(min > max))
+               min = max;
+
+       return __resolve_freq(policy, clamp_val(target_freq, min, max),
+                             CPUFREQ_RELATION_LE);
 }
 EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq);
 
        if (cpufreq_disabled())
                return -ENODEV;
 
+       target_freq = clamp_val(target_freq, policy->min, policy->max);
        target_freq = __resolve_freq(policy, target_freq, relation);
 
        pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
         * Resolve policy min/max to available frequencies. It ensures
         * no frequency resolution will neither overshoot the requested maximum
         * nor undershoot the requested minimum.
+        *
+        * Avoid storing intermediate values in policy->max or policy->min and
+        * compiler optimizations around them because they may be accessed
+        * concurrently by cpufreq_driver_resolve_freq() during the update.
         */
-       policy->min = new_data.min;
-       policy->max = new_data.max;
-       policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L);
-       policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H);
+       WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max, CPUFREQ_RELATION_H));
+       new_data.min = __resolve_freq(policy, new_data.min, CPUFREQ_RELATION_L);
+       WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min);
+
        trace_cpu_frequency_limits(policy);
 
        cpufreq_update_pressure(policy);