did something
This commit is contained in:
1 parent
ffb640b15d
commit
4bed603e6d
144 files changed
+21464
-6
No files matched your search
+65
@@ -0,0 +1,65 @@
|
||||
// Copyright 2016 The Periph Authors. All rights reserved.
|
||||
// Use of this source code is governed under the Apache License, Version 2.0
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
package pmem
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ReadPageMap reads a physical address mapping for a virtual page address from
|
||||
// /proc/self/pagemap.
|
||||
//
|
||||
// It returns the physical address that corresponds to the start of the virtual
|
||||
// page within which the virtual address virtAddr is located.
|
||||
//
|
||||
// The meaning of the return value is documented at
|
||||
// https://www.kernel.org/doc/Documentation/vm/pagemap.txt
|
||||
func ReadPageMap(virtAddr uintptr) (uint64, error) {
|
||||
if !isLinux || isWSL() {
|
||||
return 0, errors.New("pmem: pagemap is not supported on this platform")
|
||||
}
|
||||
return readPageMapLinux(virtAddr)
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var (
|
||||
pageMap fileIO
|
||||
pageMapErr error
|
||||
)
|
||||
|
||||
func readPageMapLinux(virtAddr uintptr) (uint64, error) {
|
||||
var b [8]byte
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if pageMap == nil && pageMapErr == nil {
|
||||
// Open /proc/self/pagemap.
|
||||
//
|
||||
// It is a uint64 array where the index represents the virtual 4Kb page
|
||||
// number and the value represents the physical page properties backing
|
||||
// this virtual page.
|
||||
pageMap, pageMapErr = openFile("/proc/self/pagemap", os.O_RDONLY|os.O_SYNC)
|
||||
}
|
||||
if pageMapErr != nil {
|
||||
return 0, pageMapErr
|
||||
}
|
||||
// Convert address to page number, then index in uint64 array.
|
||||
offset := int64(virtAddr / pageSize * 8)
|
||||
if _, err := pageMap.Seek(offset, io.SeekStart); err != nil {
|
||||
return 0, fmt.Errorf("pmem: failed to seek at 0x%x for 0x%x: %v", offset, virtAddr, err)
|
||||
}
|
||||
n, err := pageMap.Read(b[:])
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("pmem: failed to read at 0x%x for 0x%x: %v", offset, virtAddr, err)
|
||||
}
|
||||
if n != len(b) {
|
||||
return 0, fmt.Errorf("pmem: failed to read the amount of data %d", len(b))
|
||||
}
|
||||
return binary.LittleEndian.Uint64(b[:]), nil
|
||||
}
|
||||
Reference in new issue
Block a user