HYPERVISOR_mmu_update passes a set of request, where each request has a pointer
to the PTE along with a sub-command.
The PTE alignment padding is used to transport the sub-command while the rest
is used as a address to a PTE entry. The current documentation state that the
2 first bits are used for sub-command, hence the other ones for PTE which
imply here a 4-bytes alignment on PTEs.
On PV64 and PV32-PAE guests, all pagetable PTEs are 8-bytes aligned, hence
off-by-4 PTEs addresses are always incorrect. Non-PAE PV32 guests used
"legacy pagetables" which had 4-byte aligned PTEs. However, support had
been completely removed since Xen 4.0, and were only available when Xen was
built in 32-bits non-PAE mode [1].
Current Xen logic behave as if 3 bits are used as sub-command, thus all
off-by-4 PTEs are actually rejected as being unknown sub-commands.
Adjust the documentation to match the current logic implemented in Xen,
also expanding the documented sub-command parameter to 3 bits.
[1] 84d54d5d8b31 ("i386: Remove non-PAE hypervisor build target.")
Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
---
This happens to be a complete rewording of [2]. I'm not sure what to do exactly
regarding the signed-off.
CC: Kevin Lampis <kevin.lampis@citrix.com>
This now expanded sub-command field can be used for your "unmap_page_range optimisation"
series to avoid having to introduce a new dedicated hypercall.
[2] https://lore.kernel.org/xen-devel/20260528075539.10209-3-frediano.ziglio@cloud.com/
xen/include/public/xen.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index 2149b8dd38..b4fef2c5ba 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -218,16 +218,16 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
* x == 0 => PFD == DOMID_SELF
* x != 0 => PFD == x - 1
*
- * Sub-commands: ptr[1:0] specifies the appropriate MMU_* command.
+ * Sub-commands: ptr[2:0] specifies the appropriate MMU_* command.
* -------------
- * ptr[1:0] == MMU_NORMAL_PT_UPDATE:
+ * ptr[2:0] == MMU_NORMAL_PT_UPDATE:
* Updates an entry in a page table belonging to PFD. If updating an L1 table,
* and the new table entry is valid/present, the mapped frame must belong to
* FD. If attempting to map an I/O page then the caller assumes the privilege
* of the FD.
* FD == DOMID_IO: Permit /only/ I/O mappings, at the priv level of the caller.
* FD == DOMID_XEN: Map restricted areas of Xen's heap space.
- * ptr[:2] -- Machine address of the page-table entry to modify.
+ * ptr[:3] -- Machine address of the page-table entry to modify.
* val -- Value to write.
*
* There also certain implicit requirements when using this hypercall. The
@@ -264,17 +264,17 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
* mentioned above. The argument is MMUEXT_UNPIN_TABLE for all levels and the
* pagetable MUST not be in use (meaning that the cr3 is not set to it).
*
- * ptr[1:0] == MMU_MACHPHYS_UPDATE:
+ * ptr[2:0] == MMU_MACHPHYS_UPDATE:
* Updates an entry in the machine->pseudo-physical mapping table.
- * ptr[:2] -- Machine address within the frame whose mapping to modify.
+ * ptr[:3] -- Machine address within the frame whose mapping to modify.
* The frame must belong to the FD, if one is specified.
* val -- Value to write into the mapping entry.
*
- * ptr[1:0] == MMU_PT_UPDATE_PRESERVE_AD:
+ * ptr[2:0] == MMU_PT_UPDATE_PRESERVE_AD:
* As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are ORed
* with those in @val.
*
- * ptr[1:0] == MMU_PT_UPDATE_NO_TRANSLATE:
+ * ptr[2:0] == MMU_PT_UPDATE_NO_TRANSLATE:
* As MMU_NORMAL_PT_UPDATE above, but @val is not translated though FD
* page tables.
*
--
2.54.0
--
| Vates
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
On 07.08.2026 23:28, Teddy Astie wrote:
> HYPERVISOR_mmu_update passes a set of request, where each request has a pointer
> to the PTE along with a sub-command.
>
> The PTE alignment padding is used to transport the sub-command while the rest
> is used as a address to a PTE entry. The current documentation state that the
> 2 first bits are used for sub-command, hence the other ones for PTE which
> imply here a 4-bytes alignment on PTEs.
>
> On PV64 and PV32-PAE guests, all pagetable PTEs are 8-bytes aligned, hence
> off-by-4 PTEs addresses are always incorrect. Non-PAE PV32 guests used
> "legacy pagetables" which had 4-byte aligned PTEs. However, support had
> been completely removed since Xen 4.0, and were only available when Xen was
> built in 32-bits non-PAE mode [1].
>
> Current Xen logic behave as if 3 bits are used as sub-command, thus all
> off-by-4 PTEs are actually rejected as being unknown sub-commands.
>
> Adjust the documentation to match the current logic implemented in Xen,
> also expanding the documented sub-command parameter to 3 bits.
>
> [1] 84d54d5d8b31 ("i386: Remove non-PAE hypervisor build target.")
>
> Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
> ---
> This happens to be a complete rewording of [2]. I'm not sure what to do exactly
> regarding the signed-off.
I think the patch here nevertheless should have been v2, with original authorship
retained. It looks largely okay to me (with Frediano's nits addressed). I think,
though that ...
> --- a/xen/include/public/xen.h
> +++ b/xen/include/public/xen.h
> @@ -218,16 +218,16 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
> * x == 0 => PFD == DOMID_SELF
> * x != 0 => PFD == x - 1
> *
> - * Sub-commands: ptr[1:0] specifies the appropriate MMU_* command.
> + * Sub-commands: ptr[2:0] specifies the appropriate MMU_* command.
> * -------------
> - * ptr[1:0] == MMU_NORMAL_PT_UPDATE:
> + * ptr[2:0] == MMU_NORMAL_PT_UPDATE:
> * Updates an entry in a page table belonging to PFD. If updating an L1 table,
> * and the new table entry is valid/present, the mapped frame must belong to
> * FD. If attempting to map an I/O page then the caller assumes the privilege
> * of the FD.
> * FD == DOMID_IO: Permit /only/ I/O mappings, at the priv level of the caller.
> * FD == DOMID_XEN: Map restricted areas of Xen's heap space.
> - * ptr[:2] -- Machine address of the page-table entry to modify.
> + * ptr[:3] -- Machine address of the page-table entry to modify.
> * val -- Value to write.
> *
> * There also certain implicit requirements when using this hypercall. The
> @@ -264,17 +264,17 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
> * mentioned above. The argument is MMUEXT_UNPIN_TABLE for all levels and the
> * pagetable MUST not be in use (meaning that the cr3 is not set to it).
> *
> - * ptr[1:0] == MMU_MACHPHYS_UPDATE:
> + * ptr[2:0] == MMU_MACHPHYS_UPDATE:
> * Updates an entry in the machine->pseudo-physical mapping table.
> - * ptr[:2] -- Machine address within the frame whose mapping to modify.
> + * ptr[:3] -- Machine address within the frame whose mapping to modify.
> * The frame must belong to the FD, if one is specified.
> * val -- Value to write into the mapping entry.
> *
> - * ptr[1:0] == MMU_PT_UPDATE_PRESERVE_AD:
> + * ptr[2:0] == MMU_PT_UPDATE_PRESERVE_AD:
> * As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are ORed
> * with those in @val.
> *
> - * ptr[1:0] == MMU_PT_UPDATE_NO_TRANSLATE:
> + * ptr[2:0] == MMU_PT_UPDATE_NO_TRANSLATE:
> * As MMU_NORMAL_PT_UPDATE above, but @val is not translated though FD
> * page tables.
> *
... at least retaining some reference to the non-PAE situation would be helpful.
Jan
>CC: Kevin Lampis <kevin.lampis@citrix.com> >This now expanded sub-command field can be used for your "unmap_page_range optimisation" >series to avoid having to introduce a new dedicated hypercall. Thank you.
On Fri, 7 Aug 2026 at 22:29, Teddy Astie <teddy.astie@vates.tech> wrote:
>
> HYPERVISOR_mmu_update passes a set of request, where each request has a pointer
> to the PTE along with a sub-command.
>
> The PTE alignment padding is used to transport the sub-command while the rest
> is used as a address to a PTE entry. The current documentation state that the
"an address"
> 2 first bits are used for sub-command, hence the other ones for PTE which
> imply here a 4-bytes alignment on PTEs.
>
> On PV64 and PV32-PAE guests, all pagetable PTEs are 8-bytes aligned, hence
> off-by-4 PTEs addresses are always incorrect. Non-PAE PV32 guests used
> "legacy pagetables" which had 4-byte aligned PTEs. However, support had
> been completely removed since Xen 4.0, and were only available when Xen was
"was only available"
> built in 32-bits non-PAE mode [1].
>
> Current Xen logic behave as if 3 bits are used as sub-command, thus all
"behaves"
> off-by-4 PTEs are actually rejected as being unknown sub-commands.
>
> Adjust the documentation to match the current logic implemented in Xen,
> also expanding the documented sub-command parameter to 3 bits.
>
> [1] 84d54d5d8b31 ("i386: Remove non-PAE hypervisor build target.")
>
> Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
> ---
> This happens to be a complete rewording of [2]. I'm not sure what to do exactly
> regarding the signed-off.
>
You should use them both.
> CC: Kevin Lampis <kevin.lampis@citrix.com>
> This now expanded sub-command field can be used for your "unmap_page_range optimisation"
> series to avoid having to introduce a new dedicated hypercall.
>
> [2] https://lore.kernel.org/xen-devel/20260528075539.10209-3-frediano.ziglio@cloud.com/
>
> xen/include/public/xen.h | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
> index 2149b8dd38..b4fef2c5ba 100644
> --- a/xen/include/public/xen.h
> +++ b/xen/include/public/xen.h
> @@ -218,16 +218,16 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
> * x == 0 => PFD == DOMID_SELF
> * x != 0 => PFD == x - 1
> *
> - * Sub-commands: ptr[1:0] specifies the appropriate MMU_* command.
> + * Sub-commands: ptr[2:0] specifies the appropriate MMU_* command.
> * -------------
> - * ptr[1:0] == MMU_NORMAL_PT_UPDATE:
> + * ptr[2:0] == MMU_NORMAL_PT_UPDATE:
> * Updates an entry in a page table belonging to PFD. If updating an L1 table,
> * and the new table entry is valid/present, the mapped frame must belong to
> * FD. If attempting to map an I/O page then the caller assumes the privilege
> * of the FD.
> * FD == DOMID_IO: Permit /only/ I/O mappings, at the priv level of the caller.
> * FD == DOMID_XEN: Map restricted areas of Xen's heap space.
> - * ptr[:2] -- Machine address of the page-table entry to modify.
> + * ptr[:3] -- Machine address of the page-table entry to modify.
> * val -- Value to write.
> *
> * There also certain implicit requirements when using this hypercall. The
> @@ -264,17 +264,17 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
> * mentioned above. The argument is MMUEXT_UNPIN_TABLE for all levels and the
> * pagetable MUST not be in use (meaning that the cr3 is not set to it).
> *
> - * ptr[1:0] == MMU_MACHPHYS_UPDATE:
> + * ptr[2:0] == MMU_MACHPHYS_UPDATE:
> * Updates an entry in the machine->pseudo-physical mapping table.
> - * ptr[:2] -- Machine address within the frame whose mapping to modify.
> + * ptr[:3] -- Machine address within the frame whose mapping to modify.
> * The frame must belong to the FD, if one is specified.
> * val -- Value to write into the mapping entry.
> *
> - * ptr[1:0] == MMU_PT_UPDATE_PRESERVE_AD:
> + * ptr[2:0] == MMU_PT_UPDATE_PRESERVE_AD:
> * As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are ORed
> * with those in @val.
> *
> - * ptr[1:0] == MMU_PT_UPDATE_NO_TRANSLATE:
> + * ptr[2:0] == MMU_PT_UPDATE_NO_TRANSLATE:
> * As MMU_NORMAL_PT_UPDATE above, but @val is not translated though FD
> * page tables.
> *
Frediano
© 2016 - 2026 Red Hat, Inc.