* [PATCH v2 0/3] Viridian changes for Hyper-V as a guest
@ 2026-09-04 14:15 Ross Lagerwall
2026-09-04 14:15 ` [PATCH v2 1/3] x86/viridian: Workaround Hyper-V GP fault writing to MSR Ross Lagerwall
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Ross Lagerwall @ 2026-09-04 14:15 UTC (permalink / raw)
To: xen-devel
Cc: Ross Lagerwall, Paul Durrant, Jan Beulich, Andrew Cooper,
Roger Pau Monné, Teddy Astie, Anthony PERARD, Michal Orzel,
Julien Grall, Stefano Stabellini, Juergen Gross
Hi,
Here are some changes to get the existing Virdian enlightenments working
when running a Windows 11 guest with Hyper-V enabled
Hyper-V also depends on some unimplemented MSRs to boot, but that will
be addressed in a separate series.
Thanks,
Ross
Ross Lagerwall (3):
x86/viridian: Workaround Hyper-V GP fault writing to MSR
x86/viridian: Implement synthetic timer direct mode
tools/libxl: Add support for Viridian stimer direct mode
docs/man/xl.cfg.5.pod.in | 5 +++
tools/include/libxl.h | 6 ++++
tools/libs/light/libxl_types.idl | 1 +
tools/libs/light/libxl_x86.c | 5 +++
xen/arch/x86/hvm/viridian/synic.c | 8 +++++
xen/arch/x86/hvm/viridian/time.c | 46 ++++++++++++++++++++++++----
xen/arch/x86/hvm/viridian/viridian.c | 3 ++
xen/include/public/hvm/params.h | 7 ++++-
8 files changed, 74 insertions(+), 7 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 1/3] x86/viridian: Workaround Hyper-V GP fault writing to MSR 2026-09-04 14:15 [PATCH v2 0/3] Viridian changes for Hyper-V as a guest Ross Lagerwall @ 2026-09-04 14:15 ` Ross Lagerwall 2026-09-04 14:53 ` Roger Pau Monné 2026-09-04 14:15 ` [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode Ross Lagerwall 2026-09-04 14:15 ` [PATCH v2 3/3] tools/libxl: Add support for Viridian stimer " Ross Lagerwall 2 siblings, 1 reply; 11+ messages in thread From: Ross Lagerwall @ 2026-09-04 14:15 UTC (permalink / raw) To: xen-devel Cc: Ross Lagerwall, Paul Durrant, Jan Beulich, Andrew Cooper, Roger Pau Monné, Teddy Astie The Viridian spec requires the vector to be >= 0x10 when writing to the SINTx MSR, otherwise it should #GP fault. The spec-defined initial value is 0x0000000000010000, i.e. the vector is 0. On startup, for some reason Windows 11 Hyper-V tries to set the MSR to the spec-defined initial value and since the vector is 0, it GP faults. To workaround this, treat the write as a no-op if the value is unchanged. Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com> --- In v2: Added a comment to clarify xen/arch/x86/hvm/viridian/synic.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xen/arch/x86/hvm/viridian/synic.c b/xen/arch/x86/hvm/viridian/synic.c index e6cba7548f1b..75b004440e58 100644 --- a/xen/arch/x86/hvm/viridian/synic.c +++ b/xen/arch/x86/hvm/viridian/synic.c @@ -157,6 +157,14 @@ int viridian_synic_wrmsr(struct vcpu *v, uint32_t idx, uint64_t val) if ( !(viridian_feature_mask(d) & HVMPV_synic) ) return X86EMUL_EXCEPTION; + /* + * Windows 11 Hyper-V (26H1) has been seen to write this MSR to + * its default value, despite not being a spec compliant value. + * Tolerate writes which have no change in value. + */ + if ( val == vs->as_uint64 ) + break; + /* Vectors must be in the range 0x10-0xff inclusive */ new.as_uint64 = val; if ( new.vector < 0x10 ) -- 2.53.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/3] x86/viridian: Workaround Hyper-V GP fault writing to MSR 2026-09-04 14:15 ` [PATCH v2 1/3] x86/viridian: Workaround Hyper-V GP fault writing to MSR Ross Lagerwall @ 2026-09-04 14:53 ` Roger Pau Monné 2026-09-08 9:26 ` Ross Lagerwall 0 siblings, 1 reply; 11+ messages in thread From: Roger Pau Monné @ 2026-09-04 14:53 UTC (permalink / raw) To: Ross Lagerwall Cc: xen-devel, Paul Durrant, Jan Beulich, Andrew Cooper, Teddy Astie On Fri, Sep 04, 2026 at 03:15:14PM +0100, Ross Lagerwall wrote: > The Viridian spec requires the vector to be >= 0x10 when writing to the > SINTx MSR, otherwise it should #GP fault. > The spec-defined initial value is 0x0000000000010000, i.e. the vector is > 0. On startup, for some reason Windows 11 Hyper-V tries to set the MSR to > the spec-defined initial value and since the vector is 0, it GP faults. > To workaround this, treat the write as a no-op if the value is > unchanged. > > Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> > Acked-by: Jan Beulich <jbeulich@suse.com> > --- > > In v2: Added a comment to clarify > > xen/arch/x86/hvm/viridian/synic.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/xen/arch/x86/hvm/viridian/synic.c b/xen/arch/x86/hvm/viridian/synic.c > index e6cba7548f1b..75b004440e58 100644 > --- a/xen/arch/x86/hvm/viridian/synic.c > +++ b/xen/arch/x86/hvm/viridian/synic.c > @@ -157,6 +157,14 @@ int viridian_synic_wrmsr(struct vcpu *v, uint32_t idx, uint64_t val) > if ( !(viridian_feature_mask(d) & HVMPV_synic) ) > return X86EMUL_EXCEPTION; > > + /* > + * Windows 11 Hyper-V (26H1) has been seen to write this MSR to > + * its default value, despite not being a spec compliant value. > + * Tolerate writes which have no change in value. > + */ > + if ( val == vs->as_uint64 ) > + break; To make this a bit less workaround like, could we ignore the vector if the SINT is masked (bit 16 set)? Thanks, Roger. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/3] x86/viridian: Workaround Hyper-V GP fault writing to MSR 2026-09-04 14:53 ` Roger Pau Monné @ 2026-09-08 9:26 ` Ross Lagerwall 0 siblings, 0 replies; 11+ messages in thread From: Ross Lagerwall @ 2026-09-08 9:26 UTC (permalink / raw) To: Roger Pau Monné Cc: xen-devel, Paul Durrant, Jan Beulich, Andrew Cooper, Teddy Astie On 9/4/26 3:53 PM, Roger Pau Monné wrote: > On Fri, Sep 04, 2026 at 03:15:14PM +0100, Ross Lagerwall wrote: >> The Viridian spec requires the vector to be >= 0x10 when writing to the >> SINTx MSR, otherwise it should #GP fault. >> The spec-defined initial value is 0x0000000000010000, i.e. the vector is >> 0. On startup, for some reason Windows 11 Hyper-V tries to set the MSR to >> the spec-defined initial value and since the vector is 0, it GP faults. >> To workaround this, treat the write as a no-op if the value is >> unchanged. >> >> Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> >> Acked-by: Jan Beulich <jbeulich@suse.com> >> --- >> >> In v2: Added a comment to clarify >> >> xen/arch/x86/hvm/viridian/synic.c | 8 ++++++++ >> 1 file changed, 8 insertions(+) >> >> diff --git a/xen/arch/x86/hvm/viridian/synic.c b/xen/arch/x86/hvm/viridian/synic.c >> index e6cba7548f1b..75b004440e58 100644 >> --- a/xen/arch/x86/hvm/viridian/synic.c >> +++ b/xen/arch/x86/hvm/viridian/synic.c >> @@ -157,6 +157,14 @@ int viridian_synic_wrmsr(struct vcpu *v, uint32_t idx, uint64_t val) >> if ( !(viridian_feature_mask(d) & HVMPV_synic) ) >> return X86EMUL_EXCEPTION; >> >> + /* >> + * Windows 11 Hyper-V (26H1) has been seen to write this MSR to >> + * its default value, despite not being a spec compliant value. >> + * Tolerate writes which have no change in value. >> + */ >> + if ( val == vs->as_uint64 ) >> + break; > > To make this a bit less workaround like, could we ignore the vector if > the SINT is masked (bit 16 set)? Yes, that might be better and it appears to be what KVM does. Ross ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode 2026-09-04 14:15 [PATCH v2 0/3] Viridian changes for Hyper-V as a guest Ross Lagerwall 2026-09-04 14:15 ` [PATCH v2 1/3] x86/viridian: Workaround Hyper-V GP fault writing to MSR Ross Lagerwall @ 2026-09-04 14:15 ` Ross Lagerwall 2026-09-04 15:15 ` Roger Pau Monné 2026-09-07 9:02 ` Jan Beulich 2026-09-04 14:15 ` [PATCH v2 3/3] tools/libxl: Add support for Viridian stimer " Ross Lagerwall 2 siblings, 2 replies; 11+ messages in thread From: Ross Lagerwall @ 2026-09-04 14:15 UTC (permalink / raw) To: xen-devel Cc: Ross Lagerwall, Paul Durrant, Jan Beulich, Andrew Cooper, Roger Pau Monné, Teddy Astie, Anthony PERARD, Michal Orzel, Julien Grall, Stefano Stabellini 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@citrix.com> --- 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; + stop_stimer(vs); vs->config.as_uint64 = val; - if ( !vs->config.sintx || !vs->count ) + if ( (vs->config.direct_mode && + (vs->config.sintx || vs->config.apic_vector < 0x10)) || + (!vs->config.direct_mode && !vs->config.sintx) || !vs->count ) vs->config.enable = 0; if ( vs->config.enable ) @@ -583,8 +601,24 @@ 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 && + !(viridian_feature_mask(v->domain) & HVMPV_stimer_direct) ) + { + /* + * Old Xen didn't support direct mode but it could still be enabled + * in the MSR. Disable it now to avoid unexpected behaviour. + */ + vs->config.direct_mode = 0; + } + + if ( (vs->config.direct_mode && + (vs->config.sintx || vs->config.apic_vector < 0x10)) || + (!vs->config.direct_mode && !vs->config.sintx) || !vs->count ) + /* + * Disable if sanity checking direct mode / sintx / APIC vector + * fails, or if the count is zero. + */ vs->config.enable = 0; } } diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c index 90e749ceb581..90be5842b995 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_direct ) + res->d |= CPUID3D_STIMER_DIRECT_MODE; break; } diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index 99c40b4287f1..4db5142970c2 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -159,6 +159,10 @@ #define _HVMPV_cpu_hotplug 12 #define HVMPV_cpu_hotplug (1 << _HVMPV_cpu_hotplug) +/* Enable STIMER direct mode */ +#define _HVMPV_stimer_direct 13 +#define HVMPV_stimer_direct (1 << _HVMPV_stimer_direct) + #define HVMPV_feature_mask \ (HVMPV_base_freq | \ HVMPV_no_freq | \ @@ -172,7 +176,8 @@ HVMPV_hcall_ipi | \ HVMPV_ex_processor_masks | \ HVMPV_no_vp_limit | \ - HVMPV_cpu_hotplug) + HVMPV_cpu_hotplug | \ + HVMPV_stimer_direct) #endif -- 2.53.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode 2026-09-04 14:15 ` [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode Ross Lagerwall @ 2026-09-04 15:15 ` Roger Pau Monné 2026-09-07 8:57 ` Jan Beulich 2026-09-09 10:59 ` Ross Lagerwall 2026-09-07 9:02 ` Jan Beulich 1 sibling, 2 replies; 11+ messages in thread From: Roger Pau Monné @ 2026-09-04 15:15 UTC (permalink / raw) To: Ross Lagerwall Cc: xen-devel, Paul Durrant, Jan Beulich, Andrew Cooper, Teddy Astie, Anthony PERARD, Michal Orzel, Julien Grall, Stefano Stabellini 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@citrix.com> > --- > > 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. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode 2026-09-04 15:15 ` Roger Pau Monné @ 2026-09-07 8:57 ` Jan Beulich 2026-09-09 10:59 ` Ross Lagerwall 1 sibling, 0 replies; 11+ messages in thread From: Jan Beulich @ 2026-09-07 8:57 UTC (permalink / raw) To: Roger Pau Monné, Ross Lagerwall Cc: xen-devel, Paul Durrant, Andrew Cooper, Teddy Astie, Anthony PERARD, Michal Orzel, Julien Grall, Stefano Stabellini On 04.09.2026 17:15, Roger Pau Monné wrote: > On Fri, Sep 04, 2026 at 03:15:15PM +0100, Ross Lagerwall wrote: >> @@ -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? I think so, yes (and I thought I had expressed this also in the v1 comments, but apparently not, or not sufficiently clearly). Jan ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode 2026-09-04 15:15 ` Roger Pau Monné 2026-09-07 8:57 ` Jan Beulich @ 2026-09-09 10:59 ` Ross Lagerwall 1 sibling, 0 replies; 11+ messages in thread From: Ross Lagerwall @ 2026-09-09 10:59 UTC (permalink / raw) To: Roger Pau Monné Cc: xen-devel, Paul Durrant, Jan Beulich, Andrew Cooper, Teddy Astie, Anthony PERARD, Michal Orzel, Julien Grall, Stefano Stabellini On 9/4/26 4:15 PM, Roger Pau Monné wrote: > 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@citrix.com> >> --- >> >> 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? I did some investigation into Hyper-V's behaviour (W11 26H1) since the spec doesn't say anything about it: Reserved bits set => GP fault Direct=1 SINTx=any ApicVector<16 => GP fault Direct=1 SINTx=any ApicVector=any => SINTx appears to be ignored Direct=0 SINTx=any ApicVector>0 => GP fault Direct=0 SINTx=0 ApicVector=0 => sets Enabled=0 I'll update the patch accordingly. > > To keep the previous behavior, should Xen silently ignore the setting > when not supported, like it did in the past? OK. Unless someone objects, I'll still perform the new checks for reserved bits and the ApicVector set while Direct=0 case even if the stimer_direct flag is not present. Ross ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode 2026-09-04 14:15 ` [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode Ross Lagerwall 2026-09-04 15:15 ` Roger Pau Monné @ 2026-09-07 9:02 ` Jan Beulich 1 sibling, 0 replies; 11+ messages in thread From: Jan Beulich @ 2026-09-07 9:02 UTC (permalink / raw) To: Ross Lagerwall Cc: Paul Durrant, Andrew Cooper, Roger Pau Monné, Teddy Astie, Anthony PERARD, Michal Orzel, Julien Grall, Stefano Stabellini, xen-devel On 04.09.2026 16:15, Ross Lagerwall wrote: > @@ -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; > + > stop_stimer(vs); > > vs->config.as_uint64 = val; > > - if ( !vs->config.sintx || !vs->count ) > + if ( (vs->config.direct_mode && > + (vs->config.sintx || vs->config.apic_vector < 0x10)) || > + (!vs->config.direct_mode && !vs->config.sintx) || !vs->count ) > vs->config.enable = 0; Personally I find conditionals like this one ((a && ...) || (!a && ...)) pretty odd to read. Imo that's a case where the conditional operator is quite helpful: if ( (vs->config.direct_mode ? vs->config.sintx || vs->config.apic_vector < 0x10 : !vs->config.sintx) || !vs->count ) (Of course further adjustments are going to be needed here to address Roger's comment.) Jan ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 3/3] tools/libxl: Add support for Viridian stimer direct mode 2026-09-04 14:15 [PATCH v2 0/3] Viridian changes for Hyper-V as a guest Ross Lagerwall 2026-09-04 14:15 ` [PATCH v2 1/3] x86/viridian: Workaround Hyper-V GP fault writing to MSR Ross Lagerwall 2026-09-04 14:15 ` [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode Ross Lagerwall @ 2026-09-04 14:15 ` Ross Lagerwall 2026-09-04 23:20 ` Tu Dinh 2 siblings, 1 reply; 11+ messages in thread From: Ross Lagerwall @ 2026-09-04 14:15 UTC (permalink / raw) To: xen-devel; +Cc: Ross Lagerwall, Anthony PERARD, Juergen Gross Add support to libxl for using the stimer enlightenments in direct mode. Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> --- New in v2, since the new Viridian flag was added. docs/man/xl.cfg.5.pod.in | 5 +++++ tools/include/libxl.h | 6 ++++++ tools/libs/light/libxl_types.idl | 1 + tools/libs/light/libxl_x86.c | 5 +++++ 4 files changed, 17 insertions(+) diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in index d34951edb98d..784e926c9990 100644 --- a/docs/man/xl.cfg.5.pod.in +++ b/docs/man/xl.cfg.5.pod.in @@ -2496,6 +2496,11 @@ ticks and hence enabling this group will ensure that ticks will be consistent with use of an enlightened time source (B<time_ref_count> or B<reference_tsc>). +=item B<stimer> + +This set is the same as the B<stimer> set but additionally supports +using synthetic timers in direct mode. + =item B<hcall_ipi> This set incorporates use of a hypercall for interprocessor interrupts. diff --git a/tools/include/libxl.h b/tools/include/libxl.h index 7c098edab663..5475530a5002 100644 --- a/tools/include/libxl.h +++ b/tools/include/libxl.h @@ -381,6 +381,12 @@ */ #define LIBXL_HAVE_VIRIDIAN_HCALL_IPI 1 +/* + * LIBXL_HAVE_VIRIDIAN_STIMER_DIRECT indicates that the 'stimer_direct' value + * is present in the viridian enlightenment enumeration. + */ +#define LIBXL_HAVE_VIRIDIAN_STIMER_DIRECT 1 + /* * LIBXL_HAVE_BUILDINFO_HVM_ACPI_LAPTOP_SLATE indicates that * libxl_domain_build_info has the u.hvm.acpi_laptop_slate field. diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index a7893460f013..95075f04fe45 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -260,6 +260,7 @@ libxl_viridian_enlightenment = Enumeration("viridian_enlightenment", [ (10, "ex_processor_masks"), (11, "no_vp_limit"), (12, "cpu_hotplug"), + (13, "stimer_direct"), ]) libxl_hdtype = Enumeration("hdtype", [ diff --git a/tools/libs/light/libxl_x86.c b/tools/libs/light/libxl_x86.c index 60d4e8661c93..9e8b48372d63 100644 --- a/tools/libs/light/libxl_x86.c +++ b/tools/libs/light/libxl_x86.c @@ -389,6 +389,11 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid, if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_CPU_HOTPLUG)) mask |= HVMPV_cpu_hotplug; + if (libxl_bitmap_test(&enlightenments, + LIBXL_VIRIDIAN_ENLIGHTENMENT_STIMER_DIRECT)) + mask |= HVMPV_time_ref_count | HVMPV_synic | HVMPV_stimer | + HVMPV_stimer_direct; + if (mask != 0 && xc_hvm_param_set(CTX->xch, domid, -- 2.53.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 3/3] tools/libxl: Add support for Viridian stimer direct mode 2026-09-04 14:15 ` [PATCH v2 3/3] tools/libxl: Add support for Viridian stimer " Ross Lagerwall @ 2026-09-04 23:20 ` Tu Dinh 0 siblings, 0 replies; 11+ messages in thread From: Tu Dinh @ 2026-09-04 23:20 UTC (permalink / raw) To: Ross Lagerwall, xen-devel; +Cc: Anthony PERARD, Juergen Gross [-- Attachment #1: Type: text/plain, Size: 3146 bytes --] On 04/09/2026 16:17, Ross Lagerwall wrote: > Add support to libxl for using the stimer enlightenments in direct mode. > > Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> > --- > > New in v2, since the new Viridian flag was added. > > docs/man/xl.cfg.5.pod.in | 5 +++++ > tools/include/libxl.h | 6 ++++++ > tools/libs/light/libxl_types.idl | 1 + > tools/libs/light/libxl_x86.c | 5 +++++ > 4 files changed, 17 insertions(+) > > diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in > index d34951edb98d..784e926c9990 100644 > --- a/docs/man/xl.cfg.5.pod.in > +++ b/docs/man/xl.cfg.5.pod.in > @@ -2496,6 +2496,11 @@ ticks and hence enabling this group will ensure that ticks will be > consistent with use of an enlightened time source (B<time_ref_count> or > B<reference_tsc>). > > +=item B<stimer> > + > +This set is the same as the B<stimer> set but additionally supports > +using synthetic timers in direct mode. > + I think this should be stimer_direct. > =item B<hcall_ipi> > > This set incorporates use of a hypercall for interprocessor interrupts. > diff --git a/tools/include/libxl.h b/tools/include/libxl.h > index 7c098edab663..5475530a5002 100644 > --- a/tools/include/libxl.h > +++ b/tools/include/libxl.h > @@ -381,6 +381,12 @@ > */ > #define LIBXL_HAVE_VIRIDIAN_HCALL_IPI 1 > > +/* > + * LIBXL_HAVE_VIRIDIAN_STIMER_DIRECT indicates that the 'stimer_direct' value > + * is present in the viridian enlightenment enumeration. > + */ > +#define LIBXL_HAVE_VIRIDIAN_STIMER_DIRECT 1 > + > /* > * LIBXL_HAVE_BUILDINFO_HVM_ACPI_LAPTOP_SLATE indicates that > * libxl_domain_build_info has the u.hvm.acpi_laptop_slate field. > diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl > index a7893460f013..95075f04fe45 100644 > --- a/tools/libs/light/libxl_types.idl > +++ b/tools/libs/light/libxl_types.idl > @@ -260,6 +260,7 @@ libxl_viridian_enlightenment = Enumeration("viridian_enlightenment", [ > (10, "ex_processor_masks"), > (11, "no_vp_limit"), > (12, "cpu_hotplug"), > + (13, "stimer_direct"), > ]) > > libxl_hdtype = Enumeration("hdtype", [ > diff --git a/tools/libs/light/libxl_x86.c b/tools/libs/light/libxl_x86.c > index 60d4e8661c93..9e8b48372d63 100644 > --- a/tools/libs/light/libxl_x86.c > +++ b/tools/libs/light/libxl_x86.c > @@ -389,6 +389,11 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid, > if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_CPU_HOTPLUG)) > mask |= HVMPV_cpu_hotplug; > > + if (libxl_bitmap_test(&enlightenments, > + LIBXL_VIRIDIAN_ENLIGHTENMENT_STIMER_DIRECT)) > + mask |= HVMPV_time_ref_count | HVMPV_synic | HVMPV_stimer | > + HVMPV_stimer_direct; > + > if (mask != 0 && > xc_hvm_param_set(CTX->xch, > domid, -- Ngoc Tu Dinh | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-09-09 11:00 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-04 14:15 [PATCH v2 0/3] Viridian changes for Hyper-V as a guest Ross Lagerwall 2026-09-04 14:15 ` [PATCH v2 1/3] x86/viridian: Workaround Hyper-V GP fault writing to MSR Ross Lagerwall 2026-09-04 14:53 ` Roger Pau Monné 2026-09-08 9:26 ` Ross Lagerwall 2026-09-04 14:15 ` [PATCH v2 2/3] x86/viridian: Implement synthetic timer direct mode Ross Lagerwall 2026-09-04 15:15 ` Roger Pau Monné 2026-09-07 8:57 ` Jan Beulich 2026-09-09 10:59 ` Ross Lagerwall 2026-09-07 9:02 ` Jan Beulich 2026-09-04 14:15 ` [PATCH v2 3/3] tools/libxl: Add support for Viridian stimer " Ross Lagerwall 2026-09-04 23:20 ` Tu Dinh
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.