This source file includes following definitions.
- nlm_cop2_save
- nlm_cop2_restore
- nlm_cu2_call
- nlm_cu2_setup
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 #include <linux/capability.h>
  13 #include <linux/init.h>
  14 #include <linux/irqflags.h>
  15 #include <linux/notifier.h>
  16 #include <linux/prefetch.h>
  17 #include <linux/ptrace.h>
  18 #include <linux/sched.h>
  19 #include <linux/sched/task_stack.h>
  20 
  21 #include <asm/cop2.h>
  22 #include <asm/current.h>
  23 #include <asm/mipsregs.h>
  24 #include <asm/page.h>
  25 
  26 #include <asm/netlogic/mips-extns.h>
  27 
  28 
  29 
  30 
  31 
  32 void nlm_cop2_save(struct nlm_cop2_state *r)
  33 {
  34         asm volatile(
  35                 ".set   push\n"
  36                 ".set   noat\n"
  37                 "dmfc2  $1, $0, 0\n"
  38                 "sd     $1, 0(%1)\n"
  39                 "dmfc2  $1, $0, 1\n"
  40                 "sd     $1, 8(%1)\n"
  41                 "dmfc2  $1, $0, 2\n"
  42                 "sd     $1, 16(%1)\n"
  43                 "dmfc2  $1, $0, 3\n"
  44                 "sd     $1, 24(%1)\n"
  45                 "dmfc2  $1, $1, 0\n"
  46                 "sd     $1, 0(%2)\n"
  47                 "dmfc2  $1, $1, 1\n"
  48                 "sd     $1, 8(%2)\n"
  49                 "dmfc2  $1, $1, 2\n"
  50                 "sd     $1, 16(%2)\n"
  51                 "dmfc2  $1, $1, 3\n"
  52                 "sd     $1, 24(%2)\n"
  53                 ".set   pop\n"
  54                 : "=m"(*r)
  55                 : "r"(r->tx), "r"(r->rx));
  56 
  57         r->tx_msg_status = __read_32bit_c2_register($2, 0);
  58         r->rx_msg_status = __read_32bit_c2_register($3, 0) & 0x0fffffff;
  59 }
  60 
  61 void nlm_cop2_restore(struct nlm_cop2_state *r)
  62 {
  63         u32 rstat;
  64 
  65         asm volatile(
  66                 ".set   push\n"
  67                 ".set   noat\n"
  68                 "ld     $1, 0(%1)\n"
  69                 "dmtc2  $1, $0, 0\n"
  70                 "ld     $1, 8(%1)\n"
  71                 "dmtc2  $1, $0, 1\n"
  72                 "ld     $1, 16(%1)\n"
  73                 "dmtc2  $1, $0, 2\n"
  74                 "ld     $1, 24(%1)\n"
  75                 "dmtc2  $1, $0, 3\n"
  76                 "ld     $1, 0(%2)\n"
  77                 "dmtc2  $1, $1, 0\n"
  78                 "ld     $1, 8(%2)\n"
  79                 "dmtc2  $1, $1, 1\n"
  80                 "ld     $1, 16(%2)\n"
  81                 "dmtc2  $1, $1, 2\n"
  82                 "ld     $1, 24(%2)\n"
  83                 "dmtc2  $1, $1, 3\n"
  84                 ".set   pop\n"
  85                 : : "m"(*r), "r"(r->tx), "r"(r->rx));
  86 
  87         __write_32bit_c2_register($2, 0, r->tx_msg_status);
  88         rstat = __read_32bit_c2_register($3, 0) & 0xf0000000u;
  89         __write_32bit_c2_register($3, 0, r->rx_msg_status | rstat);
  90 }
  91 
  92 static int nlm_cu2_call(struct notifier_block *nfb, unsigned long action,
  93         void *data)
  94 {
  95         unsigned long flags;
  96         unsigned int status;
  97 
  98         switch (action) {
  99         case CU2_EXCEPTION:
 100                 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 101                         break;
 102                 local_irq_save(flags);
 103                 KSTK_STATUS(current) |= ST0_CU2;
 104                 status = read_c0_status();
 105                 write_c0_status(status | ST0_CU2);
 106                 nlm_cop2_restore(&(current->thread.cp2));
 107                 write_c0_status(status & ~ST0_CU2);
 108                 local_irq_restore(flags);
 109                 pr_info("COP2 access enabled for pid %d (%s)\n",
 110                                         current->pid, current->comm);
 111                 return NOTIFY_BAD;      
 112         }
 113 
 114         return NOTIFY_OK;               
 115 }
 116 
 117 static int __init nlm_cu2_setup(void)
 118 {
 119         return cu2_notifier(nlm_cu2_call, 0);
 120 }
 121 early_initcall(nlm_cu2_setup);