[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4] x86: add p2m_mmio_write_dm
XenGT (Intel Graphics Virtualization technology, please refer to https://01.org/xen/blogs/srclarkx/2013/graphics-virtualization- xengt) driver runs inside Dom0 as a virtual graphics device model, and needs to trap and emulate the guest's write operations to some specific memory pages, like memory pages used by guest graphics driver as PPGTT(per-process graphics translation table). We agreed to add a new p2m type "p2m_mmio_write_dm" to trap the write operation on these graphic page tables. Handling of this new p2m type are similar with existing p2m_ram_ro in most condition checks, with only difference on final policy of emulation vs. drop. For p2m_mmio_write_dm type pages, writes will go to the device model via ioreq-server. Previously, the conclusion in our v3 patch review is to provide a more generalized HVMOP_map_io_range_to_ioreq_server hypercall, by seperating rangesets inside a ioreq server to read-protected/write- protected/both-prtected. Yet, after offline discussion with Paul, we believe a more simplified solution may suffice. We can keep the existing HVMOP_map_io_range_to_ioreq_server hypercall, and let the user decide whether or not a p2m type change is necessary, because in most cases the emulator will already use the p2m_mmio_dm type. Changes from v3: - Use the existing HVMOP_map_io_range_to_ioreq_server hypercall to add write protected range. - Modify the HVMOP_set_mem_type hypercall to support the new p2m type for this range Changes from v2: - Remove excute attribute of the new p2m type p2m_mmio_write_dm - Use existing rangeset for keeping the write protection page range instead of introducing hash table. - Some code style fix. Changes from v1: - Changes the new p2m type name from p2m_ram_wp to p2m_mmio_write_dm. This means that we treat the pages as a special mmio range instead of ram. - Move macros to c file since only this file is using them. - Address various comments from Jan. Signed-off-by: Yu Zhang <yu.c.zhang@xxxxxxxxxxxxxxx> Signed-off-by: Wei Ye <wei.ye@xxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 13 ++++++++++--- xen/arch/x86/mm/p2m-ept.c | 1 + xen/arch/x86/mm/p2m-pt.c | 1 + xen/include/asm-x86/p2m.h | 1 + xen/include/public/hvm/hvm_op.h | 1 + 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 8f49b44..5f806e8 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2838,7 +2838,8 @@ int hvm_hap_nested_page_fault(paddr_t gpa, unsigned long gla, * to the mmio handler. */ if ( (p2mt == p2m_mmio_dm) || - (npfec.write_access && (p2mt == p2m_ram_ro)) ) + (npfec.write_access && + ((p2mt == p2m_ram_ro) || (p2mt == p2m_mmio_write_dm))) ) { put_gfn(p2m->domain, gfn); @@ -5922,6 +5923,8 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) a.mem_type = HVMMEM_ram_rw; else if ( p2m_is_grant(t) ) a.mem_type = HVMMEM_ram_rw; + else if ( t == p2m_mmio_write_dm ) + a.mem_type = HVMMEM_mmio_write_dm; else a.mem_type = HVMMEM_mmio_dm; rc = __copy_to_guest(arg, &a, 1) ? -EFAULT : 0; @@ -5941,7 +5944,8 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) static const p2m_type_t memtype[] = { [HVMMEM_ram_rw] = p2m_ram_rw, [HVMMEM_ram_ro] = p2m_ram_ro, - [HVMMEM_mmio_dm] = p2m_mmio_dm + [HVMMEM_mmio_dm] = p2m_mmio_dm, + [HVMMEM_mmio_write_dm] = p2m_mmio_write_dm }; if ( copy_from_guest(&a, arg, 1) ) @@ -5987,14 +5991,17 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) rc = -EAGAIN; goto param_fail4; } + if ( !p2m_is_ram(t) && - (!p2m_is_hole(t) || a.hvmmem_type != HVMMEM_mmio_dm) ) + (!p2m_is_hole(t) || a.hvmmem_type != HVMMEM_mmio_dm) && + t != p2m_mmio_write_dm ) { put_gfn(d, pfn); goto param_fail4; } rc = p2m_change_type_one(d, pfn, t, memtype[a.hvmmem_type]); + put_gfn(d, pfn); if ( rc ) goto param_fail4; diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index 15c6e83..e21a92d 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -136,6 +136,7 @@ static void ept_p2m_type_to_flags(ept_entry_t *entry, p2m_type_t type, p2m_acces entry->x = 0; break; case p2m_grant_map_ro: + case p2m_mmio_write_dm: entry->r = 1; entry->w = entry->x = 0; break; diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c index e48b63a..26fb18d 100644 --- a/xen/arch/x86/mm/p2m-pt.c +++ b/xen/arch/x86/mm/p2m-pt.c @@ -94,6 +94,7 @@ static unsigned long p2m_type_to_flags(p2m_type_t t, mfn_t mfn) default: return flags | _PAGE_NX_BIT; case p2m_grant_map_ro: + case p2m_mmio_write_dm: return flags | P2M_BASE_FLAGS | _PAGE_NX_BIT; case p2m_ram_ro: case p2m_ram_logdirty: diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 5f7fe71..a7a45af 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -72,6 +72,7 @@ typedef enum { p2m_ram_shared = 12, /* Shared or sharable memory */ p2m_ram_broken = 13, /* Broken page, access cause domain crash */ p2m_map_foreign = 14, /* ram pages from foreign domain */ + p2m_mmio_write_dm = 15, /* Read-only; writes go to the device model */ } p2m_type_t; /* Modifiers to the query */ diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h index eeb0a60..a4e5345 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -81,6 +81,7 @@ typedef enum { HVMMEM_ram_rw, /* Normal read/write guest RAM */ HVMMEM_ram_ro, /* Read-only; writes are discarded */ HVMMEM_mmio_dm, /* Reads and write go to the device model */ + HVMMEM_mmio_write_dm /* Read-only; writes go to the device model */ } hvmmem_type_t; /* Following tools-only interfaces may change in future. */ -- 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 |