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