[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 11/11] x86/altp2m: alternate p2m memory events.
Add a flag to indicate that a memory event occurred in an alternate p2m and a field containing the p2m index. Allow the response to switch to a different p2m using the same flag and field. Modify p2m_access_check() to handle alternate p2m's. Access_required is always assumed for an alternate p2m. Signed-off-by: Ed White <edmund.h.white@xxxxxxxxx> --- xen/arch/x86/mm/hap/altp2m_hap.c | 53 ++++++++++++++++++++++++++++++++++++++-- xen/arch/x86/mm/p2m.c | 18 ++++++++++++-- xen/common/mem_access.c | 1 + xen/include/asm-arm/p2m.h | 7 ++++++ xen/include/asm-x86/p2m.h | 4 +++ xen/include/public/mem_event.h | 9 +++++++ 6 files changed, 88 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/mm/hap/altp2m_hap.c b/xen/arch/x86/mm/hap/altp2m_hap.c index b889626..dd56bbc 100644 --- a/xen/arch/x86/mm/hap/altp2m_hap.c +++ b/xen/arch/x86/mm/hap/altp2m_hap.c @@ -19,6 +19,7 @@ */ #include <xen/mem_event.h> +#include <xen/mem_access.h> #include <xen/event.h> #include <public/mem_event.h> #include <asm/domain.h> @@ -63,8 +64,9 @@ altp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, * else indicate that outer handler should handle fault * * If the fault is for a present entry: - * if the page type is not p2m_ram_rw_ve crash domain - * else if hardware does not support #VE emulate it and retry + * if the page type is p2m_ram_rw_ve and hardware does not support #VE + * emulate #VE and retry if successful + * else try to send a memory event * else crash domain */ @@ -90,11 +92,58 @@ altp2mhvm_hap_nested_page_fault(struct vcpu *v, paddr_t gpa, if ( mfn_valid(mfn) ) { + bool_t violation; + mem_event_request_t *req_ptr = NULL; + /* Should #VE be emulated for this fault? */ if ( p2mt == p2m_ram_rw_ve && !cpu_has_vmx_virt_exceptions && ahvm_vcpu_emulate_ve(v) ) return ALTP2MHVM_PAGEFAULT_DONE; + /* Fault not handled yet, so try for mem_event */ + switch (p2ma) + { + case p2m_access_n: + case p2m_access_n2rwx: + default: + violation = npfec.read_access || npfec.write_access || npfec.insn_fetch; + break; + case p2m_access_r: + violation = npfec.write_access || npfec.insn_fetch; + break; + case p2m_access_w: + violation = npfec.read_access || npfec.insn_fetch; + break; + case p2m_access_x: + violation = npfec.read_access || npfec.write_access; + break; + case p2m_access_rx: + case p2m_access_rx2rw: + violation = npfec.write_access; + break; + case p2m_access_wx: + violation = npfec.read_access; + break; + case p2m_access_rw: + violation = npfec.insn_fetch; + break; + case p2m_access_rwx: + violation = 0; + break; + } + + if ( violation ) + { + p2m_mem_access_check(gpa, gla, npfec, &req_ptr); + + if ( req_ptr ) + { + mem_access_send_req(v->domain, req_ptr); + xfree(req_ptr); + return ALTP2MHVM_PAGEFAULT_DONE; + } + } + /* Could not handle fault here */ gdprintk(XENLOG_INFO, "Altp2m memory access permissions failure, " "no mem_event listener VCPU %d, dom %d\n", diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 843a433..d296c8f 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1486,6 +1486,13 @@ void p2m_mem_event_emulate_check(struct vcpu *v, const mem_event_response_t *rsp } } +void p2m_mem_event_altp2m_check(struct vcpu *v, const mem_event_response_t *rsp) +{ + if ( (rsp->flags & MEM_EVENT_FLAG_ALTERNATE_P2M) && + altp2mhvm_active(v->domain) ) + p2m_switch_vcpu_altp2m_by_id(v, rsp->altp2m_idx); +} + void p2m_setup_introspection(struct domain *d) { if ( hvm_funcs.enable_msr_exit_interception ) @@ -1502,7 +1509,8 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla, struct vcpu *v = current; unsigned long gfn = gpa >> PAGE_SHIFT; struct domain *d = v->domain; - struct p2m_domain* p2m = p2m_get_hostp2m(d); + struct p2m_domain *p2m = altp2mhvm_active(v->domain) ? + p2m_get_altp2m(v) : p2m_get_hostp2m(d); mfn_t mfn; p2m_type_t p2mt; p2m_access_t p2ma; @@ -1536,7 +1544,7 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla, if ( !mem_event_check_ring(&d->mem_event->access) || !req_ptr ) { /* No listener */ - if ( p2m->access_required ) + if ( p2m->access_required || altp2mhvm_active(v->domain) ) { gdprintk(XENLOG_INFO, "Memory access permissions failure, " "no mem_event listener VCPU %d, dom %d\n", @@ -1612,6 +1620,12 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla, req->vcpu_id = v->vcpu_id; p2m_mem_event_fill_regs(req); + + if ( altp2mhvm_active(v->domain) ) + { + req->flags |= MEM_EVENT_FLAG_ALTERNATE_P2M; + req->altp2m_idx = vcpu_altp2mhvm(v).p2midx; + } } /* Pause the current VCPU */ diff --git a/xen/common/mem_access.c b/xen/common/mem_access.c index d8aac5f..223d048 100644 --- a/xen/common/mem_access.c +++ b/xen/common/mem_access.c @@ -48,6 +48,7 @@ void mem_access_resume(struct domain *d) v = d->vcpu[rsp.vcpu_id]; p2m_mem_event_emulate_check(v, &rsp); + p2m_mem_event_altp2m_check(v, &rsp); /* Unpause domain. */ if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED ) diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h index da36504..c838f26 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -78,6 +78,13 @@ void p2m_mem_event_emulate_check(struct vcpu *v, }; static inline +void p2m_mem_event_altp2m_check(struct vcpu *v, + const mem_event_response_t *rsp) +{ + /* Not supported on ARM. */ +}; + +static inline void p2m_setup_introspection(struct domain *d) { /* No special setup on ARM. */ diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 52588ed..e4bc64f 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -737,6 +737,10 @@ bool_t p2m_change_altp2m_pfn(struct domain *d, uint16_t idx, /* Invalidate a page in all alternate p2m's */ void p2m_remove_altp2m_page(struct domain *d, unsigned long gfn); +/* Check to see if vcpu should be switched to a different p2m. */ +void p2m_mem_event_altp2m_check(struct vcpu *v, + const mem_event_response_t *rsp); + /* * p2m type to IOMMU flags */ diff --git a/xen/include/public/mem_event.h b/xen/include/public/mem_event.h index 599f9e8..b877899 100644 --- a/xen/include/public/mem_event.h +++ b/xen/include/public/mem_event.h @@ -47,6 +47,14 @@ * potentially having side effects (like memory mapped or port I/O) disabled. */ #define MEM_EVENT_FLAG_EMULATE_NOWRITE (1 << 6) +/* + * On a request, indicates that the event occurred in the alternate p2m specified by + * the altp2m_idx request field. + * + * On a response, indicates that the VCPU should resume in the alternate p2m specified + * by the altp2m_idx response field if possible. + */ +#define MEM_EVENT_FLAG_ALTERNATE_P2M (1 << 7) /* Reasons for the memory event request */ #define MEM_EVENT_REASON_UNKNOWN 0 /* typical reason */ @@ -117,6 +125,7 @@ typedef struct mem_event_st { uint16_t reason; struct mem_event_regs_x86 x86_regs; + uint16_t altp2m_idx; } mem_event_request_t, mem_event_response_t; DEFINE_RING_TYPES(mem_event, mem_event_request_t, mem_event_response_t); -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |