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