Skip to content

klasnalol/Limits_droper

Repository files navigation

Limits_droper

Tools for reading/writing Intel package power limits, CPU ratios, and core voltage offset via MCHBAR MMIO and MSRs. Includes a Qt GUI (Wayland/COSMIC friendly via polkit), CLI utilities, and a privileged helper.

Purpose

This project was made to bypass enforced power limits on a specific test setup by directly adjusting package power limit registers over MSR and MCHBAR MMIO. It has only been tested on an ES i7-13700HX (Q1K3) on an ASUS PRIME B660M-K D4, to bypass 55W (PL1) and 157W (PL2) limits. Other CPUs, steppings, or boards may behave differently.

What’s here

  • mchbar_read.c: read a few MCHBAR registers (including the package power limit window at 0x59A0).
  • mchbar_pl_write.c: write the MCHBAR package power limit register (0x59A0).
  • mchbar_scan.c: scan MCHBAR for PL1/PL2 patterns (useful if the PL register offset differs).
  • limits_ui.c: interactive CLI UI to view/set PL1/PL2 in watts and sync MSR <-> MMIO.
  • qt_ui/: Qt Widgets GUI with buttons for read/set/sync, ratio control, and core voltage offset.
  • helper/: privileged helper + polkit policy for running the Qt GUI as your user (Wayland/COSMIC friendly).

Features

  • Read/write PL1/PL2 in watts (MSR 0x610 and MCHBAR 0x59A0).
  • Sync MSR <-> MMIO power limit values.
  • P-core / E-core ratio targets (IA32_PERF_CTL 0x199) with current ratio display (IA32_PERF_STATUS 0x198).
  • Core voltage offset (OC mailbox MSR 0x150, core plane).
  • Basic CPU info panel in the GUI (model, microcode, core counts, P/E MHz).
  • GUI profile save/load (JSON) with optional startup auto-apply and crash-guard fallback.

Requirements

  • Linux with access to /dev/mem (root).
  • MSR driver for /dev/cpu/0/msr (load with modprobe msr).
  • Root privileges for reads/writes (helper uses polkit).
  • Qt6 or Qt5 Widgets development package (for qt_ui).
  • Qt tools / build tools (Qt CMake tooling) for the GUI build.
  • Polkit (pkexec) for the Qt GUI helper on Wayland.

Note on MCHBAR scanning: finding the register offset by pattern matching requires the current PL1/PL2 values. If you already changed limits, pass those values to mchbar_scan (or use --units) so it can match correctly.

Build

As a typical CMake you can just do the following

cmake -B build

Qt UI build only:

cd qt_ui
cmake -S . -B build
cmake --build build

Helper build:

gcc -std=c11 -Wall -Wextra -O2 -o limits_helper helper/limits_helper.c -lm

Install helper + polkit policy (required on Wayland/COSMIC):

sudo install -m 0755 build/limits_helper /usr/local/bin/limits_helper
sudo install -m 0644 helper/com.limits_droper.helper.policy /usr/share/polkit-1/actions/

Of course, if you use a build directory other than build/, you should adjust your commands appropriately.

If you install the helper somewhere else, update the policy exec.path to match and export LIMITS_HELPER_PATH.

Install

From release

  1. Download the Ubuntu or Fedora tarball from the GitHub Releases page.
  2. Extract it:
tar -xzf Limits_droper-<version>-linux-<distro>.tar.gz
cd Limits_droper-<version>-linux-<distro>
  1. Install the helper + polkit policy (required on Wayland/COSMIC):
sudo install -m 0755 limits_helper /usr/local/bin/limits_helper
sudo install -m 0644 com.limits_droper.helper.policy /usr/share/polkit-1/actions/
  1. Run the GUI:
./limits_ui_qt

From source

  1. Build the tools and GUI:
gcc -std=c11 -Wall -Wextra -O2 -o mchbar_read mchbar_read.c
gcc -std=c11 -Wall -Wextra -O2 -o mchbar_pl_write mchbar_pl_write.c
gcc -std=c11 -Wall -Wextra -O2 -o mchbar_scan mchbar_scan.c -lm
gcc -std=c11 -Wall -Wextra -O2 -o limits_ui limits_ui.c -lm
gcc -std=c11 -Wall -Wextra -O2 -o limits_helper helper/limits_helper.c -lm
cmake -S qt_ui -B qt_ui/build
cmake --build qt_ui/build
  1. Install the helper + polkit policy:
sudo install -m 0755 limits_helper /usr/local/bin/limits_helper
sudo install -m 0644 helper/com.limits_droper.helper.policy /usr/share/polkit-1/actions/
  1. Run the GUI:
./qt_ui/build/limits_ui_qt

Usage

Read MCHBAR values:

sudo ./build/mchbar_read

Scan MCHBAR for PL1/PL2 pattern (default 55W/157W):

sudo ./build/mchbar_scan

Note: scanning relies on matching the current PL1/PL2 values. If you already changed limits, pass those values to mchbar_scan (or use --units) so it can find the correct register offset. Scan using explicit watts:

sudo ./build/mchbar_scan --pl1 55 --pl2 157

Scan using raw units (if you already know them):

sudo ./build/mchbar_scan --units 0x1b8 0x4e8

Write MCHBAR package limits (PL1/PL2):

sudo build/mchbar_pl_write --set 150 170
sudo build/mchbar_pl_write --restore 0x004284e800df81b8

Write kernel powercap limits (intel-rapl, in micro-watts):

sudo ./build/limits_helper --write-powercap 160000000 170000000

Start/stop/disable/enable powercap writer services:

sudo ./build/limits_helper --start-thermald
sudo ./build/limits_helper --stop-thermald
sudo ./build/limits_helper --disable-thermald
sudo ./build/limits_helper --enable-thermald

sudo ./build/limits_helper --start-tuned
sudo ./build/limits_helper --stop-tuned
sudo ./build/limits_helper --disable-tuned
sudo ./build/limits_helper --enable-tuned

sudo ./build/limits_helper --start-tuned-ppd
sudo ./build/limits_helper --stop-tuned-ppd
sudo ./build/limits_helper --disable-tuned-ppd
sudo ./build/limits_helper --enable-tuned-ppd

--start-* / --stop-* change runtime state now. --enable-* / --disable-* only change boot persistence.

Interactive UI (read/set/sync MSR + MMIO):

sudo build/limits_ui

Qt UI:

./qt_ui/build/limits_ui_qt

If you cd qt_ui first, run ./build/limits_ui_qt. The GUI uses polkit via pkexec, so it should be run as your user (no sudo). You can override the helper path with LIMITS_HELPER_PATH. Profiles + startup:

  • Use "Save Profile" / "Load Profile" to store JSON profiles with PL1/PL2, ratios, and core UV.
  • Enable "Apply on startup" to auto-apply the selected profile. If the previous auto-apply did not finish (crash/lockup), startup auto-apply is disabled and an optional fallback profile can be applied instead.

Notes

  • MCHBAR base is discovered from PCI config (host bridge 0x48), package power limit register at offset 0x59A0.
  • MSR power unit is taken from IA32_RAPL_POWER_UNIT (0x606) and applied when converting watts.
  • Power limits are written to IA32_PKG_POWER_LIMIT (0x610) and/or MCHBAR 0x59A0.
  • Ratio targets are shown from IA32_PERF_CTL (0x199); current ratios are read from IA32_PERF_STATUS (0x198).
  • P/E detection uses CPUID leaf 0x1A core type when available.
  • Core voltage offset uses the OC mailbox (MSR 0x150) with a core-plane offset (mV). Use with caution.
  • Tested only on ES i7-13700HX (Q1K3) on PRIME B660M-K D4, used to bypass 55W and 157W limits. Other CPUs/boards may differ.

Troubleshooting

  • GUI shows permission errors: make sure the helper is installed and the polkit policy is in place, then run the GUI as your user (not sudo).
  • Verify helper output:
    pkexec /usr/local/bin/limits_helper --read
  • P/E lists empty: CPUID 0x1A may be unavailable. Use “Set All” ratio or add a manual mapping.

Credits

Safety

Writing MSRs/MMIO can destabilize a system or damage hardware. Use at your own risk.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors