On 6/7/24 1:43 PM, Richard Henderson wrote:
On 6/6/24 07:02, Don Porter wrote:
+/**
+ * get_pte - Copy the contents of the page table entry at node[i] into pt_entry. + *           Optionally, add the relevant bits to the virtual address in
+ *           vaddr_pte.
+ *
+ * @cs - CPU state
+ * @node - physical address of the current page table node
+ * @i - index (in page table entries, not bytes) of the page table
+ *      entry, within node
+ * @height - height of node within the tree (leaves are 1, not 0)
+ * @pt_entry - Poiter to a PTE_t, stores the contents of the page table entry + * @vaddr_parent - The virtual address bits already translated in walking the + *                 page table to node.  Optional: only used if vaddr_pte is set. + * @vaddr_pte - Optional pointer to a variable storing the virtual address bits
+ *              translated by node[i].
+ * @pte_paddr - Pointer to the physical address of the PTE within node.
+ *              Optional parameter.
+ */
+void
+x86_get_pte(CPUState *cs, hwaddr node, int i, int height,
+            PTE_t *pt_entry, vaddr vaddr_parent, vaddr *vaddr_pte,
+            hwaddr *pte_paddr)
+
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+    int32_t a20_mask = x86_get_a20_mask(env);
+    hwaddr pte;
+
+    if (env->hflags & HF_LMA_MASK) {
+        /* 64 bit */
+        int pte_width = 8;
+        pte = (node + (i * pte_width)) & a20_mask;
+        pt_entry->pte64_t = address_space_ldq(cs->as, pte,
+ MEMTXATTRS_UNSPECIFIED, NULL);
+    } else {
+        /* 32 bit */
+        int pte_width = 4;
+        pte = (node + (i * pte_width)) & a20_mask;
+        pt_entry->pte32_t = address_space_ldl(cs->as, pte,
+ MEMTXATTRS_UNSPECIFIED, NULL);
+    }
+
+    if (vaddr_pte) {
+        int shift = 0;
+        _mmu_decode_va_parameters(cs, height, &shift, NULL);
+        *vaddr_pte = vaddr_parent | ((i & 0x1ffULL) << shift);
+    }
+
+    if (pte_paddr) {
+        *pte_paddr = pte;
+    }
+}

This fails to recurse with nested page tables, which definitely breaks the TCG walker.

Hi Richard,

Thank you again for all of the advice and feedback.

What do you think the correct semantics should be for nested paging?

My understanding is that the current 'info mem' command on x86 does not recur on nested page tables, but this does seem like a useful extension.  Same for 'info tlb'.

In the case of 'info pg', I might want to print each page table separately, rather than a combined/shadow view.

My reading of the tcg code is that it also walks the guest page tables first, then uses probe_access_full() to query the guest->host physical translation, but I may be misunderstanding the code: https://github.com/qemu/qemu/blob/046a64b9801343e2e89eef10c7a48eec8d8c0d4f/target/i386/tcg/sysemu/excp_helper.c#L432

In patch 6 of the series, I replace the chunk of mmu_translate() in tcg that walks the guest page tables, but leave the portion alone that does the nested page walk.

I'm open to implementing a nested walker, but it might be better not to add more functionality/changes to this patch series.

Thank you,

Don


Reply via email to