DF-4904 / sim_vidunderflow.c
/* * DF-4904 logic harness — unsigned underflow in the Phase-1 voltage ramp * of k8_powernow_setperf() (sys/dev/powermng/powernow/powernow.c:260-262). * * uint32_t val; // powernow.c:231 * while (cvid > vid) { * val = cvid - (1 << cstate->mvs); // int math -> negative * WRITE_FIDVID(cfid, (val > 0) ? val : 0, 1ULL); // val is u32: the * // (val > 0) guard can NEVER catch the underflow: -1 wraps to * // 0xFFFFFFFF which is > 0. WRITE_FIDVID shifts it << 8 and * // writes MSR 0xc0010041 with bits 8..31 set (reserved field * // garbage + corrupted InitIstartId/StepOrFreq fields). * * When cvid < (1 << mvs) -- e.g. cvid=1 (0.825V), mvs=2 (100mV steps) -- * the driver programs a malformed FID_VID_CTL instead of clamping to 0. */ #include <stdio.h> #include <stdint.h> #include <string.h> #define WRITE_FIDVID(fid, vid, ctrl) \ ((uint64_t)((((uint64_t)(ctrl)) << 32) | (1ULL << 16) | \ (((uint64_t)((uint32_t)(vid))) << 8) | ((uint32_t)(fid)))) int main(void) { int cvid = 1, vid = 0, mvs = 2; /* plausible K8 values */ uint32_t val; uint64_t msr_word; val = cvid - (1 << mvs); /* powernow.c:261 */ printf("cvid=%d vid=%d mvs=%d -> cvid-(1<<mvs) = %d\n", cvid, vid, mvs, cvid - (1 << mvs)); printf("stored in uint32_t val = 0x%08x\n", val); printf("(val > 0) as evaluated = %s <-- underflow slips through\n", val > 0 ? "TRUE" : "false"); msr_word = WRITE_FIDVID(0x0a, (val > 0) ? val : 0, 1ULL); printf("WRMSR(0xc0010041) value = 0x%016llx\n", (unsigned long long)msr_word); printf(" VID field (bits 8-12) = 0x%llx\n", (unsigned long long)((msr_word >> 8) & 0x1f)); printf(" bits 13-31 (reserved) = 0x%llx <-- garbage written\n", (unsigned long long)((msr_word >> 13) & 0x7ffff)); return 0; } |