cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

helpers.h (1299B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __VDSO_HELPERS_H
      3#define __VDSO_HELPERS_H
      4
      5#ifndef __ASSEMBLY__
      6
      7#include <vdso/datapage.h>
      8
      9static __always_inline u32 vdso_read_begin(const struct vdso_data *vd)
     10{
     11	u32 seq;
     12
     13	while (unlikely((seq = READ_ONCE(vd->seq)) & 1))
     14		cpu_relax();
     15
     16	smp_rmb();
     17	return seq;
     18}
     19
     20static __always_inline u32 vdso_read_retry(const struct vdso_data *vd,
     21					   u32 start)
     22{
     23	u32 seq;
     24
     25	smp_rmb();
     26	seq = READ_ONCE(vd->seq);
     27	return seq != start;
     28}
     29
     30static __always_inline void vdso_write_begin(struct vdso_data *vd)
     31{
     32	/*
     33	 * WRITE_ONCE it is required otherwise the compiler can validly tear
     34	 * updates to vd[x].seq and it is possible that the value seen by the
     35	 * reader it is inconsistent.
     36	 */
     37	WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1);
     38	WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1);
     39	smp_wmb();
     40}
     41
     42static __always_inline void vdso_write_end(struct vdso_data *vd)
     43{
     44	smp_wmb();
     45	/*
     46	 * WRITE_ONCE it is required otherwise the compiler can validly tear
     47	 * updates to vd[x].seq and it is possible that the value seen by the
     48	 * reader it is inconsistent.
     49	 */
     50	WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1);
     51	WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1);
     52}
     53
     54#endif /* !__ASSEMBLY__ */
     55
     56#endif /* __VDSO_HELPERS_H */