Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Page fault in page walking #2

Open
cyruscyliu opened this issue Oct 24, 2024 · 3 comments
Open

Page fault in page walking #2

cyruscyliu opened this issue Oct 24, 2024 · 3 comments

Comments

@cyruscyliu
Copy link
Collaborator

cyruscyliu commented Oct 24, 2024

In vmcs_linear2phy()

bool vmcs_linear2phy(bx_address laddr, bx_phy_address *phy)
{
      // ...
      for (; level >= 0; --level) {
        Bit64u pte;
        pt_address += ((laddr >> (9 + 9*level)) & 0xff8);
        offset_mask >>= 9;
        if (vmcs_translate_guest_physical_ept(pt_address, &pt_address, NULL))
            goto page_fault;
        BX_MEM(0)->readPhysicalPage(BX_CPU(id), pt_address, 8, &pte);    // <<<<<<<<<<<<<<<<<<<<<<<<<<
        if(!(pte & 1))
          goto page_fault;
        if (pte & BX_PAGING_PHY_ADDRESS_RESERVED_BITS)
          goto page_fault;
        pt_address = bx_phy_address(pte & BX_CONST64(0x000ffffffffff000));
        if (level == BX_LEVEL_PTE) break;
        if (pte & 0x80) {
          // large page
          pt_address &= BX_CONST64(0x000fffffffffe000);
          if (pt_address & offset_mask)
            goto page_fault;
          if (BX_CPU(id)->is_cpu_extension_supported(BX_ISA_1G_PAGES) && level == BX_LEVEL_PDPTE) break;
          if (level == BX_LEVEL_PDE) break;
          goto page_fault;
        }
      }

// <<<<<<<<<<<<<<<<<<<<<<<<<<
pte will be 0, which implies a page fault

But when pte is zero, this shouldn't crash HyperPill. It should go to page_fault and exit.

I found it was due to the bad compiler. Clang will remove the checks below with O2 and O3

        if(!(pte & 1))
          goto page_fault;
        if (pte & BX_PAGING_PHY_ADDRESS_RESERVED_BITS)
          goto page_fault;
@cyruscyliu
Copy link
Collaborator Author

cyruscyliu commented Oct 25, 2024

Compiling HyperPill with O0 and O1 won't remove these checks.

@cyruscyliu
Copy link
Collaborator Author

a workaround to keep the checks

diff --git a/ept.cc b/ept.cc
index 056db22..2d9b223 100644
--- a/ept.cc
+++ b/ept.cc
@@ -128,6 +128,7 @@ int vmcs_translate_guest_physical_ept(bx_phy_address guest_paddr, bx_phy_address
 }
 
 // Translate GVA -> GPA -> HPA
+__attribute__((optnone))
 bool vmcs_linear2phy(bx_address laddr, bx_phy_address *phy)
 {
   bx_phy_address paddress;

@cyruscyliu
Copy link
Collaborator Author

cyruscyliu commented Oct 25, 2024

I tested clang-11.1.0-6, 12.0.1-19ubuntu3, 13.0.1-2ubuntu2.2, and 14.0.0-1ubuntu1.1, they all keep the checks.
But, clang 15.0.7 removes the checks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant