Skip to content

Commit 9591c4d

Browse files
authored
Merge pull request #147 from eddyb/rdpmc-tweaks
Minor tweaks to the measureme::counters module.
2 parents 16688a5 + 42e97a6 commit 9591c4d

File tree

1 file changed

+48
-12
lines changed

1 file changed

+48
-12
lines changed

measureme/src/counters.rs

+48-12
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,16 @@
4848
//! * if I/O can be isolated to separate profiling events, and doesn't impact
4949
//! execution in a more subtle way (see below), the deterministic parts of
5050
//! the program can still be profiled with high accuracy
51-
//! * low-level non-determinism (e.g. ASLR, randomized `HashMap`s, thread scheduling)
51+
//! * intentional uses of randomness may change execution paths, though for
52+
//! cryptographic operations specifically, "constant time" implementations
53+
//! are preferred / necessary (in order to limit an external observer's
54+
//! ability to infer secrets), so they're not as much of a problem
55+
//! * even otherwise-deterministic machine-local communication (to e.g. system
56+
//! services or drivers) can behave unpredictably (especially under load)
57+
//! * while we haven't observed this in the wild yet, it's possible for
58+
//! file reads/writes to be split up into multiple smaller chunks
59+
//! (and therefore take more userspace instructions to fully read/write)
60+
//! * low-level non-determinism (e.g. ASLR, randomized `HashMap`s, timers)
5261
//! * ASLR ("Address Space Layout Randomization"), may be provided by the OS for
5362
//! security reasons, or accidentally caused through allocations that depend on
5463
//! random data (even as low-entropy as e.g. the base 10 length of a process ID)
@@ -65,9 +74,17 @@
6574
//! ASLR and ASLR-like effects, making the entire program more sensitive
6675
//! * the default hasher is randomized, and while `rustc` doesn't use it,
6776
//! proc macros can (and will), and it's harder to disable than Linux ASLR
68-
//! * `jemalloc` (the allocator used by `rustc`, at least in official releases)
69-
//! has a 10 second "purge timer", which can introduce an ASLR-like effect,
70-
//! unless disabled with `MALLOC_CONF=dirty_decay_ms:0,muzzy_decay_ms:0`
77+
//! * most ways of measuring time will inherently never perfectly align with
78+
//! exact points in the program's execution, making time behave like another
79+
//! low-entropy source of randomness - this also means timers will elapse at
80+
//! unpredictable points (which can further impact the rest of the execution)
81+
//! * this includes the common thread scheduler technique of preempting the
82+
//! currently executing thread with a periodic timer interrupt, so the exact
83+
//! interleaving of multiple threads will likely not be reproducible without
84+
//! special OS configuration, or tools that emulate a deterministic scheduler
85+
//! * `jemalloc` (the allocator used by `rustc`, at least in official releases)
86+
//! has a 10 second "purge timer", which can introduce an ASLR-like effect,
87+
//! unless disabled with `MALLOC_CONF=dirty_decay_ms:0,muzzy_decay_ms:0`
7188
//! * hardware flaws (whether in the design or implementation)
7289
//! * hardware interrupts ("IRQs") and exceptions (like page faults) cause
7390
//! overcounting (1 instruction per interrupt, possibly the `iret` from the
@@ -525,10 +542,10 @@ mod hw {
525542
} else {
526543
asm!(
527544
// Dummy `cpuid(0)` to serialize instruction execution.
528-
"xor eax, eax",
545+
"xor %eax, %eax", // Intel syntax: "xor eax, eax"
529546
"cpuid",
530547

531-
"mov ecx, {rdpmc_ecx:e}",
548+
"mov {rdpmc_ecx:e}, %ecx", // Intel syntax: "mov ecx, {rdpmc_ecx:e}"
532549
"rdpmc",
533550
rdpmc_ecx = in(reg) reg_idx,
534551
out("eax") lo,
@@ -539,6 +556,12 @@ mod hw {
539556
out("ecx") _,
540557

541558
options(nostack),
559+
560+
// HACK(eddyb) LLVM 9 and older do not support modifiers
561+
// in Intel syntax inline asm; whenever Rust minimum LLVM
562+
// version becomes LLVM 10, remove and replace above
563+
// instructions with Intel syntax version (from comments).
564+
options(att_syntax),
542565
);
543566
}
544567
}
@@ -556,14 +579,14 @@ mod hw {
556579
unsafe {
557580
asm!(
558581
// Dummy `cpuid(0)` to serialize instruction execution.
559-
"xor eax, eax",
582+
"xor %eax, %eax", // Intel syntax: "xor eax, eax"
560583
"cpuid",
561584

562-
"mov ecx, {a_rdpmc_ecx:e}",
585+
"mov {a_rdpmc_ecx:e}, %ecx", // Intel syntax: "mov ecx, {a_rdpmc_ecx:e}"
563586
"rdpmc",
564-
"mov {a_rdpmc_eax:e}, eax",
565-
"mov {a_rdpmc_edx:e}, edx",
566-
"mov ecx, {b_rdpmc_ecx:e}",
587+
"mov %eax, {a_rdpmc_eax:e}", // Intel syntax: "mov {a_rdpmc_eax:e}, eax"
588+
"mov %edx, {a_rdpmc_edx:e}", // Intel syntax: "mov {a_rdpmc_edx:e}, edx"
589+
"mov {b_rdpmc_ecx:e}, %ecx", // Intel syntax: "mov ecx, {b_rdpmc_ecx:e}"
567590
"rdpmc",
568591
a_rdpmc_ecx = in(reg) a_reg_idx,
569592
a_rdpmc_eax = out(reg) a_lo,
@@ -577,6 +600,12 @@ mod hw {
577600
out("ecx") _,
578601

579602
options(nostack),
603+
604+
// HACK(eddyb) LLVM 9 and older do not support modifiers
605+
// in Intel syntax inline asm; whenever Rust minimum LLVM
606+
// version becomes LLVM 10, remove and replace above
607+
// instructions with Intel syntax version (from comments).
608+
options(att_syntax),
580609
);
581610
}
582611
(
@@ -786,10 +815,17 @@ mod hw {
786815
let mut _tmp: u64 = 0;
787816
unsafe {
788817
asm!(
789-
"lock xadd qword ptr [{atomic}], {tmp}",
818+
// Intel syntax: "lock xadd [{atomic}], {tmp}"
819+
"lock xadd {tmp}, ({atomic})",
790820

791821
atomic = in(reg) &mut atomic,
792822
tmp = inout(reg) _tmp,
823+
824+
// HACK(eddyb) LLVM 9 and older do not support modifiers
825+
// in Intel syntax inline asm; whenever Rust minimum LLVM
826+
// version becomes LLVM 10, remove and replace above
827+
// instructions with Intel syntax version (from comments).
828+
options(att_syntax),
793829
);
794830
}
795831

0 commit comments

Comments
 (0)