|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v1 2/2] x86/viridian: Implement synthetic timer direct mode
On 28/08/2026 15:14, 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.
Hello, is this new behavior compared to Server 2025? What happens if
direct mode is not available, does it fall back to disabling stimer?
>
> Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
> ---
>
> Should this use a new Viridian feature bit or is it OK to use the
> existing stimer bit?
>
> xen/arch/x86/hvm/viridian/time.c | 25 +++++++++++++++++++------
> xen/arch/x86/hvm/viridian/viridian.c | 3 +++
> 2 files changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/viridian/time.c
> b/xen/arch/x86/hvm/viridian/time.c
> index 082528dc9416..2b0ac3eac963 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, struct viridian_stimer *vs)
> +{
> + struct vlapic *vlapic = vcpu_vlapic(v);
> +
> + if ( vlapic_enabled(vlapic) )
> + vlapic_set_irq(vcpu_vlapic(v), 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);
> @@ -372,7 +382,7 @@ int viridian_time_wrmsr(struct vcpu *v, uint32_t idx,
> uint64_t val)
>
> vs->config.as_uint64 = val;
>
> - if ( !vs->config.sintx || !vs->count )
> + if ( (!vs->config.direct_mode && !vs->config.sintx) || !vs->count )
> vs->config.enable = 0;
>
> if ( vs->config.enable )
> @@ -583,8 +593,11 @@ void viridian_time_load_vcpu_ctxt(
>
> vs->config.as_uint64 = ctxt->stimer_config_msr[i];
> vs->count = ctxt->stimer_count_msr[i];
> - if ( !vs->config.sintx || !vs->count )
> - /* Reject enabling with a zero sintx or count fields. */
> + if ( (!vs->config.direct_mode && !vs->config.sintx) || !vs->count )
> + /*
> + * Reject enabling with a zero sintx (if not using direct mode)
> or
> + * zero count field.
> + */
> vs->config.enable = 0;
> }
> }
> diff --git a/xen/arch/x86/hvm/viridian/viridian.c
> b/xen/arch/x86/hvm/viridian/viridian.c
> index 90e749ceb581..99192e8d077d 100644
> --- a/xen/arch/x86/hvm/viridian/viridian.c
> +++ b/xen/arch/x86/hvm/viridian/viridian.c
> @@ -78,6 +78,7 @@ typedef union _HV_CRASH_CTL_REG_CONTENTS
> #define CPUID3D_CPU_DYNAMIC_PARTITIONING (1 << 3)
> #define CPUID3D_CRASH_MSRS (1 << 10)
> #define CPUID3D_SINT_POLLING (1 << 17)
> +#define CPUID3D_STIMER_DIRECT_MODE (1 << 19)
>
> /* Viridian CPUID leaf 4: Implementation Recommendations. */
> #define CPUID4A_HCALL_REMOTE_TLB_FLUSH (1 << 2)
> @@ -185,6 +186,8 @@ void cpuid_viridian_leaves(const struct vcpu *v, uint32_t
> leaf,
> res->d |= CPUID3D_CRASH_MSRS;
> if ( viridian_feature_mask(d) & HVMPV_synic )
> res->d |= CPUID3D_SINT_POLLING;
> + if ( viridian_feature_mask(d) & HVMPV_stimer )
> + res->d |= CPUID3D_STIMER_DIRECT_MODE;
>
> break;
> }
--
Ngoc Tu Dinh | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |