Skip to content

Commit 4bd1973

Browse files
committed
fix field order for INVPCID descriptor
Both Intel's and AMD's manuals describe the INVPCID descriptor as a 128-bit value with the linear address stored in the upper half and the PCID stored in the lower half. x86 uses little-endian byte ordering and so the lower half (pcid) should be stored before the upper half (address). Previously, our `InvpcidDescriptor` type stored the halves in the opposite order with the address before the pcid. This patch fixes the order, so that the pcid is stored before the address. This new order is also the order used by Linux and OpenBSD: https://github.com/torvalds/linux/blob/3e5e6c9900c3d71895e8bdeacfb579462e98eba1/arch/x86/include/asm/invpcid.h#L8 https://github.com/openbsd/src/blob/4e368faebf86e9a349446b5839c333bc17bd3f9a/sys/arch/amd64/include/cpufunc.h#L173 It's beyond me how this wasn't noticed earlier. The previous incorrect layout could lead to TLB entries not being flushed and #GP faults.
1 parent 323d46c commit 4bd1973

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

src/instructions/tlb.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ pub enum InvPicdCommand {
4949
#[repr(C)]
5050
#[derive(Debug)]
5151
struct InvpcidDescriptor {
52-
address: u64,
5352
pcid: u64,
53+
address: u64,
5454
}
5555

5656
/// Structure of a PCID. A PCID has to be <= 4096 for x86_64.
@@ -95,8 +95,8 @@ impl fmt::Display for PcidTooBig {
9595
#[inline]
9696
pub unsafe fn flush_pcid(command: InvPicdCommand) {
9797
let mut desc = InvpcidDescriptor {
98-
address: 0,
9998
pcid: 0,
99+
address: 0,
100100
};
101101

102102
let kind: u64;

0 commit comments

Comments
 (0)