Skip to content

HyperCore v6.11.0 — Thermal Guard Corrections

Choose a tag to compare

@itswill00 itswill00 released this 30 Sep 01:10
· 2 commits to main since this release

A full audit of the daemon, the WebUI and the packaging turned up that the 3-tier thermal guard was not enforcing two of its three tiers. Gaming at 70°C ran uncapped, and the vendor thermal stack was being suppressed on a hot device by the same code path that claims to stand down when it gets warm.

Both are fixed, along with the packaging gaps that let the module run code it had just rejected.

Nothing here is cosmetic. If you play games in a warm room, the behaviour change is real and it is in the direction of not cooking the phone.

Thermal guard

  • Tier 1 now actually caps Gaming — the tier-1 branch was gated on the MOBA profile, so a plain Gaming title at 70°C fell through to the hardware ceiling with no mitigation at all. Both profiles are capped now; MOBA keeps the higher 2.0 GHz Big allowance.
  • Ceilings are clamped to the hardware maximum — the tier values are constants, so a part reporting a lower ceiling must not be pushed above it.
  • The vendor thermal stack is no longer suppressed when hot — apply_profile wrote sconfig 10 (thermal-nolimits) and thrm_enable 0 at every tier, immediately undoing the skip that enforce_gaming_thermal_bypass performs at tier >= 1.
  • A dead sensor no longer reads as a cold SoC — a sensor reporting 0 has not produced a sample, but the raw read went into the threshold comparisons directly, pinning the device at Tier 0 with the bypass armed.
  • Thermal zones are selected by type, not by index — the scan skipped zones that had not published a reading yet, which on MTK parts is most of them for the first seconds after boot. The hardcoded fallback is now accepted only after its type confirms it is the wanted sensor.
  • GPU cooling device is matched properly — thermal-devfreq is the generic cpufreq type and matches the CPU policies too, so gaming could force cur_state 0 onto a CPU cooling device.

CPU

  • Governor and rate limits are applied per cluster — the stock baseline captures the Big cluster separately because MTK parts routinely boot the two clusters on different governors, but one value was written to all policies. Interactive was handing the Big cluster the Little cluster's values.
  • Devfreq ceiling is raised before the floor is lifted — devfreq returns -EINVAL for min above max. Latent today, silent failure tomorrow.

Packaging & security

  • update.json is generated at build time — it is what module.prop points updateJson at, and nothing in the repo read it, which is exactly why no build step touched it and the release URL went stale on every version bump.
  • Install no longer executes a payload that failed verification — the integrity layer asked the daemon to verify itself even after the manifest check had already failed.
  • status.json is created 0600 — it took whatever the inherited umask allowed, leaving the copy in /dev world-readable.
  • Uninstall preserves user configuration — it removed all of /data/adb/hypercore, taking charge limits, the hand-built gamelist and the HUD config with it. Settings now go to a timestamped sidecar under /data/adb/hypercore_removed/.
  • Grants are revoked on uninstall — the SYSTEM_ALERT_WINDOW appops outlived the module.
  • Gamelist autodetect no longer appends to shared storage — it wrote as root to a path an app could replace with a symlink.

Notes

  • Tier 2 keeps its existing 1.8 GHz ceiling. A never-applied 1.4/1.5 GHz value had been sitting in a comment; adopting it would have stacked a large behaviour change on top of a correctness fix.
  • A peer at uid 2000 (adb shell) is not a read-only client. It is deliberate, since the documented adb shell workflow depends on it, but anyone holding an adb pairing token can drive charge mode, PURGE_RAM and profile switching. Worth knowing before leaving wireless debugging enabled.

Verification

  • 81,648 tier transitions across every starting tier and a dense CPU/battery grid were replayed against the previous implementation: zero divergence whenever both sensors reported, which is what makes the Tier 1 change safe to land.
  • Clean under -Wall -Wextra -Werror and the clang static analyzer.