Merge tag 'y2038-drivers-for-v5.6-signed' of git://git.kernel.org:/pub/scm/linux...
[linux-2.6-microblaze.git] / net / packet / af_packet.c
index 3bec515..30c6879 100644 (file)
@@ -408,17 +408,17 @@ static int __packet_get_status(const struct packet_sock *po, void *frame)
        }
 }
 
-static __u32 tpacket_get_timestamp(struct sk_buff *skb, struct timespec *ts,
+static __u32 tpacket_get_timestamp(struct sk_buff *skb, struct timespec64 *ts,
                                   unsigned int flags)
 {
        struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
 
        if (shhwtstamps &&
            (flags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
-           ktime_to_timespec_cond(shhwtstamps->hwtstamp, ts))
+           ktime_to_timespec64_cond(shhwtstamps->hwtstamp, ts))
                return TP_STATUS_TS_RAW_HARDWARE;
 
-       if (ktime_to_timespec_cond(skb->tstamp, ts))
+       if (ktime_to_timespec64_cond(skb->tstamp, ts))
                return TP_STATUS_TS_SOFTWARE;
 
        return 0;
@@ -428,13 +428,20 @@ static __u32 __packet_set_timestamp(struct packet_sock *po, void *frame,
                                    struct sk_buff *skb)
 {
        union tpacket_uhdr h;
-       struct timespec ts;
+       struct timespec64 ts;
        __u32 ts_status;
 
        if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
                return 0;
 
        h.raw = frame;
+       /*
+        * versions 1 through 3 overflow the timestamps in y2106, since they
+        * all store the seconds in a 32-bit unsigned integer.
+        * If we create a version 4, that should have a 64-bit timestamp,
+        * either 64-bit seconds + 32-bit nanoseconds, or just 64-bit
+        * nanoseconds.
+        */
        switch (po->tp_version) {
        case TPACKET_V1:
                h.h1->tp_sec = ts.tv_sec;
@@ -769,8 +776,8 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1,
                 * It shouldn't really happen as we don't close empty
                 * blocks. See prb_retire_rx_blk_timer_expired().
                 */
-               struct timespec ts;
-               getnstimeofday(&ts);
+               struct timespec64 ts;
+               ktime_get_real_ts64(&ts);
                h1->ts_last_pkt.ts_sec = ts.tv_sec;
                h1->ts_last_pkt.ts_nsec = ts.tv_nsec;
        }
@@ -800,7 +807,7 @@ static void prb_thaw_queue(struct tpacket_kbdq_core *pkc)
 static void prb_open_block(struct tpacket_kbdq_core *pkc1,
        struct tpacket_block_desc *pbd1)
 {
-       struct timespec ts;
+       struct timespec64 ts;
        struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1;
 
        smp_rmb();
@@ -813,7 +820,7 @@ static void prb_open_block(struct tpacket_kbdq_core *pkc1,
        BLOCK_NUM_PKTS(pbd1) = 0;
        BLOCK_LEN(pbd1) = BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
 
-       getnstimeofday(&ts);
+       ktime_get_real_ts64(&ts);
 
        h1->ts_first_pkt.ts_sec = ts.tv_sec;
        h1->ts_first_pkt.ts_nsec = ts.tv_nsec;
@@ -2163,7 +2170,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
        unsigned long status = TP_STATUS_USER;
        unsigned short macoff, netoff, hdrlen;
        struct sk_buff *copy_skb = NULL;
-       struct timespec ts;
+       struct timespec64 ts;
        __u32 ts_status;
        bool is_drop_n_account = false;
        bool do_vnet = false;
@@ -2295,7 +2302,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
        skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
 
        if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
-               getnstimeofday(&ts);
+               ktime_get_real_ts64(&ts);
 
        status |= ts_status;