[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] x86/ACPI: fix S3 wakeup vector mapping
commit 0f089bbf43ecce6f27576cb548ba4341d0ec46a8 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Jan 5 13:09:55 2021 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Jan 5 13:09:55 2021 +0100 x86/ACPI: fix S3 wakeup vector mapping Use of __acpi_map_table() here was at least close to an abuse already before, but it will now consistently return NULL here. Drop the layering violation and use set_fixmap() directly. Re-use of the ACPI fixmap area is hopefully going to remain "fine" for the time being. Add checks to acpi_enter_sleep(): The vector now needs to be contained within a single page, but the ACPI spec requires 64-byte alignment of FACS anyway. Also bail if no wakeup vector was determined in the first place, in part as preparation for a subsequent relaxation change. Fixes: 1c4aa69ca1e1 ("xen/acpi: Rework acpi_os_map_memory() and acpi_os_unmap_memory()") Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/arch/x86/acpi/boot.c | 5 +++++ xen/arch/x86/acpi/power.c | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/acpi/boot.c b/xen/arch/x86/acpi/boot.c index cecb414681..b34bd6a581 100644 --- a/xen/arch/x86/acpi/boot.c +++ b/xen/arch/x86/acpi/boot.c @@ -443,6 +443,11 @@ acpi_fadt_parse_sleep_info(struct acpi_table_fadt *fadt) "FACS is shorter than ACPI spec allow: %#x", facs->length); + if (facs_pa % 64) + printk(KERN_WARNING PREFIX + "FACS is not 64-byte aligned: %#lx", + facs_pa); + acpi_sinfo.wakeup_vector = facs_pa + offsetof(struct acpi_table_facs, firmware_waking_vector); acpi_sinfo.vector_width = 32; diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c index 7f162a4df9..ad9b8733f3 100644 --- a/xen/arch/x86/acpi/power.c +++ b/xen/arch/x86/acpi/power.c @@ -174,17 +174,20 @@ static void acpi_sleep_prepare(u32 state) if ( state != ACPI_STATE_S3 ) return; - wakeup_vector_va = __acpi_map_table( - acpi_sinfo.wakeup_vector, sizeof(uint64_t)); - /* TBoot will set resume vector itself (when it is safe to do so). */ if ( tboot_in_measured_env() ) return; + set_fixmap(FIX_ACPI_END, acpi_sinfo.wakeup_vector); + wakeup_vector_va = fix_to_virt(FIX_ACPI_END) + + PAGE_OFFSET(acpi_sinfo.wakeup_vector); + if ( acpi_sinfo.vector_width == 32 ) *(uint32_t *)wakeup_vector_va = bootsym_phys(wakeup_start); else *(uint64_t *)wakeup_vector_va = bootsym_phys(wakeup_start); + + clear_fixmap(FIX_ACPI_END); } static void acpi_sleep_post(u32 state) {} @@ -331,6 +334,12 @@ static long enter_state_helper(void *data) */ int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep) { + if ( sleep->sleep_state == ACPI_STATE_S3 && + (!acpi_sinfo.wakeup_vector || !acpi_sinfo.vector_width || + (PAGE_OFFSET(acpi_sinfo.wakeup_vector) > + PAGE_SIZE - acpi_sinfo.vector_width / 8)) ) + return -EOPNOTSUPP; + if ( sleep->flags & XENPF_ACPI_SLEEP_EXTENDED ) { if ( !acpi_sinfo.sleep_control.address || -- generated by git-patchbot for /home/xen/git/xen.git#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |