scsi: 3ware: fix 32-bit time calculations
authorArnd Bergmann <arnd@arndb.de>
Fri, 10 Nov 2017 15:58:25 +0000 (16:58 +0100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 5 Dec 2017 01:32:53 +0000 (20:32 -0500)
twl_aen_queue_event/twa_aen_queue_event, we use do_gettimeofday() to
read the lower 32 bits of the current time in seconds, to pass them to
the TW_IOCTL_GET_NEXT_EVENT ioctl or the 3ware_aen_read sysfs file.

This will overflow on all architectures in year 2106, there is not much
we can do about that without breaking the ABI. User space has 90 years
to learn to deal with it, so it's probably ok.

I'm changing it to use ktime_get_real_seconds() with a comment to
document what happens when.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Adam Radford <aradford@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-sas.c

index 00e7968a1d70f6b120aa0309087d196f77f5f145..cb9af3f7b6536e0c354b360bd34773891d132744 100644 (file)
@@ -369,7 +369,6 @@ out:
 static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
 {
        u32 local_time;
-       struct timeval time;
        TW_Event *event;
        unsigned short aen;
        char host[16];
@@ -392,8 +391,8 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
        memset(event, 0, sizeof(TW_Event));
 
        event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
-       do_gettimeofday(&time);
-       local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+       /* event->time_stamp_sec overflows in y2106 */
+       local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
        event->time_stamp_sec = local_time;
        event->aen_code = aen;
        event->retrieved = TW_AEN_NOT_RETRIEVED;
index b150e131b2e76a172aa13bbf84949ec0cc269cd4..c283fdb3cb24d4e82cc6c718d921acbad4545624 100644 (file)
@@ -221,7 +221,6 @@ out:
 static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
 {
        u32 local_time;
-       struct timeval time;
        TW_Event *event;
        unsigned short aen;
        char host[16];
@@ -240,8 +239,8 @@ static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
        memset(event, 0, sizeof(TW_Event));
 
        event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
-       do_gettimeofday(&time);
-       local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+       /* event->time_stamp_sec overflows in y2106 */
+       local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
        event->time_stamp_sec = local_time;
        event->aen_code = aen;
        event->retrieved = TW_AEN_NOT_RETRIEVED;