LCOV - code coverage report
Current view: top level - arch/x86/lib - msr.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 21 45 46.7 %
Date: 2022-03-28 16:04:14 Functions: 2 10 20.0 %
Branches: 6 16 37.5 %

           Branch data     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                 :         13 : int msr_read(u32 msr, struct msr *m)
      40                 :            : {
      41                 :         13 :         int err;
      42                 :         13 :         u64 val;
      43                 :            : 
      44                 :          0 :         err = rdmsrl_safe(msr, &val);
      45   [ +  -  -  - ]:         13 :         if (!err)
      46                 :         13 :                 m->q = val;
      47                 :            : 
      48                 :         13 :         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                 :         13 : int msr_write(u32 msr, struct msr *m)
      58                 :            : {
      59                 :          0 :         return wrmsrl_safe(msr, m->q);
      60                 :            : }
      61                 :            : 
      62                 :         13 : static inline int __flip_bit(u32 msr, u8 bit, bool set)
      63                 :            : {
      64                 :         13 :         struct msr m, m1;
      65                 :         13 :         int err = -EINVAL;
      66                 :            : 
      67         [ +  - ]:         13 :         if (bit > 63)
      68                 :            :                 return err;
      69                 :            : 
      70                 :         13 :         err = msr_read(msr, &m);
      71         [ +  - ]:         13 :         if (err)
      72                 :            :                 return err;
      73                 :            : 
      74                 :         13 :         m1 = m;
      75         [ +  - ]:         13 :         if (set)
      76                 :         13 :                 m1.q |=  BIT_64(bit);
      77                 :            :         else
      78                 :          0 :                 m1.q &= ~BIT_64(bit);
      79                 :            : 
      80         [ +  - ]:         13 :         if (m1.q == m.q)
      81                 :            :                 return 0;
      82                 :            : 
      83                 :         13 :         err = msr_write(msr, &m1);
      84         [ -  + ]:         13 :         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                 :         13 : int msr_set_bit(u32 msr, u8 bit)
      99                 :            : {
     100                 :         13 :         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                 :          0 : int msr_clear_bit(u32 msr, u8 bit)
     112                 :            : {
     113                 :          0 :         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