[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/5] xen/riscv: always set A/D bits at boot time



On 2026-08-28 18:12 +0200, Oleksii Kurochko wrote:
> 
> 
> On 8/28/26 3:58 PM, Baptiste Le Duc wrote:
> > On 2026-08-28 12:59 +0200, Oleksii Kurochko wrote:
> >>
> >>
> >> On 8/27/26 5:33 PM, Baptiste Le Duc wrote:
> >>> Always set the PTE A/D bits at boot time to avoid an unhandled page fault
> >>> on platforms that implement neither Svade nor Svadu, and on platforms that
> >>> declare both in the device tree.
> >>>
> >>> Rewrite the comment to enumerate the four possible Svade/Svadu 
> >>> combinations
> >>> (inspired by [1]) and set A/D unconditionally, which is correct in all 
> >>> four
> >>> cases until Svadu is fully supported (full support requires the SBI FWFT
> >>> call to enable hardware updating of A/D bits).
> >>>
> >>> [1] https://lwn.net/Articles/980016/
> >>>
> >>> Assisted-by: Claude:claude-opus-5
> >>> Signed-off-by: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>
> >>> ---
> >>>    xen/arch/riscv/p2m.c | 70 ++++++++++++++++++++++++++------------------
> >>>    1 file changed, 42 insertions(+), 28 deletions(-)
> >>>
> >>> diff --git a/xen/arch/riscv/p2m.c b/xen/arch/riscv/p2m.c
> >>> index 1cea86512c..11dc289f0f 100644
> >>> --- a/xen/arch/riscv/p2m.c
> >>> +++ b/xen/arch/riscv/p2m.c
> >>> @@ -591,38 +591,52 @@ static void p2m_set_permission(pte_t *e, p2m_type_t 
> >>> t)
> >>>        e->pte |= PTE_USER;
> >>>    
> >>>        /*
> >>> -     * Two schemes to manage the A and D bits are defined:
> >>> -     *   • The Svade extension: when a virtual page is accessed and the 
> >>> A bit
> >>> -     *     is clear, or is written and the D bit is clear, a page-fault
> >>> -     *     exception is raised.
> >>> -     *   • When the Svade extension is not implemented, the following 
> >>> scheme
> >>> -     *     applies.
> >>> -     *     When a virtual page is accessed and the A bit is clear, the 
> >>> PTE is
> >>> -     *     updated to set the A bit. When the virtual page is written 
> >>> and the
> >>> -     *     D bit is clear, the PTE is updated to set the D bit. When 
> >>> G-stage
> >>> -     *     address translation is in use and is not Bare, the G-stage 
> >>> virtual
> >>> -     *     pages may be accessed or written by implicit accesses to 
> >>> VS-level
> >>> -     *     memory management data structures, such as page tables.
> >>> -     * Thereby to avoid a page-fault in case of Svade is available, it is
> >>> -     * necessary to set A and D bits.
> >>> +     * Svade and Svadu extensions represent two schemes for managing the 
> >>> PTE
> >>> +     * A/D bits. When the PTE A/D bits need to be set, the Svade 
> >>> extension
> >>> +     * indicates that a page fault will be raised. In contrast, the Svadu
> >>> +     * extension supports hardware updating of the PTE A/D bits.
> >>>         *
> >>> -     * TODO: For now, it’s fine to simply set the A/D bits, since OpenSBI
> >>> -     *       delegates page faults to a lower privilege mode and so 
> >>> OpenSBI
> >>> -     *       isn't expect to handle page-faults occured in lower modes.
> >>> -     *       By setting the A/D bits here, page faults that would 
> >>> otherwise
> >>> -     *       be generated due to unset A/D bits will not occur in Xen.
> >>> +     * There are 4 possible combinations of these extensions in the 
> >>> device
> >>> +     * tree. The default hardware behavior for each is:
> >>>         *
> >>> -     *       Currently, Xen on RISC-V does not make use of the 
> >>> information
> >>> -     *       that could be obtained from handling such page faults, which
> >>> -     *       could otherwise be useful for several use cases such as 
> >>> demand
> >>> -     *       paging, cache-flushing optimizations, memory access 
> >>> tracking,etc.
> >>> +     * 1) Neither Svade nor Svadu present in DT => It is technically 
> >>> unknown
> >>> +     *    whether the platform uses Svade or Svadu. Xen should be 
> >>> prepared to
> >>> +     *    handle either hardware updating of the PTE A/D bits or page 
> >>> faults
> >>> +     *    when they need updating. To support both, Xen always sets the 
> >>> 'A' and
> >>> +     *    'D' PTE bits at boot time.
> >>>         *
> >>> -     *       To support the more general case and the optimizations 
> >>> mentioned
> >>> -     *       above, it would be better to stop setting the A/D bits here 
> >>> and
> >>> -     *       instead handle page faults that occur due to unset A/D bits.
> >>> +     * 2) Only Svade present in DT => Xen must assume Svade to be always
> >>> +     *    enabled.
> >>> +     *
> >>> +     * 3) Only Svadu present in DT => Xen must assume Svadu to be always
> >>> +     *    enabled.
> >>> +     *
> >>> +     * 4) Both Svade and Svadu present in DT => Xen must assume Svadu is 
> >>> turned
> >>> +     *    off at boot time by setting A/D bits. To use Svadu, the 
> >>> supervisor
> >>> +     *    must explicitly enable it using the SBI FWFT extension.
> >>> +     *
> >>> +     * The Svade extension is mandatory and the Svadu extension is 
> >>> optional in
> >>> +     * the RVA23 profile. Platforms wanting to take advantage of Svadu 
> >>> can
> >>> +     * choose option 3. Platforms aware of the profile can choose option 
> >>> 4, and
> >>> +     * Linux won't get the benefit of Svadu until the SBI FWFT extension 
> >>> is
> >>> +     * available.
> >>
> >> I have a feeling that the DT-binding-related comment should not be
> >> present here, as it explains when Svadu or Svade should be considered
> >> enabled or disabled. We should perform this kind of detection in
> >> riscv_fill_hwcap() [cpufeature.c]. Then, in p2m_set_permission(), we
> >> should use riscv_isa_extension_available() to determine which extension
> >> is available and, based on that, set the A and D bits.
> >>
> >> At this point, I think the original comment was better, as it simply
> >> explained what Svade and Svadu are and, therefore, provided a better
> >> explanation of why the A and D bits should or should not be set.
> >>
> >> So, my suggestion is the following:
> >>
> >> +/*
> >> + * Svade and Svadu extensions represent two schemes for managing the PTE
> >> + * A/D bits. When the PTE A/D bits need to be set, the Svade extension
> >> + * indicates that a page fault will be raised. In contrast, the Svadu
> >> + * extension supports hardware updating of the PTE A/D bits.
> >> + *
> >> + * There are 4 possible combinations of these extensions in the device
> >> tree.
> >> + * The default hardware behavior for each is:
> >> + *
> >> + * 1) Neither Svade nor Svadu present in DT => It is technically unknown
> >> + *    whether the platform uses Svade or Svadu. Xen should be prepared to
> >> + *    handle either hardware updating of the PTE A/D bits or page
> >> faults when
> >> + *    they need updating. To support both, Xen always sets the 'A' and
> >> 'D' PTE
> >> + *    bits at boot time.
> >> + *
> >> + * 2) Only Svade present in DT => Xen must assume Svade to be always
> >> enabled.
> >> + *
> >> + * 3) Only Svadu present in DT => Xen must assume Svadu to be always
> >> enabled.
> >> + *
> >> + * 4) Both Svade and Svadu present in DT => Xen must assume Svadu is 
> >> turned
> >> + *    off at boot time by setting A/D bits. To use Svadu, the
> >> supervisor must
> >> + *    explicitly enable it using the SBI FWFT extension.
> >> + *
> >> + * The Svade extension is mandatory and the Svadu extension is optional
> >> in the
> >> + * RVA23 profile. Platforms wanting to take advantage of Svadu can choose
> >> + * option 3. Platforms aware of the profile can choose option 4, and
> >> Xen won't
> >> + * get the benefit of Svadu until the SBI FWFT extension is available.
> >> + *
> >> + * In other words, hardware manages the A/D bits on its own only in case 
> >> 3;
> >> + * in all the other cases software has to preset them. Instead of open
> >> coding
> >> + * this in every A/D bits user, RISCV_ISA_EXT_svade is used to mean
> >> "software
> >> + * is responsible for the A/D bits" and is set here for the cases 1, 2
> >> and 4.
> >> + */
> >> +static void __init riscv_resolve_ad_scheme(void)
> >> +{
> >> +    bool svade = riscv_isa_extension_available(NULL, RISCV_ISA_EXT_svade);
> >> +    bool svadu = riscv_isa_extension_available(NULL, RISCV_ISA_EXT_svadu);
> >> +
> >> +    /* Case 3: leave the A/D bits management to hardware. */
> >> +    if ( svadu && !svade )
> >> +        return;
> >> +
> >> +    /* Cases 1, 2 and 4: Xen has to preset the A/D bits. */
> >> +    __set_bit(RISCV_ISA_EXT_svade, riscv_isa);
> >> +}
> >> +
> >>    void __init riscv_fill_hwcap(void)
> >>    {
> >>        unsigned int i;
> >> @@ -513,6 +560,8 @@ void __init riscv_fill_hwcap(void)
> >>            __set_bit(RISCV_ISA_EXT_sstc, riscv_isa);
> >>        }
> >>
> >> +    riscv_resolve_ad_scheme();
> >> +
> >>
> >> And then ...
> >>
> >>
> >>> +     *
> >>> +     * Currently, Xen on RISC-V does not make use of the information 
> >>> that could
> >>> +     * be obtained from handling such page faults, which could otherwise 
> >>> be
> >>> +     * useful for several use cases such as demand paging, cache-flushing
> >>> +     * optimizations, memory access tracking, etc.
> >>> +     *
> >>> +     * To support the more general case and the optimizations mentioned 
> >>> above,
> >>> +     * it would be better to stop setting the A/D bits here and instead 
> >>> handle
> >>> +     * page faults that occur due to unset A/D bits.
> >>> +     */
> >>> +
> >>> +    /*
> >>> +     * Preset unconditionally for all 4 cases above, harmless when Svadu
> >>> +     * manages the bits (case 3). Skipping it for case 3 requires SBI 
> >>> FWFT
> >>> +     * which is not yet supported.
> >>>         */
> >>> -    if ( riscv_isa_extension_available(NULL, RISCV_ISA_EXT_svade) )
> >>> -        e->pte |= PTE_ACCESSED | PTE_DIRTY;
> >>> +    e->pte |= PTE_ACCESSED | PTE_DIRTY;
> >>
> >> ... we could restore the check and the comment we originally had in
> > 
> > Yes it makes sense as we now manually force the svade extension in 1, 2
> > and 4 cases.
> > 
> >> p2m_set_permission(), but probably with some updates, something along
> >> the following lines:
> >>
> >> /*
> >>    * Xen has to preset the A/D bits unless the hardware is known to update
> >>    * them on its own. riscv_fill_hwcap() folds all the Svade/Svadu device
> >>    * tree combinations into RISCV_ISA_EXT_svade, which then means that
> >>    * software is responsible for the A/D bits" (see
> >>    * riscv_resolve_ad_scheme()).
> >>    */
> >>
> >> I have another comment regarding:
> >>
> >>   > +    /*
> >>   > +     * Preset unconditionally for all 4 cases above, harmless when 
> >> Svadu
> >>   > +     * manages the bits (case 3). Skipping it for case 3 requires
> >> SBI FWFT
> >>   > +     * which is not yet supported.
> >>   >        */
> >>   > -    if ( riscv_isa_extension_available(NULL, RISCV_ISA_EXT_svade) )
> >>   > -        e->pte |= PTE_ACCESSED | PTE_DIRTY;
> >>   > +    e->pte |= PTE_ACCESSED | PTE_DIRTY;
> >>
> >> I am not sure that this comment is correct. In case 3, we should not
> >> need to use the SBI FWFT extension. Case 3 means that Xen must assume
> >> that Svadu is enabled. Therefore, it is the responsibility of OpenSBI,
> >> or the pre-bootloader that loads OpenSBI, to enable it. If it fails to
> >> do so, then OpenSBI or the pre-bootloader is not complying with the DT
> >> binding documentation and it should be fixed in first place.
> > 
> > You right, thanks
> >>
> >> As further evidence, this is what OpenSBI already does [1]:
> >> /*
> >>    * Assume only Svadu is supported when it is the only extension
> >>    * present in the ISA string. Svade is assumed when neither are
> >>    * present. When both are present we must default to Svade (see
> >>    * the zero reset value of FWFT.PTE_AD_HW_UPDATING).
> >>    */
> >> if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SVADE))
> >>       __set_menvcfg_ext(SBI_HART_EXT_SVADU, ENVCFG_ADUE);
> >>
> >> Therefore, in case 3, the original check is still valid, and there is no
> >> need for Xen to support the SBI FWFT extension for this case. I think
> >> the original check should therefore be kept as it was:
> > 
> > Yes agree, I'll change that in v2.
> > 
> >> if ( riscv_isa_extension_available(NULL, RISCV_ISA_EXT_svade) )
> >>       e->pte |= PTE_ACCESSED | PTE_DIRTY;
> >>
> >> The SBI FWFT extension is only required for case 4. If both Svade and
> >> Svadu are present in the DT, Svade is selected by default. To use Svadu
> >> instead, SBI FWFT is required to set the ADUE bit in menvcfg, which is
> >> only accessible from M-mode.
> >>
> >> Since SBI FWFT is relatively new and may not be supported by older
> >> OpenSBI versions, another option is to have OpenSBI hard-code ADUE=1.
> >> Alternatively, the DTS could specify only one of Svade or Svadu in the
> >> riscv,isa property. In that case, upstream OpenSBI can handle the
> >> configuration automatically. So specifically for our case (Svadu and
> >> Svade things) we don't need SBI FWFT at all.
> > 
> > So if I understood correclty, you want to not let the option to change
> > ADUE bits in case 4 right? Therefore, I think we should document that
> > somewhere to clearly indicates that if someone want to use Svadu, he
> > should remove `svade` in the riscv,isa DT property.
> 
> Yes, that is exactly correct. Without SBI FWFT support, Xen cannot 
> toggle menvcfg.ADUE in Case 4. Thus, the only viable workaround to use 
> Svadu is to remove 'svade' from the riscv,isa DT property (Case 3), 
> which prompts OpenSBI to enable ADUE=1 at boot time.
> 
> I agree document that somewhere will make this behavior/intention clear!
> 
> Not insisting on that:
> I also think it would be a good idea to add an early printk() warning in 
> the detection logic when both Svade and Svadu are present but SBI FWFT 
> is missing, guiding users to drop 'svade' from their DT if they want to 
> leverage Svadu. Something like:
> 
> if ( svade && svadu )
> {
>      /* Assuming sbi_fwft_is_supported() or similar probe is available */
>      if ( !sbi_probe_extension(SBI_EXT_FWFT) )
>      {
>          printk(XENLOG_WARNING
>                 "RISC-V: Both Svade and Svadu detected, but SBI FWFT is 
> missing.\n"
>                 "RISC-V: Defaulting to software A/D updates (Svade).\n"
>                 "RISC-V: To force hardware A/D updates (Svadu), remove 
> 'svade' from DT.\n");
>      }
> }
> 
> somewhere in the function (riscv_resolve_ad_scheme) I suggested above.

Agree, it'll be better. I'm going to apply that in v2
> 
> >>
> >> [1]
> >> https://github.com/riscv-software-src/opensbi/blob/master/lib/sbi/sbi_hart.c#L171
> >>
> > Thanks for this very clear review.
> 
> Welcome.
> 
> ~ Oleksii
> 
> 
> 





 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.