Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 64733)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 64734)
@@ -89,4 +89,5 @@
        bs3-cmn-PagingAlias.c \
        bs3-cmn-PagingProtect.c \
+       bs3-cmn-PagingQueryAddressInfo.c \
        bs3-cmn-PagingSetupCanonicalTraps.c \
        bs3-cmn-pic-data.c \
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingQueryAddressInfo.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingQueryAddressInfo.c	(revision 64734)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingQueryAddressInfo.c	(revision 64734)
@@ -0,0 +1,150 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3PagingQueryAddressInfo
+ */
+
+/*
+ * Copyright (C) 2007-2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <bs3kit.h>
+#include <iprt/asm-amd64-x86.h>
+#include <VBox/err.h>
+
+
+#undef Bs3PagingQueryAddressInfo
+BS3_CMN_DEF(int, Bs3PagingQueryAddressInfo,(uint64_t uFlat, PBS3PAGINGINFO4ADDR pPgInfo))
+{
+    RTCCUINTXREG const  cr3        = ASMGetCR3();
+    RTCCUINTXREG const  cr4        = g_uBs3CpuDetected & BS3CPU_F_CPUID ? ASMGetCR4() : 0;
+    bool const          fLegacyPTs = !(cr4 & X86_CR4_PAE);
+    int                 rc = VERR_OUT_OF_RANGE;
+
+
+    pPgInfo->fFlags             = 0;
+    pPgInfo->u.apbEntries[0]    = NULL;
+    pPgInfo->u.apbEntries[1]    = NULL;
+    pPgInfo->u.apbEntries[2]    = NULL;
+    pPgInfo->u.apbEntries[3]    = NULL;
+
+    if (!fLegacyPTs)
+    {
+#if TMPL_BITS == 16
+        uint32_t const  uMaxAddr = BS3_MODE_IS_RM_OR_V86(g_bBs3CurrentMode) ? _1M - 1 : BS3_SEL_TILED_AREA_SIZE - 1;
+#else
+        uintptr_t const uMaxAddr = ~(uintptr_t)0;
+#endif
+        uint64_t const  fEfer    = g_uBs3CpuDetected & BS3CPU_F_LONG_MODE ? ASMRdMsr(MSR_K6_EFER) : 0;
+
+        pPgInfo->cEntries = fEfer & MSR_K6_EFER_LMA ? 4 : 3;
+        pPgInfo->cbEntry  = sizeof(X86PTEPAE);
+        if ((cr3 & X86_CR3_AMD64_PAGE_MASK) <= uMaxAddr)
+        {
+            if (   (fEfer & MSR_K6_EFER_LMA)
+                && X86_IS_CANONICAL(uFlat))
+            {
+                /* 48-bit long mode paging. */
+                pPgInfo->u.Pae.pPml4e  = (X86PML4E BS3_FAR *)Bs3XptrFlatToCurrent(cr3 & X86_CR3_AMD64_PAGE_MASK);
+                pPgInfo->u.Pae.pPml4e += (uFlat >> X86_PML4_SHIFT) & X86_PML4_MASK;
+                if (!pPgInfo->u.Pae.pPml4e->n.u1Present)
+                    rc = VERR_PAGE_NOT_PRESENT;
+                else if (pPgInfo->u.Pae.pPml4e->u <= uMaxAddr)
+                {
+                    pPgInfo->u.Pae.pPdpe  = (X86PDPE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPml4e->u & X86_PAGE_BASE_MASK);
+                    pPgInfo->u.Pae.pPdpe += (uFlat >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64;
+                    if (!pPgInfo->u.Pae.pPdpe->n.u1Present)
+                        rc = VERR_PAGE_NOT_PRESENT;
+                    else if (pPgInfo->u.Pae.pPdpe->b.u1Size)
+                        rc = VINF_SUCCESS;
+                    else
+                        rc = VINF_TRY_AGAIN;
+                }
+            }
+            else if (   !(fEfer & MSR_K6_EFER_LMA)
+                     && uFlat <= _4G)
+            {
+                /* 32-bit PAE paging. */
+                pPgInfo->u.Pae.pPdpe  = (X86PDPE BS3_FAR *)Bs3XptrFlatToCurrent(cr3 & X86_CR3_PAE_PAGE_MASK);
+                pPgInfo->u.Pae.pPdpe += ((uint32_t)uFlat >> X86_PDPT_SHIFT) & X86_PDPT_MASK_PAE;
+                if (!pPgInfo->u.Pae.pPdpe->n.u1Present)
+                    rc = VERR_PAGE_NOT_PRESENT;
+                else
+                    rc = VINF_TRY_AGAIN;
+            }
+
+            /* Common code for the PD and PT levels. */
+            if (   rc == VINF_TRY_AGAIN
+                && pPgInfo->u.Pae.pPdpe->u <= uMaxAddr)
+            {
+                rc = VERR_OUT_OF_RANGE;
+                pPgInfo->u.Pae.pPde  = (X86PDEPAE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPdpe->u & X86_PAGE_BASE_MASK);
+                pPgInfo->u.Pae.pPde += (uFlat >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
+                if (!pPgInfo->u.Pae.pPde->n.u1Present)
+                    rc = VERR_PAGE_NOT_PRESENT;
+                else if (pPgInfo->u.Pae.pPde->b.u1Size)
+                    rc = VINF_SUCCESS;
+                else if (pPgInfo->u.Pae.pPde->u <= uMaxAddr)
+                {
+                    pPgInfo->u.Pae.pPte  = (X86PTEPAE BS3_FAR *)Bs3XptrFlatToCurrent(  pPgInfo->u.Pae.pPde->u
+                                                                                     & X86_PAGE_BASE_MASK);
+                }
+            }
+            else if (rc == VINF_TRY_AGAIN)
+                rc = VERR_OUT_OF_RANGE;
+        }
+    }
+    else
+    {
+#if TMPL_BITS == 16
+        uint32_t const  uMaxAddr = BS3_MODE_IS_RM_OR_V86(g_bBs3CurrentMode) ? _1M - 1 : BS3_SEL_TILED_AREA_SIZE - 1;
+#else
+        uint32_t const  uMaxAddr = UINT32_MAX;
+#endif
+
+        pPgInfo->cEntries = 2;
+        pPgInfo->cbEntry  = sizeof(X86PTE);
+        if (   uFlat < _4G
+            && cr3 <= uMaxAddr)
+        {
+            pPgInfo->u.Legacy.pPde  = (X86PDE BS3_FAR *)Bs3XptrFlatToCurrent(cr3 & X86_CR3_PAGE_MASK);
+            pPgInfo->u.Legacy.pPde += ((uint32_t)uFlat >> X86_PD_SHIFT) & X86_PD_MASK;
+            if (!pPgInfo->u.Legacy.pPde->b.u1Present)
+                rc = VERR_PAGE_NOT_PRESENT;
+            else if (pPgInfo->u.Legacy.pPde->b.u1Size)
+                rc = VINF_SUCCESS;
+            else if (pPgInfo->u.Legacy.pPde->u <= uMaxAddr)
+            {
+                pPgInfo->u.Legacy.pPte  = (X86PTE BS3_FAR *)Bs3XptrFlatToCurrent(  pPgInfo->u.Legacy.pPde->u
+                                                                                 & X86_PAGE_BASE_MASK_32);
+                pPgInfo->u.Legacy.pPte += ((uint32_t)uFlat >> X86_PT_SHIFT) & X86_PT_MASK;
+                if (pPgInfo->u.Legacy.pPte->n.u1Present)
+                    rc = VINF_SUCCESS;
+                else
+                    rc = VERR_PAGE_NOT_PRESENT;
+            }
+        }
+    }
+    return rc;
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk	(revision 64733)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk	(revision 64734)
@@ -41,6 +41,7 @@
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingInitRootForPAE)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingInitRootForPP)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingProtect)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingProtectPtr)
-$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingProtect)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingQueryAddressInfo)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingUnalias)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SwitchFromV86To16BitAndCallC)
@@ -65,11 +66,10 @@
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3MemMove)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3MemPCpy)
-$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingGetPde)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingGetPte)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingSetupCanonicalTraps)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabAlloc)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabAllocEx)
-$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabAlloc)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabListAlloc)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabListAllocEx)
-$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabListAlloc)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3MemFree)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3MemGuardedTestPageFree)
@@ -105,6 +105,6 @@
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TestSubV)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TestTerm)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3Trap16Init)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3Trap16InitEx)
-$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3Trap16Init)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3Trap16SetGate)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3Trap32Init)
@@ -115,6 +115,6 @@
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapPrintFrame)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapReInit)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapRmV86Init)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapRmV86InitEx)
-$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapRmV86Init)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapRmV86SetGate)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapSetHandlerEx)
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h	(revision 64733)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h	(revision 64734)
@@ -51,5 +51,4 @@
 #define bs3PagingGetLegacyPte BS3_CMN_MANGLER(bs3PagingGetLegacyPte)
 #define bs3PagingGetPaePte BS3_CMN_MANGLER(bs3PagingGetPaePte)
-#define Bs3PagingGetPde BS3_CMN_MANGLER(Bs3PagingGetPde)
 #define Bs3PagingGetPte BS3_CMN_MANGLER(Bs3PagingGetPte)
 #define Bs3PagingInitRootForLM BS3_CMN_MANGLER(Bs3PagingInitRootForLM)
@@ -58,4 +57,5 @@
 #define Bs3PagingProtect BS3_CMN_MANGLER(Bs3PagingProtect)
 #define Bs3PagingProtectPtr BS3_CMN_MANGLER(Bs3PagingProtectPtr)
+#define Bs3PagingQueryAddressInfo BS3_CMN_MANGLER(Bs3PagingQueryAddressInfo)
 #define Bs3PagingSetupCanonicalTraps BS3_CMN_MANGLER(Bs3PagingSetupCanonicalTraps)
 #define Bs3PagingUnalias BS3_CMN_MANGLER(Bs3PagingUnalias)
@@ -146,6 +146,6 @@
 #define Bs3TrapSetHandler BS3_CMN_MANGLER(Bs3TrapSetHandler)
 #define Bs3TrapSetHandlerEx BS3_CMN_MANGLER(Bs3TrapSetHandlerEx)
+#define Bs3TrapSetJmp BS3_CMN_MANGLER(Bs3TrapSetJmp)
 #define Bs3TrapSetJmpAndRestore BS3_CMN_MANGLER(Bs3TrapSetJmpAndRestore)
-#define Bs3TrapSetJmp BS3_CMN_MANGLER(Bs3TrapSetJmp)
 #define Bs3TrapUnsetJmp BS3_CMN_MANGLER(Bs3TrapUnsetJmp)
 #define Bs3UInt32Div BS3_CMN_MANGLER(Bs3UInt32Div)
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h	(revision 64733)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h	(revision 64734)
@@ -51,5 +51,4 @@
 #undef bs3PagingGetLegacyPte
 #undef bs3PagingGetPaePte
-#undef Bs3PagingGetPde
 #undef Bs3PagingGetPte
 #undef Bs3PagingInitRootForLM
@@ -58,4 +57,5 @@
 #undef Bs3PagingProtect
 #undef Bs3PagingProtectPtr
+#undef Bs3PagingQueryAddressInfo
 #undef Bs3PagingSetupCanonicalTraps
 #undef Bs3PagingUnalias
@@ -146,6 +146,6 @@
 #undef Bs3TrapSetHandler
 #undef Bs3TrapSetHandlerEx
+#undef Bs3TrapSetJmp
 #undef Bs3TrapSetJmpAndRestore
-#undef Bs3TrapSetJmp
 #undef Bs3TrapUnsetJmp
 #undef Bs3UInt32Div
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 64733)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 64734)
@@ -2212,10 +2212,51 @@
 
 /**
- * Get the pointer to the PDE for the given address.
- *
- * @returns Pointer to the PDE.
- * @param   uFlat               The flat address of the page which PDE we want.
- */
-BS3_CMN_PROTO_STUB(void BS3_FAR *, Bs3PagingGetPde,(uint64_t uFlat));
+ * Paging information for an address.
+ */
+typedef struct BS3PAGINGINFO4ADDR
+{
+    /** The depth of the system's paging mode.
+     * This is always 2 for legacy, 3 for PAE and 4 for long mode. */
+    uint8_t             cEntries;
+    /** The size of the page structures (the entires). */
+    uint8_t             cbEntry;
+    /** Flags defined for future fun, currently zero. */
+    uint16_t            fFlags;
+    /** Union display different view on the entry pointers. */
+    union
+    {
+        /** Pointer to the page structure entries, starting with the PTE as 0.
+         * If large pages are involved, the first entry will be NULL (first two if 1GB
+         * page).  Same if the address is invalid on a higher level. */
+        uint8_t BS3_FAR    *apbEntries[4];
+        /** Alternative view for legacy mode. */
+        struct
+        {
+            X86PTE BS3_FAR *pPte;
+            X86PDE BS3_FAR *pPde;
+            void           *pvUnused2;
+            void           *pvUnused3;
+        } Legacy;
+        /** Alternative view for PAE and Long mode. */
+        struct
+        {
+            X86PTEPAE BS3_FAR *pPte;
+            X86PDEPAE BS3_FAR *pPde;
+            X86PDPE   BS3_FAR *pPdpe;
+            X86PML4E  BS3_FAR *pPml4e;
+        } Pae;
+    } u;
+} BS3PAGINGINFO4ADDR;
+/** Pointer to paging information for and address.   */
+typedef BS3PAGINGINFO4ADDR BS3_FAR *PBS3PAGINGINFO4ADDR;
+
+/**
+ * Queries paging information about the given virtual address.
+ *
+ * @returns VBox status code.
+ * @param   uFlat               The flat address to query information about.
+ * @param   pPgInfo             Where to return the information.
+ */
+BS3_CMN_PROTO_STUB(int, Bs3PagingQueryAddressInfo,(uint64_t uFlat, PBS3PAGINGINFO4ADDR pPgInfo));
 
 
