diff --git a/SOURCES/backport-83736c567d.patch b/SOURCES/backport-83736c567d.patch new file mode 100644 index 0000000..2e56217 --- /dev/null +++ b/SOURCES/backport-83736c567d.patch @@ -0,0 +1,50 @@ +From 83736c567d6b64dbce98f251ca72e7870f556421 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper +Date: Tue, 29 Dec 2020 17:51:23 +0000 +Subject: [PATCH] x86/hpet: Fix return value of hpet_setup() +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +hpet_setup() is idempotent if the rate has already been calculated, and +returns the cached value. However, this only works correctly when the return +statements are identical. + +Use a sensibly named local variable, rather than a dead one with a bad name. + +Fixes: a60bb68219 ("x86/time: reduce rounding errors in calculations") +Signed-off-by: Andrew Cooper +Reviewed-by: Roger Pau Monné +--- + xen/arch/x86/hpet.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c +index a55e68e6f7..e6fab8acd8 100644 +--- a/xen/arch/x86/hpet.c ++++ b/xen/arch/x86/hpet.c +@@ -743,7 +743,7 @@ u64 __init hpet_setup(void) + { + static u64 __initdata hpet_rate; + u32 hpet_id, hpet_period; +- unsigned int last; ++ unsigned int last, rem; + + if ( hpet_rate ) + return hpet_rate; +@@ -773,9 +773,11 @@ u64 __init hpet_setup(void) + hpet_resume(hpet_boot_cfg); + + hpet_rate = 1000000000000000ULL; /* 10^15 */ +- (void)do_div(hpet_rate, hpet_period); ++ rem = do_div(hpet_rate, hpet_period); ++ if ( (rem * 2) > hpet_period ) ++ hpet_rate++; + + return hpet_rate; + } + + void hpet_resume(u32 *boot_cfg) +-- +2.20.1 + diff --git a/SOURCES/backport-e1de4c196a2eb4fd5063c30a2e115adf144bdeef.patch b/SOURCES/backport-e1de4c196a2eb4fd5063c30a2e115adf144bdeef.patch new file mode 100644 index 0000000..ecd3f3b --- /dev/null +++ b/SOURCES/backport-e1de4c196a2eb4fd5063c30a2e115adf144bdeef.patch @@ -0,0 +1,122 @@ +From e1de4c196a2eb4fd5063c30a2e115adf144bdeef Mon Sep 17 00:00:00 2001 +From: Andrew Cooper +Date: Thu, 6 Aug 2020 13:00:07 +0100 +Subject: [PATCH] x86/timer: Fix boot on Intel systems using ITSSPRC static PIT + clock gating + +Recent Intel client devices have disabled the legacy PIT for powersaving +reasons, breaking compatibility with a traditional IBM PC. Xen depends on a +legacy timer interrupt to check that the IO-APIC/PIC routing is configured +correctly, and fails to boot with: + + (XEN) ******************************* + (XEN) Panic on CPU 0: + (XEN) IO-APIC + timer doesn't work! Boot with apic_verbosity=debug and send report. Then try booting with the `noapic` option + (XEN) ******************************* + +While this setting can be undone by Xen, the details of how to differ by +chipset, and would be very short sighted for battery based devices. See bit 2 +"8254 Static Clock Gating Enable" in: + + https://edc.intel.com/content/www/us/en/design/products-and-solutions/processors-and-chipsets/comet-lake-u/intel-400-series-chipset-on-package-platform-controller-hub-register-database/itss-power-reduction-control-itssprc-offset-3300/ + +All impacted systems have an HPET, but there is no indication of the absence +of PIT functionality, nor a suitable way to probe for its absence. As a short +term fix, reconfigure the HPET into legacy replacement mode. A better +longterm fix would be to avoid the reliance on the timer interrupt entirely. + +Signed-off-by: Andrew Cooper +Tested-by: Jason Andryuk +Acked-by: Jan Beulich +--- + xen/arch/x86/hpet.c | 67 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 66 insertions(+), 1 deletion(-) + +diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c +index e6fab8acd8..1ff005fb4a 100644 +--- a/xen/arch/x86/hpet.c ++++ b/xen/arch/x86/hpet.c +@@ -742,7 +742,7 @@ static u32 *hpet_boot_cfg; + u64 __init hpet_setup(void) + { + static u64 __initdata hpet_rate; +- u32 hpet_id, hpet_period; ++ unsigned int hpet_id, hpet_period, hpet_cfg; + unsigned int last, rem; + + if ( hpet_rate ) +@@ -777,6 +777,71 @@ u64 __init hpet_setup(void) + if ( (rem * 2) > hpet_period ) + hpet_rate++; + ++ /* ++ * Intel chipsets from Skylake/ApolloLake onwards can statically clock ++ * gate the 8259 PIT. This option is enabled by default in slightly later ++ * systems, as turning the PIT off is a prerequisite to entering the C11 ++ * power saving state. ++ * ++ * Xen currently depends on the legacy timer interrupt being active while ++ * IRQ routing is configured. ++ * ++ * Reconfigure the HPET into legacy mode to re-establish the timer ++ * interrupt. ++ */ ++ if ( hpet_id & HPET_ID_LEGSUP && ++ !((hpet_cfg = hpet_read32(HPET_CFG)) & HPET_CFG_LEGACY) ) ++ { ++ unsigned int c0_cfg, ticks, count; ++ ++ /* Stop the main counter. */ ++ hpet_write32(hpet_cfg & ~HPET_CFG_ENABLE, HPET_CFG); ++ ++ /* Reconfigure channel 0 to be 32bit periodic. */ ++ c0_cfg = hpet_read32(HPET_Tn_CFG(0)); ++ c0_cfg |= (HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | ++ HPET_TN_32BIT); ++ hpet_write32(c0_cfg, HPET_Tn_CFG(0)); ++ ++ /* ++ * The exact period doesn't have to match a legacy PIT. All we need ++ * is an interrupt queued up via the IO-APIC to check routing. ++ * ++ * Use HZ as the frequency. ++ */ ++ ticks = ((SECONDS(1) / HZ) * div_sc(hpet_rate, SECONDS(1), 32)) >> 32; ++ ++ count = hpet_read32(HPET_COUNTER); ++ ++ /* ++ * HPET_TN_SETVAL above is atrociously documented in the spec. ++ * ++ * Periodic HPET channels have a main comparator register, and ++ * separate "accumulator" register. Despite being named accumulator ++ * in the spec, this is not an accurate description of its behaviour ++ * or purpose. ++ * ++ * Each time an interrupt is generated, the "accumulator" register is ++ * re-added to the comparator set up the new period. ++ * ++ * Normally, writes to the CMP register update both registers. ++ * However, under these semantics, it is impossible to set up a ++ * periodic timer correctly without the main HPET counter being at 0. ++ * ++ * Instead, HPET_TN_SETVAL is a self-clearing control bit which we can ++ * use for periodic timers to mean that the second write to CMP ++ * updates the accumulator only, and not the absolute comparator ++ * value. ++ * ++ * This lets us set a period when the main counter isn't at 0. ++ */ ++ hpet_write32(count + ticks, HPET_Tn_CMP(0)); ++ hpet_write32(ticks, HPET_Tn_CMP(0)); ++ ++ /* Restart the main counter, and legacy mode. */ ++ hpet_write32(hpet_cfg | HPET_CFG_ENABLE | HPET_CFG_LEGACY, HPET_CFG); ++ } ++ + return hpet_rate; + } + +-- +2.20.1 + diff --git a/SPECS/xen.spec b/SPECS/xen.spec index 4f098b5..275dd1d 100644 --- a/SPECS/xen.spec +++ b/SPECS/xen.spec @@ -259,6 +259,8 @@ Patch214: backport-758fae24d7b9.patch Patch215: backport-e373bc1bdc59.patch Patch216: backport-b7c333016e3d.patch Patch217: xsa360.patch +Patch218: backport-83736c567d.patch +Patch219: backport-e1de4c196a2eb4fd5063c30a2e115adf144bdeef.patch Provides: gitsha(https://code.citrite.net/rest/archive/latest/projects/XSU/repos/xen/archive?at=RELEASE-4.13.1&prefix=xen-4.13.1&format=tar.gz#/xen-4.13.1.tar.gz) = 6278553325a9f76d37811923221b21db3882e017 Provides: gitsha(ssh://git@code.citrite.net/xs/xen.pg.git) = 70d4b5941e4fa18d059d0f62cb3bbf5dab7a7946