diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-09-18 22:13:04 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-09-24 16:27:48 +1000 |
commit | 07b1266962085412e85af2e7df471ec9ed0c35f5 (patch) | |
tree | 5b200821f274126a28365ad19f004160e2e928f7 /drivers/gpu/drm/nouveau/nouveau_perf.c | |
parent | e022878571690e09e965e8c6bfc837b3dc5b6b74 (diff) | |
download | op-kernel-dev-07b1266962085412e85af2e7df471ec9ed0c35f5.zip op-kernel-dev-07b1266962085412e85af2e7df471ec9ed0c35f5.tar.gz |
drm/nouveau: fix potential accuracy loss when parsing perf 0x1c tables
Reported-by: Roy Spliet <r.spliet@student.tudelft.nl>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_perf.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_perf.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c index a882a36..a397420 100644 --- a/drivers/gpu/drm/nouveau/nouveau_perf.c +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c @@ -90,50 +90,44 @@ nouveau_perf_init(struct drm_device *dev) case 0x15: perflvl->fanspeed = entry[55]; perflvl->voltage = entry[56]; - perflvl->core = ROM32(entry[1]) / 100; - perflvl->memory = ROM32(entry[5]) / 100; + perflvl->core = ROM32(entry[1]) * 10; + perflvl->memory = ROM32(entry[5]) * 10; break; case 0x21: case 0x23: case 0x24: perflvl->fanspeed = entry[4]; perflvl->voltage = entry[5]; - perflvl->core = ROM16(entry[6]); - perflvl->memory = ROM16(entry[11]); + perflvl->core = ROM16(entry[6]) * 1000; + perflvl->memory = ROM16(entry[11]) * 1000; break; case 0x25: perflvl->fanspeed = entry[4]; perflvl->voltage = entry[5]; - perflvl->core = ROM16(entry[6]); - perflvl->shader = ROM16(entry[10]); - perflvl->memory = ROM16(entry[12]); + perflvl->core = ROM16(entry[6]) * 1000; + perflvl->shader = ROM16(entry[10]) * 1000; + perflvl->memory = ROM16(entry[12]) * 1000; break; case 0x30: case 0x35: perflvl->fanspeed = entry[6]; perflvl->voltage = entry[7]; - perflvl->core = ROM16(entry[8]); - perflvl->shader = ROM16(entry[10]); - perflvl->memory = ROM16(entry[12]); + perflvl->core = ROM16(entry[8]) * 1000; + perflvl->shader = ROM16(entry[10]) * 1000; + perflvl->memory = ROM16(entry[12]) * 1000; /*XXX: confirm on 0x35 */ - perflvl->unk05 = ROM16(entry[16]); + perflvl->unk05 = ROM16(entry[16]) * 1000; break; case 0x40: #define subent(n) entry[perf[2] + ((n) * perf[3])] perflvl->fanspeed = 0; /*XXX*/ perflvl->voltage = 0; /*XXX: entry[2] */; - perflvl->core = ROM16(subent(0)) & 0xfff; - perflvl->shader = ROM16(subent(1)) & 0xfff; - perflvl->memory = ROM16(subent(2)) & 0xfff; + perflvl->core = (ROM16(subent(0)) & 0xfff) * 1000; + perflvl->shader = (ROM16(subent(1)) & 0xfff) * 1000; + perflvl->memory = (ROM16(subent(2)) & 0xfff) * 1000; break; } - /* convert MHz -> KHz, it's more convenient */ - perflvl->core *= 1000; - perflvl->memory *= 1000; - perflvl->shader *= 1000; - perflvl->unk05 *= 1000; - /* make sure vid is valid */ if (pm->voltage.supported && perflvl->voltage) { vid = nouveau_volt_vid_lookup(dev, perflvl->voltage); |