|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode
On Fri, Sep 04, 2026 at 03:15:15PM +0100, Ross Lagerwall wrote:
> In direct mode, the timer asserts an interrupt on expiration rather than
> using a SynIC message. It is useful to implement this since Windows 11's
> Hyper-V can only use synthetic timers in direct mode.
>
> Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
> ---
>
> In v2:
>
> * Handle migration from older Xen by introducing a new Viridian flag.
> * Added more sanity checks during MSR write and vCPU context load.
>
> xen/arch/x86/hvm/viridian/time.c | 46 ++++++++++++++++++++++++----
> xen/arch/x86/hvm/viridian/viridian.c | 3 ++
> xen/include/public/hvm/params.h | 7 ++++-
> 3 files changed, 49 insertions(+), 7 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/viridian/time.c
> b/xen/arch/x86/hvm/viridian/time.c
> index 082528dc9416..4c8352612b19 100644
> --- a/xen/arch/x86/hvm/viridian/time.c
> +++ b/xen/arch/x86/hvm/viridian/time.c
> @@ -223,6 +223,14 @@ static void start_stimer(struct viridian_stimer *vs)
> set_timer(&vs->timer, timeout + NOW());
> }
>
> +static void stimer_deliver_direct(struct vcpu *v, const struct
> viridian_stimer *vs)
> +{
> + struct vlapic *vlapic = vcpu_vlapic(v);
> +
> + if ( vlapic_enabled(vlapic) )
> + vlapic_set_irq(vlapic, vs->config.apic_vector, 0);
> +}
> +
> static void poll_stimer(struct vcpu *v, unsigned int stimerx)
> {
> struct viridian_vcpu *vv = v->arch.hvm.viridian;
> @@ -242,9 +250,11 @@ static void poll_stimer(struct vcpu *v, unsigned int
> stimerx)
> if ( !test_bit(stimerx, &vv->stimer_pending) )
> return;
>
> - if ( !viridian_synic_deliver_timer_msg(v, vs->config.sintx,
> - stimerx, vs->expiration,
> - time_ref_count(v->domain)) )
> + if ( vs->config.direct_mode )
> + stimer_deliver_direct(v, vs);
> + else if ( !viridian_synic_deliver_timer_msg(v, vs->config.sintx,
> + stimerx, vs->expiration,
> + time_ref_count(v->domain)) )
> return;
>
> clear_bit(stimerx, &vv->stimer_pending);
> @@ -361,6 +371,7 @@ int viridian_time_wrmsr(struct vcpu *v, uint32_t idx,
> uint64_t val)
> case HV_X64_MSR_STIMER2_CONFIG:
> case HV_X64_MSR_STIMER3_CONFIG:
> {
> + union hv_stimer_config new;
> unsigned int stimerx = (idx - HV_X64_MSR_STIMER0_CONFIG) / 2;
> struct viridian_stimer *vs =
> &array_access_nospec(vv->stimer, stimerx);
> @@ -368,11 +379,18 @@ int viridian_time_wrmsr(struct vcpu *v, uint32_t idx,
> uint64_t val)
> if ( !(viridian_feature_mask(d) & HVMPV_stimer) )
> return X86EMUL_EXCEPTION;
>
> + new.as_uint64 = val;
> + if ( new.direct_mode &&
> + !(viridian_feature_mask(d) & HVMPV_stimer_direct) )
> + return X86EMUL_EXCEPTION;
Do we know whether native HyperV also injects a #GP in case of setting
reserved bits on the register?
To keep the previous behavior, should Xen silently ignore the setting
when not supported, like it did in the past?
Thanks, Roger.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |