⬢ DragonFlyBSD Kernel Audit
DF-3688 / sprintf_budget.c
← back to finding ↓ download raw
/*
 * DF-3688 harness: output-budget math for smu7_print_clock_levels
 * (smu7_hwmgr.c:4428-4431 PP_SCLK loop, 4444-4447 PP_MCLK, 4458-4463 PP_PCIE).
 *
 * The dpm table count is the unvalidated VBIOS dependency count (up to 255,
 * per DF-1166's premise: no cap in smu7_setup_dpm_tables_v0/v1).  The sysfs
 * read buffer for pp_dpm_sclk/pp_dpm_mclk/pp_dpm_pcie is one page (4096
 * bytes) allocated by kernfs; smu7_print_clock_levels sprintf()s one line
 * per level with no budget check.
 *
 * This harness reproduces the exact format strings and accumulates the byte
 * count for realistic VBIOS clock values.
 */
#include <stdio.h>
#include <stdint.h>
#include <string.h>

int main(void)
{
	char page[65536];	/* generous scratch, real buffer is 4096 */
	int size = 0, i;
	int counts[] = { 8, 64, 128, 170, 200, 255 };
	uint32_t clk = 100000;	/* 10 kHz units, i.e. a 1000 MHz part */
	uint32_t pcie_speed = 0;
	int limit = 4096;	/* PAGE_SIZE on x86_64 */

	for (int c = 0; c < (int)(sizeof(counts) / sizeof(counts[0])); c++) {
		int count = counts[c];
		size = 0;
		for (i = 0; i < count; i++)
			size += sprintf(page + size, "%d: %uMhz %s\n",
					i, (clk + i * 2500) / 100, (i == 0) ? "*" : "");
		printf("PP_SCLK  count=%3d -> %5d bytes %s PAGE_SIZE(%d)\n",
		       count, size, size > limit ? "OVERFLOWS" : "fits in", limit);
	}

	/* PP_SCLK with large u32 VBIOS clock values (ucClockHigh<<16|usClockLow
	 * spans the full u32 range; e.g. 0xC0000000 = 3.2 GHz-ish parts) */
	size = 0;
	for (i = 0; i < 255; i++)
		size += sprintf(page + size, "%d: %uMhz %s\n",
				i, 0xC0000000u / 100, (i == 0) ? "*" : "");
	printf("PP_SCLK count=255, u32 clocks  -> %d bytes %s PAGE_SIZE(%d)\n",
	       size, size > limit ? "OVERFLOWS" : "fits in", limit);

	/* PP_PCIE format (4459-4463) */
	size = 0;
	for (i = 0; i < 255; i++)
		size += sprintf(page + size, "%d: %s %s\n", i,
				(pcie_speed == 0) ? "2.5GT/s, x8" : "", (i == 0) ? "*" : "");
	printf("PP_PCIE count=255 -> %d bytes %s PAGE_SIZE(%d)\n",
	       size, size > limit ? "OVERFLOWS" : "fits in", limit);

	if (size > limit) {
		printf("RESULT: SYSFS PAGE OVERFLOW CONFIRMED - %d bytes written into a "
		       "4096-byte kernfs buffer once the VBIOS DPM count exceeds ~%d levels\n",
		       size, 170);
		return 0;
	}
	fprintf(stderr, "RESULT: overflow not observed\n");
	return 1;
}