Skip to content

Commit 2c021b4

Browse files
arndbgroeck
authored andcommitted
hwmon: (occ) fix unaligned accesses
Passing a pointer to an unaligned integer as a function argument is undefined behavior: drivers/hwmon/occ/common.c:492:27: warning: taking address of packed member 'accumulator' of class or structure 'power_sensor_2' may result in an unaligned pointer value [-Waddress-of-packed-member] 492 | val = occ_get_powr_avg(&power->accumulator, | ^~~~~~~~~~~~~~~~~~ drivers/hwmon/occ/common.c:493:13: warning: taking address of packed member 'update_tag' of class or structure 'power_sensor_2' may result in an unaligned pointer value [-Waddress-of-packed-member] 493 | &power->update_tag); | ^~~~~~~~~~~~~~~~~ Move the get_unaligned() calls out of the function and pass these through argument registers instead. Fixes: c10e753 ("hwmon (occ): Add sensor types and versions") Signed-off-by: Arnd Bergmann <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]>
1 parent 744c2fe commit 2c021b4

File tree

1 file changed

+13
-15
lines changed

1 file changed

+13
-15
lines changed

drivers/hwmon/occ/common.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -459,12 +459,10 @@ static ssize_t occ_show_power_1(struct device *dev,
459459
return sysfs_emit(buf, "%llu\n", val);
460460
}
461461

462-
static u64 occ_get_powr_avg(u64 *accum, u32 *samples)
462+
static u64 occ_get_powr_avg(u64 accum, u32 samples)
463463
{
464-
u64 divisor = get_unaligned_be32(samples);
465-
466-
return (divisor == 0) ? 0 :
467-
div64_u64(get_unaligned_be64(accum) * 1000000ULL, divisor);
464+
return (samples == 0) ? 0 :
465+
mul_u64_u32_div(accum, 1000000UL, samples);
468466
}
469467

470468
static ssize_t occ_show_power_2(struct device *dev,
@@ -489,8 +487,8 @@ static ssize_t occ_show_power_2(struct device *dev,
489487
get_unaligned_be32(&power->sensor_id),
490488
power->function_id, power->apss_channel);
491489
case 1:
492-
val = occ_get_powr_avg(&power->accumulator,
493-
&power->update_tag);
490+
val = occ_get_powr_avg(get_unaligned_be64(&power->accumulator),
491+
get_unaligned_be32(&power->update_tag));
494492
break;
495493
case 2:
496494
val = (u64)get_unaligned_be32(&power->update_tag) *
@@ -527,8 +525,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
527525
return sysfs_emit(buf, "%u_system\n",
528526
get_unaligned_be32(&power->sensor_id));
529527
case 1:
530-
val = occ_get_powr_avg(&power->system.accumulator,
531-
&power->system.update_tag);
528+
val = occ_get_powr_avg(get_unaligned_be64(&power->system.accumulator),
529+
get_unaligned_be32(&power->system.update_tag));
532530
break;
533531
case 2:
534532
val = (u64)get_unaligned_be32(&power->system.update_tag) *
@@ -541,8 +539,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
541539
return sysfs_emit(buf, "%u_proc\n",
542540
get_unaligned_be32(&power->sensor_id));
543541
case 5:
544-
val = occ_get_powr_avg(&power->proc.accumulator,
545-
&power->proc.update_tag);
542+
val = occ_get_powr_avg(get_unaligned_be64(&power->proc.accumulator),
543+
get_unaligned_be32(&power->proc.update_tag));
546544
break;
547545
case 6:
548546
val = (u64)get_unaligned_be32(&power->proc.update_tag) *
@@ -555,8 +553,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
555553
return sysfs_emit(buf, "%u_vdd\n",
556554
get_unaligned_be32(&power->sensor_id));
557555
case 9:
558-
val = occ_get_powr_avg(&power->vdd.accumulator,
559-
&power->vdd.update_tag);
556+
val = occ_get_powr_avg(get_unaligned_be64(&power->vdd.accumulator),
557+
get_unaligned_be32(&power->vdd.update_tag));
560558
break;
561559
case 10:
562560
val = (u64)get_unaligned_be32(&power->vdd.update_tag) *
@@ -569,8 +567,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
569567
return sysfs_emit(buf, "%u_vdn\n",
570568
get_unaligned_be32(&power->sensor_id));
571569
case 13:
572-
val = occ_get_powr_avg(&power->vdn.accumulator,
573-
&power->vdn.update_tag);
570+
val = occ_get_powr_avg(get_unaligned_be64(&power->vdn.accumulator),
571+
get_unaligned_be32(&power->vdn.update_tag));
574572
break;
575573
case 14:
576574
val = (u64)get_unaligned_be32(&power->vdn.update_tag) *

0 commit comments

Comments
 (0)