vmx-mmio-2pages.patch
PATCH 1/1 vmx-mmio-2pages.patch
Handle the case where the MMIO instruction crosses a page boundary.
Signed-off-by Arun Sharma <[email protected]>
arch/x86/vmx_platform.c renamed from xen/arch/x86/vmx_platform.c +28 -14
@@ -406,35 +406,49 @@return DECODE_failure; } -int inst_copy_from_guest (unsigned char *buf,unsigned long guest_eip,int inst_len) +int inst_copy_from_guest (unsigned char *buf,unsigned long guest_eip, +int inst_len) {l1_pgentry_t gpte;unsigned long mfn;unsigned long ma;unsigned char * inst_start; +int remaining =0 ;if (inst_len >MAX_INST_LEN || inst_len <=0 ) {return 0 ; } -if ((guest_eip &PAGE_MASK ) == ((guest_eip + inst_len) &PAGE_MASK )) { -if (vmx_paging_enabled (current)) { - gpte =gva_to_gpte (guest_eip); - mfn =phys_to_machine_mapping (l1e_get_pfn (gpte)); - }else { - mfn =phys_to_machine_mapping (guest_eip >>PAGE_SHIFT ); +if (vmx_paging_enabled (current)) { + gpte =gva_to_gpte (guest_eip); + mfn =phys_to_machine_mapping (l1e_get_pfn (gpte)); +/* Does this cross a page boundary ? */ +if ((guest_eip &PAGE_MASK ) != ((guest_eip + inst_len) &PAGE_MASK )) { + remaining = (guest_eip + inst_len) & ~PAGE_MASK ; + inst_len -= remaining; } - ma = (mfn <<PAGE_SHIFT ) | (guest_eip & (PAGE_SIZE -1 )); + + }else { + mfn =phys_to_machine_mapping (guest_eip >>PAGE_SHIFT ); + } + ma = (mfn <<PAGE_SHIFT ) | (guest_eip & (PAGE_SIZE -1 )); + inst_start = (unsigned char *)map_domain_mem (ma); + +memcpy ((char *)buf, inst_start, inst_len); +unmap_domain_mem (inst_start); + +if (remaining) { + gpte =gva_to_gpte (guest_eip+inst_len+remaining); + mfn =phys_to_machine_mapping (l1e_get_pfn (gpte)); + + ma = (mfn <<PAGE_SHIFT ); inst_start = (unsigned char *)map_domain_mem (ma); -memcpy ((char *)buf, inst_start, inst_len); +memcpy ((char *)buf+inst_len, inst_start, remaining);unmap_domain_mem (inst_start); - }else { -// Todo: In two page frames -BUG (); + } - -return inst_len; +return inst_len+remaining; }static void init_instruction (struct instruction *mmio_inst)