code.flowtr.dev/mirrors/u-root@v1.0.0/cmds/msr/msr_linux.go (about)

     1  // Copyright 2012-2017 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file contains support functions for msr access for Linux.
     6  package main
     7  
     8  import (
     9  	"encoding/binary"
    10  	"fmt"
    11  	"log"
    12  	"os"
    13  	"path/filepath"
    14  )
    15  
    16  func msrList(n string) []string {
    17  	m, err := filepath.Glob(filepath.Join("/dev/cpu", n, "msr"))
    18  	// This err will be if the glob was bad.
    19  	if err != nil {
    20  		log.Fatalf("No MSRs matched %v: %v", n, err)
    21  	}
    22  	// len will be zero for any of a number of reasons.
    23  	if len(m) == 0 {
    24  		log.Fatalf("No msrs found. Make sure your kernel is compiled with msrs, and you may need to 'sudo modprobe msr'. To see available msrs, ls /dev/cpu.")
    25  	}
    26  	return m
    27  }
    28  
    29  func openAll(m []string, o int) ([]*os.File, []error) {
    30  	var (
    31  		f    = make([]*os.File, len(m))
    32  		errs = make([]error, len(m))
    33  	)
    34  	for i := range m {
    35  		f[i], errs[i] = os.OpenFile(m[i], o, 0)
    36  	}
    37  	return f, errs
    38  }
    39  
    40  func doio(msr *os.File, addr uint32, f func(*os.File) error) error {
    41  	if _, err := msr.Seek(int64(addr), 0); err != nil {
    42  		return fmt.Errorf("Bad address %v: %v", addr, err)
    43  	}
    44  	return f(msr)
    45  }
    46  
    47  func rdmsr(m []string, addr uint32) ([]uint64, []error) {
    48  	var regs = make([]uint64, len(m))
    49  
    50  	f, errs := openAll(m, os.O_RDONLY)
    51  	for i := range m {
    52  		if errs[i] != nil {
    53  			continue
    54  		}
    55  		errs[i] = doio(f[i], addr, func(port *os.File) error {
    56  			return binary.Read(port, binary.LittleEndian, &regs[i])
    57  		})
    58  	}
    59  	return regs, errs
    60  }
    61  
    62  func wrmsr(m []string, addr uint32, data uint64) []error {
    63  	f, errs := openAll(m, os.O_RDWR)
    64  
    65  	for i := range m {
    66  		if errs[i] != nil {
    67  			continue
    68  		}
    69  		errs[i] = doio(f[i], addr, func(port *os.File) error {
    70  			return binary.Write(port, binary.LittleEndian, data)
    71  		})
    72  	}
    73  	return errs
    74  }