void read_gphys_l (u64 phys, void *data, u32 attr) { if ((phys & 0xFFF) >= 0xFFD) { read_gphys_w (phys + 0, ((u16 *)data) + 0, attr); read_gphys_w (phys + 2, ((u16 *)data) + 1, attr); return; } attr = cache_get_attr (phys, attr); mmio_lock (); if (!mmio_access_memory (phys, false, data, 4, attr)) { phys = current->gmm.gp2hp (phys, NULL); read_hphys_l (phys, data, attr); } mmio_unlock (); }
int virt_memcpy(ulong virtaddr, int nr_bytes, void * value){ struct memdump_data data; u64 ent[5]; int r, levels; memset(ent, 0, sizeof(ent)); memset(&data, 0, sizeof(struct memdump_data)); data.virtaddr = virtaddr; get_control_regs((ulong *)&data.cr0, (ulong *)&data.cr3, (ulong *)&data.cr4, &data.efer); r = cpu_mmu_get_pte(data.virtaddr, (ulong)data.cr0, (ulong)data.cr3, (ulong)data.cr4, data.efer, false, false, false, ent, &levels); if (r == VMMERR_SUCCESS) { data.physaddr = (ent[0] & PTE_ADDR_MASK64) | ((data.virtaddr) & 0xFFF); if(nr_bytes == 4) { read_hphys_l(data.physaddr, value, 0); } if(nr_bytes == 8) { read_hphys_q(data.physaddr, value, 0); } return 0; } return -1; }
static void install_int0x15_hook (void) { u64 int0x15_code, int0x15_data, int0x15_base; u64 int0x15_vector_phys = 0x15 * 4; int count, len1, len2, i; struct e820_data *q; u64 b1, l1, b2, l2; u32 n, nn1, nn2; u32 t1, t2; void *p; len1 = guest_int0x15_hook_end - guest_int0x15_hook; int0x15_code = alloc_realmodemem (len1); count = 0; for (n = 0, nn1 = 1; nn1; n = nn1) { nn1 = getfakesysmemmap (n, &b1, &l1, &t1); nn2 = getsysmemmap (n, &b2, &l2, &t2); if (nn1 == nn2 && b1 == b2 && l1 == l2 && t1 == t2) continue; count++; } len2 = count * sizeof (struct e820_data); int0x15_data = alloc_realmodemem (len2); if (int0x15_data > int0x15_code) int0x15_base = int0x15_code; else int0x15_base = int0x15_data; int0x15_base &= 0xFFFF0; /* save old interrupt vector */ read_hphys_l (int0x15_vector_phys, &guest_int0x15_orig, 0); /* write parameters properly */ guest_int0x15_e801_fake_ax = e801_fake_ax; guest_int0x15_e801_fake_bx = e801_fake_bx; guest_int0x15_e820_data_minus0x18 = int0x15_data - int0x15_base - 0x18; guest_int0x15_e820_end = int0x15_data + len2 - int0x15_base; /* copy the program code */ p = mapmem_hphys (int0x15_code, len1, MAPMEM_WRITE); memcpy (p, guest_int0x15_hook, len1); unmapmem (p, len1); /* create e820_data */ q = mapmem_hphys (int0x15_data, len2, MAPMEM_WRITE); i = 0; for (n = 0, nn1 = 1; nn1; n = nn1) { nn1 = getfakesysmemmap (n, &b1, &l1, &t1); nn2 = getsysmemmap (n, &b2, &l2, &t2); if (nn1 == nn2 && b1 == b2 && l1 == l2 && t1 == t2) continue; ASSERT (i < count); q[i].n = n; q[i].nn = nn1; q[i].base = b1; q[i].len = l1; q[i].type = t1; i++; } unmapmem (q, len2); /* set interrupt vector */ write_hphys_l (int0x15_vector_phys, (int0x15_code - int0x15_base) | (int0x15_base << 12), 0); }