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, ®s[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 }