From 1821df475b462ff16140a22e1872dbfdc64de9ac Mon Sep 17 00:00:00 2001 From: Udo Steinberg Date: Wed, 24 Jul 2013 14:28:19 +0200 Subject: [PATCH] vTLB: Use PAE format on 64bit hosts. --- include/vtlb.hpp | 9 +++++++-- src/regs.cpp | 34 +++++++++++++++++++--------------- src/vtlb.cpp | 28 ++++++++++++++-------------- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/include/vtlb.hpp b/include/vtlb.hpp index 324156d80..8e7336c5e 100644 --- a/include/vtlb.hpp +++ b/include/vtlb.hpp @@ -4,7 +4,7 @@ * Copyright (C) 2009-2011 Udo Steinberg * Economic rights: Technische Universitaet Dresden (Germany) * - * Copyright (C) 2012 Udo Steinberg, Intel Corporation. + * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. * * This file is part of the NOVA microhypervisor. * @@ -25,11 +25,15 @@ class Exc_regs; +#ifdef __i386__ class Vtlb : public Pte +#else +class Vtlb : public Pte +#endif { private: ALWAYS_INLINE - inline bool global() const { return val & TLB_G; } + inline bool mark() const { return val & TLB_M; } ALWAYS_INLINE inline bool frag() const { return val & TLB_F; } @@ -57,6 +61,7 @@ class Vtlb : public Pte TLB_S = 1UL << 7, TLB_G = 1UL << 8, TLB_F = 1UL << 9, + TLB_M = 1UL << 10, PTE_P = TLB_P, PTE_S = TLB_S, diff --git a/src/regs.cpp b/src/regs.cpp index 0a7b8903a..af4203ef3 100644 --- a/src/regs.cpp +++ b/src/regs.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2009-2011 Udo Steinberg * Economic rights: Technische Universitaet Dresden (Germany) * - * Copyright (C) 2012 Udo Steinberg, Intel Corporation. + * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. * * This file is part of the NOVA microhypervisor. * @@ -111,14 +111,14 @@ mword Exc_regs::linear_address (mword val) const template mword Exc_regs::cr0_set() const { - mword msk = 0; + mword set = 0; if (!nst_on) - msk |= Cpu::CR0_PG | Cpu::CR0_WP | Cpu::CR0_PE; + set |= Cpu::CR0_PG | Cpu::CR0_WP | Cpu::CR0_PE; if (!fpu_on) - msk |= Cpu::CR0_TS; + set |= Cpu::CR0_TS; - return T::fix_cr0_set | msk; + return T::fix_cr0_set | set; } template @@ -130,23 +130,27 @@ mword Exc_regs::cr0_msk() const template mword Exc_regs::cr4_set() const { - mword msk = 0; - - if (!nst_on) - msk |= Cpu::CR4_PSE; + mword set = nst_on ? 0 : +#ifdef __i386__ + Cpu::CR4_PSE; +#else + Cpu::CR4_PSE | Cpu::CR4_PAE; +#endif - return T::fix_cr4_set | msk; + return T::fix_cr4_set | set; } template mword Exc_regs::cr4_msk() const { - mword msk = 0; - - if (!nst_on) - msk |= Cpu::CR4_PGE | Cpu::CR4_PAE; + mword clr = nst_on ? 0 : +#ifdef __i386__ + Cpu::CR4_PGE | Cpu::CR4_PAE; +#else + Cpu::CR4_PGE; +#endif - return T::fix_cr4_clr | cr4_set() | msk; + return T::fix_cr4_clr | clr | cr4_set(); } template diff --git a/src/vtlb.cpp b/src/vtlb.cpp index c831c5a78..ce2dd3ab8 100644 --- a/src/vtlb.cpp +++ b/src/vtlb.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2009-2011 Udo Steinberg * Economic rights: Technische Universitaet Dresden (Germany) * - * Copyright (C) 2012 Udo Steinberg, Intel Corporation. + * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. * * This file is part of the NOVA microhypervisor. * @@ -35,12 +35,12 @@ size_t Vtlb::gwalk (Exc_regs *regs, mword gla, mword &gpa, mword &attr, mword &e bool pge = regs->cr4_shadow & Cpu::CR4_PGE; bool wp = regs->cr0_shadow & Cpu::CR0_WP; - unsigned lev = max(); + unsigned lev = 2; for (uint32 e, *pte= reinterpret_cast(regs->cr3_shadow & ~PAGE_MASK);; pte = reinterpret_cast(e & ~PAGE_MASK)) { - unsigned shift = --lev * bpl() + PAGE_BITS; - pte += gla >> shift & ((1UL << bpl()) - 1); + unsigned shift = --lev * 10 + PAGE_BITS; + pte += gla >> shift & ((1UL << 10) - 1); if (User::peek (pte, e) != ~0UL) { gpa = reinterpret_cast(pte); @@ -72,8 +72,8 @@ size_t Vtlb::gwalk (Exc_regs *regs, mword gla, mword &gpa, mword &attr, mword &e attr |= e & TLB_UC; - if (EXPECT_TRUE (pge)) - attr |= e & TLB_G; + if (EXPECT_TRUE (pge) && (e & TLB_G)) + attr |= TLB_M; size_t size = 1UL << shift; @@ -144,17 +144,17 @@ Vtlb::Reason Vtlb::miss (Exc_regs *regs, mword virt, mword &error) if (lev) { - if (size < 1UL << shift) { + if (lev == 2 || size < 1UL << shift) { if (tlb->super()) - tlb->val = static_castval>(Buddy::ptr_to_phys (new Vtlb) | TLB_G | TLB_A | TLB_U | TLB_W | TLB_P); + tlb->val = static_castval>(Buddy::ptr_to_phys (new Vtlb) | (lev == 2 ? 0 : TLB_A | TLB_U | TLB_W) | TLB_M | TLB_P); else if (!tlb->present()) { - static_cast(Buddy::phys_to_ptr (tlb->addr()))->flush_ptab (tlb->global()); - tlb->val |= TLB_G | TLB_P; + static_cast(Buddy::phys_to_ptr (tlb->addr()))->flush_ptab (tlb->mark()); + tlb->val |= TLB_M | TLB_P; } - tlb->val &= static_castval>(attr | ~TLB_G); + tlb->val &= static_castval>(attr | ~TLB_M); tlb->val |= static_castval>(attr & TLB_F); continue; @@ -180,9 +180,9 @@ void Vtlb::flush_ptab (bool full) continue; if (EXPECT_FALSE (full)) - e->val |= TLB_G; + e->val |= TLB_M; - else if (EXPECT_FALSE (e->global())) + else if (EXPECT_FALSE (e->mark())) continue; e->val &= ~TLB_P; @@ -204,7 +204,7 @@ void Vtlb::flush (mword virt) if (l && !e->super() && !e->frag()) continue; - e->val |= TLB_G; + e->val |= TLB_M; e->val &= ~TLB_P; Counter::print<1,16> (++Counter::vtlb_flush, Console_vga::COLOR_LIGHT_RED, SPN_VFL);