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

pseudo.h (2441B)


      1/* 
      2        pseudo.h    (c) 1997-8  Grant R. Guenther <grant@torque.net>
      3                                Under the terms of the GNU General Public License.
      4
      5	This is the "pseudo-interrupt" logic for parallel port drivers.
      6
      7        This module is #included into each driver.  It makes one
      8        function available:
      9
     10		ps_set_intr( void (*continuation)(void),
     11			     int  (*ready)(void),
     12			     int timeout,
     13			     int nice )
     14
     15	Which will arrange for ready() to be evaluated frequently and
     16	when either it returns true, or timeout jiffies have passed,
     17	continuation() will be invoked.
     18
     19	If nice is 1, the test will done approximately once a
     20	jiffy.  If nice is 0, the test will also be done whenever
     21	the scheduler runs (by adding it to a task queue).  If
     22	nice is greater than 1, the test will be done once every
     23	(nice-1) jiffies. 
     24
     25*/
     26
     27/* Changes:
     28
     29	1.01	1998.05.03	Switched from cli()/sti() to spinlocks
     30	1.02    1998.12.14      Added support for nice > 1
     31*/
     32	
     33#define PS_VERSION	"1.02"
     34
     35#include <linux/sched.h>
     36#include <linux/workqueue.h>
     37
     38static void ps_tq_int(struct work_struct *work);
     39
     40static void (* ps_continuation)(void);
     41static int (* ps_ready)(void);
     42static unsigned long ps_timeout;
     43static int ps_tq_active = 0;
     44static int ps_nice = 0;
     45
     46static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused)));
     47
     48static DECLARE_DELAYED_WORK(ps_tq, ps_tq_int);
     49
     50static void ps_set_intr(void (*continuation)(void), 
     51			int (*ready)(void),
     52			int timeout, int nice)
     53{
     54	unsigned long	flags;
     55
     56	spin_lock_irqsave(&ps_spinlock,flags);
     57
     58	ps_continuation = continuation;
     59	ps_ready = ready;
     60	ps_timeout = jiffies + timeout;
     61	ps_nice = nice;
     62
     63	if (!ps_tq_active) {
     64		ps_tq_active = 1;
     65		if (!ps_nice)
     66			schedule_delayed_work(&ps_tq, 0);
     67		else
     68			schedule_delayed_work(&ps_tq, ps_nice-1);
     69	}
     70	spin_unlock_irqrestore(&ps_spinlock,flags);
     71}
     72
     73static void ps_tq_int(struct work_struct *work)
     74{
     75	void (*con)(void);
     76	unsigned long flags;
     77
     78	spin_lock_irqsave(&ps_spinlock,flags);
     79
     80	con = ps_continuation;
     81	ps_tq_active = 0;
     82
     83	if (!con) {
     84		spin_unlock_irqrestore(&ps_spinlock,flags);
     85		return;
     86	}
     87	if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) {
     88		ps_continuation = NULL;
     89		spin_unlock_irqrestore(&ps_spinlock,flags);
     90		con();
     91		return;
     92	}
     93	ps_tq_active = 1;
     94	if (!ps_nice)
     95		schedule_delayed_work(&ps_tq, 0);
     96	else
     97		schedule_delayed_work(&ps_tq, ps_nice-1);
     98	spin_unlock_irqrestore(&ps_spinlock,flags);
     99}
    100
    101/* end of pseudo.h */
    102