This will be used to remove the mapcache override/current vcpu mechanism when reworking map_domain_page() to be safe in the middle of context switches.
Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com> --- xen/arch/x86/mm.c | 11 +++++++++++ xen/arch/x86/setup.c | 2 ++ xen/common/efi/runtime.c | 3 +++ xen/include/asm-x86/mm.h | 11 +++++++++++ 4 files changed, 27 insertions(+) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 57b3e25..7c08807 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -499,6 +499,7 @@ void make_cr3(struct vcpu *v, mfn_t mfn) } DEFINE_PER_CPU(unsigned long, curr_ptbase); +DEFINE_PER_CPU(bool, curr_extended_directmap); void do_write_ptbase(struct vcpu *v, bool tlb_maintenance) { @@ -506,6 +507,8 @@ void do_write_ptbase(struct vcpu *v, bool tlb_maintenance) unsigned int cpu = smp_processor_id(); unsigned long *this_curr_ptbase = &per_cpu(curr_ptbase, cpu); l4_pgentry_t percpu_mappings = per_cpu(percpu_mappings, cpu); + bool *this_extd_directmap = &per_cpu(curr_extended_directmap, cpu); + bool new_extd_directmap = paging_mode_external(v->domain); l4_pgentry_t *new_l4t; struct page_info *new_pg; @@ -529,11 +532,19 @@ void do_write_ptbase(struct vcpu *v, bool tlb_maintenance) new_l4t[l4_table_offset(PERCPU_LINEAR_START)] = percpu_mappings; barrier(); + /* If the new cr3 has a short directmap, report so before switching... */ + if ( !new_extd_directmap ) + *this_extd_directmap = new_extd_directmap; + if ( tlb_maintenance ) write_cr3(new_cr3); else asm volatile ( "mov %0, %%cr3" :: "r" (new_cr3) : "memory" ); + /* ... else report afterwards. */ + if ( new_extd_directmap ) + *this_extd_directmap = new_extd_directmap; + /* Mark the old cr3 as no longer in use. */ if ( new_cr3 != *this_curr_ptbase ) { diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 662c383..80efef0 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -270,6 +270,7 @@ void early_switch_to_idle(bool bsp) : "memory" ); per_cpu(curr_ptbase, cpu) = v->arch.cr3; + per_cpu(curr_extended_directmap, cpu) = true; lidt(&idtr); @@ -713,6 +714,7 @@ void __init noreturn __start_xen(unsigned long mbi_p) idle_vcpu[0] = current; percpu_init_areas(); + per_cpu(curr_extended_directmap, 0) = true; init_idt_traps(); { diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c index 3dbc2e8..fe6d3af 100644 --- a/xen/common/efi/runtime.c +++ b/xen/common/efi/runtime.c @@ -112,6 +112,7 @@ struct efi_rs_state efi_rs_enter(void) } write_cr3(virt_to_maddr(efi_l4_pgtable)); + this_cpu(curr_extended_directmap) = true; return state; } @@ -120,6 +121,8 @@ void efi_rs_leave(struct efi_rs_state *state) { if ( !state->cr3 ) return; + + this_cpu(curr_extended_directmap) = paging_mode_external(current->domain); write_cr3(state->cr3); if ( is_pv_vcpu(current) && !is_idle_vcpu(current) ) { diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 64044c6..54b7499 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -567,6 +567,17 @@ void audit_domains(void); DECLARE_PER_CPU(unsigned long, curr_ptbase); +/* + * Indicates whether the current %cr3 contains a short or extended directmap. + * Care needs to be taken when updating, as map_domain_page() is used in + * interrupt/exception context. It is safe to indicate that the current %cr3 + * is short when it is actually extended (in which case, map_domain_page() + * will use a mapping slot rather than refering to the directmap), but it is + * not safe to indicate the opposite (in which case, map_domain_page() will + * return a pointer into 64bit PV kernel address space). + */ +DECLARE_PER_CPU(bool, curr_extended_directmap); + void make_cr3(struct vcpu *v, mfn_t mfn); void update_cr3(struct vcpu *v); int vcpu_destroy_pagetables(struct vcpu *); -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel