:p
atchew
Login
OpenBSD will attempt to unconditionally access PSTATE0 if HWCR.TscFreqSel is set, and will also attempt to unconditionally access HWCR if the TSC is reported as Invariant. The reasoning for exposing HWCR.TscFreqSel was to avoid Linux from printing a (bogus) warning message, but doing so at the cost of OpenBSD not booting is not a suitable solution. In order to fix expose an empty HWCR. Fixes: 14b95b3b8546 ('x86/AMD: expose HWCR.TscFreqSel to guests') Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- Not sure whether we want to expose something when is_cpufreq_controller() is true, seeing as there's a special wrmsr handler for the same MSR in that case. Likely should be done for PV only, but also likely quite bogus. Missing reported by as the issue came from the QubesOS tracker. --- xen/arch/x86/msr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -XXX,XX +XXX,XX @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val) case MSR_K8_HWCR: if ( !(cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) ) goto gp_fault; - *val = get_cpu_family(cp->basic.raw_fms, NULL, NULL) >= 0x10 - ? K8_HWCR_TSC_FREQ_SEL : 0; + /* + * OpenBSD 7.3 accesses HWCR unconditionally if the TSC is reported as + * Invariant. Do not set TSC_FREQ_SEL as that would trigger OpenBSD to + * also poke at PSTATE0. + */ + *val = 0; break; case MSR_VIRT_SPEC_CTRL: -- 2.42.0
OpenBSD 7.3 will unconditionally access HWCR if the TSC is reported as Invariant, and it will then attempt to also unconditionally access PSTATE0 if HWCR.TscFreqSel is set (currently the case on Xen). The relation between HWCR.TscFreqSel and PSTATE0 is not clearly written down in the PPR, but it's natural for OSes to attempt to fetch the P0 frequency if the TSC increments at the P0 frequency. Exposing PSTATEn (PSTATE0 at least) with all zeroes is not a suitable solution because the PstateEn bit is read-write, and OSes could legitimately attempt to set PstateEn=1 which Xen couldn't handle. In order to fix expose an empty HWCR, which is an architectural MSR and so must be accessible. Note it was not safe to expose the TscFreqSel bit because it is not architectural, and could change meaning between models. Reported-by: Solène Rapenne <solene@openbsd.org> Link: https://github.com/QubesOS/qubes-issues/issues/8502 Fixes: 14b95b3b8546 ('x86/AMD: expose HWCR.TscFreqSel to guests') Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- xen/arch/x86/msr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -XXX,XX +XXX,XX @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val) case MSR_K8_HWCR: if ( !(cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) ) goto gp_fault; - *val = get_cpu_family(cp->basic.raw_fms, NULL, NULL) >= 0x10 - ? K8_HWCR_TSC_FREQ_SEL : 0; + *val = 0; break; case MSR_VIRT_SPEC_CTRL: -- 2.42.0