From 4e464bb0c31019cb01efa0c04ca754f8e53c278c Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 13 Nov 2014 09:55:19 +0100 Subject: [PATCH] x86: tolerate running on EFI runtime services page tables in map_domain_page() In the event of a #PF while in an EFI runtime service function we otherwise can't dump the page tables, making the analysis of the problem more cumbersome. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper master commit: e65436ba36be8f1b735573d8fc9af7d8a053ba5f master date: 2014-10-27 16:43:12 +0100 --- xen/arch/x86/domain_page.c | 6 +++++- xen/arch/x86/efi/runtime.c | 5 +++++ xen/arch/x86/efi/stub.c | 6 ++++++ xen/include/xen/efi.h | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c index 9297ea07e6..50f54e5323 100644 --- a/xen/arch/x86/domain_page.c +++ b/xen/arch/x86/domain_page.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -36,11 +37,14 @@ static inline struct vcpu *mapcache_current_vcpu(void) */ if ( unlikely(pagetable_is_null(v->arch.guest_table)) && !is_hvm_vcpu(v) ) { + unsigned long cr3; + /* If we really are idling, perform lazy context switch now. */ if ( (v = idle_vcpu[smp_processor_id()]) == current ) sync_local_execstate(); /* We must now be running on the idle page table. */ - ASSERT(read_cr3() == __pa(idle_pg_table)); + ASSERT((cr3 = read_cr3()) == __pa(idle_pg_table) || + (efi_enabled && cr3 == efi_rs_page_table())); } return v; diff --git a/xen/arch/x86/efi/runtime.c b/xen/arch/x86/efi/runtime.c index e67052b37f..ec1b227b13 100644 --- a/xen/arch/x86/efi/runtime.c +++ b/xen/arch/x86/efi/runtime.c @@ -93,6 +93,11 @@ void efi_rs_leave(unsigned long cr3) stts(); } +paddr_t efi_rs_page_table(void) +{ + return virt_to_maddr(efi_l4_pgtable); +} + unsigned long efi_get_time(void) { EFI_TIME time; diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c index 1520bae6e3..8a914826a4 100644 --- a/xen/arch/x86/efi/stub.c +++ b/xen/arch/x86/efi/stub.c @@ -9,6 +9,12 @@ const bool_t efi_enabled = 0; void __init efi_init_memory(void) { } +paddr_t efi_rs_page_table(void) +{ + BUG(); + return 0; +} + unsigned long efi_get_time(void) { BUG(); diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h index 8a2b78892d..5e02724572 100644 --- a/xen/include/xen/efi.h +++ b/xen/include/xen/efi.h @@ -28,6 +28,7 @@ struct xenpf_efi_runtime_call; struct compat_pf_efi_runtime_call; void efi_init_memory(void); +paddr_t efi_rs_page_table(void); unsigned long efi_get_time(void); void efi_halt_system(void); void efi_reset_system(bool_t warm); -- 2.39.5