LCOV - code coverage report
Current view: top level - arch/x86/lib - msr.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 19 45 42.2 %
Date: 2021-04-22 12:43:58 Functions: 3 10 30.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : #include <linux/export.h>
       3             : #include <linux/percpu.h>
       4             : #include <linux/preempt.h>
       5             : #include <asm/msr.h>
       6             : #define CREATE_TRACE_POINTS
       7             : #include <asm/msr-trace.h>
       8             : 
       9           0 : struct msr *msrs_alloc(void)
      10             : {
      11           0 :         struct msr *msrs = NULL;
      12             : 
      13           0 :         msrs = alloc_percpu(struct msr);
      14           0 :         if (!msrs) {
      15           0 :                 pr_warn("%s: error allocating msrs\n", __func__);
      16           0 :                 return NULL;
      17             :         }
      18             : 
      19             :         return msrs;
      20             : }
      21             : EXPORT_SYMBOL(msrs_alloc);
      22             : 
      23           0 : void msrs_free(struct msr *msrs)
      24             : {
      25           0 :         free_percpu(msrs);
      26           0 : }
      27             : EXPORT_SYMBOL(msrs_free);
      28             : 
      29             : /**
      30             :  * Read an MSR with error handling
      31             :  *
      32             :  * @msr: MSR to read
      33             :  * @m: value to read into
      34             :  *
      35             :  * It returns read data only on success, otherwise it doesn't change the output
      36             :  * argument @m.
      37             :  *
      38             :  */
      39           9 : int msr_read(u32 msr, struct msr *m)
      40             : {
      41           9 :         int err;
      42           9 :         u64 val;
      43             : 
      44           9 :         err = rdmsrl_safe(msr, &val);
      45           9 :         if (!err)
      46           9 :                 m->q = val;
      47             : 
      48           9 :         return err;
      49             : }
      50             : 
      51             : /**
      52             :  * Write an MSR with error handling
      53             :  *
      54             :  * @msr: MSR to write
      55             :  * @m: value to write
      56             :  */
      57           0 : int msr_write(u32 msr, struct msr *m)
      58             : {
      59           0 :         return wrmsrl_safe(msr, m->q);
      60             : }
      61             : 
      62           9 : static inline int __flip_bit(u32 msr, u8 bit, bool set)
      63             : {
      64           9 :         struct msr m, m1;
      65           9 :         int err = -EINVAL;
      66             : 
      67           9 :         if (bit > 63)
      68             :                 return err;
      69             : 
      70           9 :         err = msr_read(msr, &m);
      71           9 :         if (err)
      72             :                 return err;
      73             : 
      74           9 :         m1 = m;
      75           9 :         if (set)
      76           0 :                 m1.q |=  BIT_64(bit);
      77             :         else
      78           9 :                 m1.q &= ~BIT_64(bit);
      79             : 
      80           9 :         if (m1.q == m.q)
      81             :                 return 0;
      82             : 
      83           0 :         err = msr_write(msr, &m1);
      84           0 :         if (err)
      85           0 :                 return err;
      86             : 
      87             :         return 1;
      88             : }
      89             : 
      90             : /**
      91             :  * Set @bit in a MSR @msr.
      92             :  *
      93             :  * Retval:
      94             :  * < 0: An error was encountered.
      95             :  * = 0: Bit was already set.
      96             :  * > 0: Hardware accepted the MSR write.
      97             :  */
      98           0 : int msr_set_bit(u32 msr, u8 bit)
      99             : {
     100           0 :         return __flip_bit(msr, bit, true);
     101             : }
     102             : 
     103             : /**
     104             :  * Clear @bit in a MSR @msr.
     105             :  *
     106             :  * Retval:
     107             :  * < 0: An error was encountered.
     108             :  * = 0: Bit was already cleared.
     109             :  * > 0: Hardware accepted the MSR write.
     110             :  */
     111           9 : int msr_clear_bit(u32 msr, u8 bit)
     112             : {
     113           9 :         return __flip_bit(msr, bit, false);
     114             : }
     115             : 
     116             : #ifdef CONFIG_TRACEPOINTS
     117           0 : void do_trace_write_msr(unsigned int msr, u64 val, int failed)
     118             : {
     119           0 :         trace_write_msr(msr, val, failed);
     120           0 : }
     121             : EXPORT_SYMBOL(do_trace_write_msr);
     122             : EXPORT_TRACEPOINT_SYMBOL(write_msr);
     123             : 
     124           0 : void do_trace_read_msr(unsigned int msr, u64 val, int failed)
     125             : {
     126           0 :         trace_read_msr(msr, val, failed);
     127           0 : }
     128             : EXPORT_SYMBOL(do_trace_read_msr);
     129             : EXPORT_TRACEPOINT_SYMBOL(read_msr);
     130             : 
     131           0 : void do_trace_rdpmc(unsigned counter, u64 val, int failed)
     132             : {
     133           0 :         trace_rdpmc(counter, val, failed);
     134           0 : }
     135             : EXPORT_SYMBOL(do_trace_rdpmc);
     136             : EXPORT_TRACEPOINT_SYMBOL(rdpmc);
     137             : 
     138             : #endif

Generated by: LCOV version 1.14