Skip to content

Commit

Permalink
page: enable PCID
Browse files Browse the repository at this point in the history
Signed-off-by: smallkirby <ssmallkirby@gmail.com>
  • Loading branch information
smallkirby committed Oct 31, 2024
1 parent c07894e commit ad4e475
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
6 changes: 3 additions & 3 deletions ymir/arch/x86/asm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ pub const Cr4 = packed struct(u64) {
de: bool,
/// Page size extension.
pse: bool,
/// Physical address extension.
/// Physical address extension. If unset, 32-bit paging.
pae: bool,
/// Machine check exception.
mce: bool,
Expand All @@ -706,8 +706,8 @@ pub const Cr4 = packed struct(u64) {
osxmmexcpt: bool,
/// Virtual machine extensions.
umip: bool,
/// Reserved.
_reserved: u1 = 0,
/// 57-bit linear addresses. If set, CPU uses 5-level paging.
la57: bool = false,
/// Virtual machine extensions enable.
vmxe: bool,
/// Safer mode extensions enable.
Expand Down
26 changes: 24 additions & 2 deletions ymir/arch/x86/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;

const arch = @import("arch.zig");
const am = @import("asm.zig");
const cpuid = @import("cpuid.zig");

const ymir = @import("ymir");
const mem = ymir.mem;
Expand Down Expand Up @@ -313,7 +314,14 @@ pub fn reconstruct(allocator: Allocator) PageError!void {
}

var cr3 = @intFromPtr(lv4tbl) & ~@as(u64, 0xFFF);
cr3 |= 0x001; // PCID // TODO

// Enable PCID.
// Note that KVM disallows enabling PCID when CR3[11:0]!=000H though it is not documented in SDM.
// Anyway on KVM, we have to enable PCID before loading CR3 that has CPUID.
// See https://github.com/torvalds/linux/blob/0fc810ae3ae110f9e2fcccce80fc8c8d62f97907/arch/x86/kvm/x86.c#L1395
if (enablePcid()) {
cr3 |= 0x001; // PCID // TODO
}

// Set new lv4-table and flush all TLBs.
am.loadCr3(cr3);
Expand Down Expand Up @@ -389,6 +397,18 @@ fn splitTable(T: type, ent: *T, allocator: Allocator) PageError!void {
ent.* = T.newMapTable(tbl.ptr, true);
}

/// Enable PCID.
fn enablePcid() bool {
const cpuid_result = cpuid.Leaf.from(0x01).query(null);
if (ymir.bits.isset(cpuid_result.ecx, 17)) {
var cr4 = am.readCr4();
cr4.pcide = true;
am.loadCr4(cr4);

return true;
} else return false;
}

/// Show the process of the address translation for the given linear address.
pub fn showPageTable(lin_addr: Virt, logger: anytype) void {
const pml4_index = (lin_addr >> lv4_shift) & index_mask;
Expand Down Expand Up @@ -480,7 +500,9 @@ fn EntryBase(table_level: TableLevel) type {
restart: bool = false,
/// When the entry maps a page, physical address of the page.
/// When the entry references a page table, 4KB aligned address of the page table.
phys: u51,
phys: u21,
/// ReservedZ
_reserved: u30 = 0,
/// Execute Disable.
xd: bool = false,

Expand Down

0 comments on commit ad4e475

Please sign in to comment.