aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarun.sharma@intel.com[kaf24] <arun.sharma@intel.com[kaf24]>2005-06-02 08:12:25 +0000
committerarun.sharma@intel.com[kaf24] <arun.sharma@intel.com[kaf24]>2005-06-02 08:12:25 +0000
commit55bcae6d7e3f0feb6a4a0abf9f9e09731d96d24c (patch)
treea5f13bba2e25840b96602ad2eaefc5571c217978
parent56b9e01ac8817be1059e4260f2298d040684209e (diff)
downloadxen-55bcae6d7e3f0feb6a4a0abf9f9e09731d96d24c.tar.gz
xen-55bcae6d7e3f0feb6a4a0abf9f9e09731d96d24c.tar.bz2
xen-55bcae6d7e3f0feb6a4a0abf9f9e09731d96d24c.zip
bitkeeper revision 1.1633 (429ebf697h76hFAG0kPyIQgpATAdnw)
[PATCH] vmx-mmio-2pages.patch Handle the case where the MMIO instruction crosses a page boundary. Signed-off-by: Arun Sharma <arun.sharma@intel.com>
-rw-r--r--xen/arch/x86/vmx_platform.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/xen/arch/x86/vmx_platform.c b/xen/arch/x86/vmx_platform.c
index 0dfe6d855a..47f4ffd9fb 100644
--- a/xen/arch/x86/vmx_platform.c
+++ b/xen/arch/x86/vmx_platform.c
@@ -406,35 +406,49 @@ static int vmx_decode(const unsigned char *inst, struct instruction *thread_inst
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)