Ejemplo n.º 1
0
static
int copy_to_gva(guest_cpu_handle_t gcpu,
		uint64_t gva,
		uint32_t size,
		uint64_t hva)
{
	uint64_t dst_gva = gva;
	uint64_t src_hva = 0;
	uint8_t *local_ptr = (uint8_t *)hva;
	uint32_t size_remaining = size;
	uint32_t size_copied = 0;

	while (size_remaining) {
		if (!gcpu_gva_to_hva(gcpu, dst_gva, &src_hva)) {
			MON_LOG(mask_mon,
				level_error,
				"%s: Invalid guest pointer address %P\n",
				__FUNCTION__,
				gva);
			return -1;
		}
		/* Copy until end */
		if (dst_gva > (UINT64_ALL_ONES - size_remaining)) {
			MON_LOG(mask_mon,
				level_error,
				"Error: size bounds exceeded\n");
			return -1;
		}
		if ((dst_gva + size_remaining) <= (dst_gva | PAGE_4KB_MASK)) {
			mon_memcpy((void *)src_hva,
				(void *)local_ptr,
				size_remaining);
			return 0;
		} else {
			/* Copy until end of page */
			size_copied = (uint32_t)
				      (((dst_gva +
					 PAGE_4KB_SIZE) &
					~PAGE_4KB_MASK) - dst_gva);

			mon_memcpy((void *)src_hva,
				(void *)local_ptr,
				size_copied);

			/* Adjust size and pointers for next copy */
			size_remaining -= size_copied;
			local_ptr += size_copied;
			dst_gva += size_copied;
		}
	}

	return 0;
}
Ejemplo n.º 2
0
boolean_t e820_abstraction_initialize(const int15_e820_memory_map_t *
				      e820_memory_map,
				      uint32_t int15_handler_address)
{
	/* INT15 handling is only required for pre-OS launch and is not
	 * required for post-OS launch */
	if (!g_is_post_launch && mon_is_unrestricted_guest_supported()) {
		/* initialize int15 handling vectors */
		update_int15_handling(int15_handler_address);
	}

	if (e820_memory_map != NULL) {
		uint32_t size =
			e820_memory_map->memory_map_size +
			sizeof(e820_memory_map->memory_map_size);
		g_e820_map = (int15_e820_memory_map_t *)mon_memory_alloc(size);
		if (g_e820_map == NULL) {
			return FALSE;
		}
		mon_memcpy(g_e820_map, e820_memory_map, size);
		MON_DEBUG_CODE(e820_abstraction_print_memory_map(
				E820_ORIGINAL_MAP));
		return TRUE;
	}
	return FALSE;
}
Ejemplo n.º 3
0
void CDECL mon_memcpy_assuming_mmio(uint8_t *dst, uint8_t *src, int32_t count)
{
	switch (count) {
	case 0:
		break;

	case 1:
		*dst = *src;
		break;

	case 2:
		*(uint16_t *)dst = *(uint16_t *)src;
		break;

	case 4:
		*(uint32_t *)dst = *(uint32_t *)src;
		break;

	case 8:
		*(uint64_t *)dst = *(uint64_t *)src;
		break;

	case 16:
		*(uint64_t *)dst = *(uint64_t *)src;
		dst += sizeof(uint64_t);
		src += sizeof(uint64_t);
		*(uint64_t *)dst = *(uint64_t *)src;
		break;

	default:
		mon_memcpy(dst, src, count);
		break;
	}
}
Ejemplo n.º 4
0
size_t mem_image_read(gen_image_access_t *ia,
		      void *dest, size_t src_offset, size_t bytes_to_read)
{
	mem_image_access_t *mia = (mem_image_access_t *)ia;

	if ((src_offset + bytes_to_read) > mia->size) {
		bytes_to_read = mia->size - src_offset; /* read no more than size */
	}

	mon_memcpy(dest, mia->image + src_offset, bytes_to_read);
	return bytes_to_read;
}
Ejemplo n.º 5
0
int copy_e820_table_from_efi(xmon_desc_t *td, uint64_t *e820_addr)
{
	mon_guest_cpu_startup_state_t *s;
	int15_e820_memory_map_t *e820;
	void *inf;

	s = (mon_guest_cpu_startup_state_t *)GUEST1_BASE(td);
	inf = (void *)((uint32_t)(s->gp.reg[IA32_REG_RBX]));

	e820 = (int15_e820_memory_map_t *)mon_page_alloc(1);

	if (e820 == NULL) {
		return -1;
	}

	mon_memcpy(e820, inf, 4096);
	*e820_addr = (uint64_t)(uint32_t)e820;

	return 0;
}
Ejemplo n.º 6
0
/*
 * copy e820 memory info to other address, and hide some memories in e820 table.
 */
boolean_t hide_runtime_memory(multiboot_info_t *mbi,
			      uint32_t hide_mem_addr,
			      uint32_t hide_mem_size)
{
	uint32_t num_of_entries, entry_idx;
	multiboot_memory_map_t *newmmap_addr;

	/* Are mmap_* valid? */
	if (!(mbi->flags & MBI_MEMMAP)) {
		return FALSE;
	}

	multiboot_memory_map_t *mmap;

	/* add space for two more entries for boundary case. */
	num_of_entries = mbi->mmap_length / sizeof(multiboot_memory_map_t) + 2;
	newmmap_addr = (multiboot_memory_map_t *)
		       allocate_memory(
		sizeof(multiboot_memory_map_t) * num_of_entries);
	if (!newmmap_addr) {
		return FALSE;
	}


	for (entry_idx = 0, mmap = (multiboot_memory_map_t *)mbi->mmap_addr;
	     (unsigned long)mmap < mbi->mmap_addr + mbi->mmap_length;
	     entry_idx++, mmap = (multiboot_memory_map_t *)
				 ((unsigned long)mmap + mmap->size +
				  sizeof(mmap->size))) {
		if (((mmap->addr + mmap->len) <= hide_mem_addr) ||
		    ((hide_mem_addr + hide_mem_size) <= mmap->addr)) {
			/* do not modify it */
			mon_memcpy(&newmmap_addr[entry_idx], mmap,
				sizeof(multiboot_memory_map_t));
		} else {
			/* input address range to be hidden needs to be of type AVAILABLE. */
			if (mmap->type != MULTIBOOT_MEMORY_AVAILABLE) {
				print_string(
					"ERROR: the type of memory to hide is not AVAILABLE in e820 table!!\n");
				return FALSE;
			}

			newmmap_addr[entry_idx].size = mmap->size;
			newmmap_addr[entry_idx].addr = mmap->addr;
			newmmap_addr[entry_idx].len = hide_mem_addr - mmap->addr;
			newmmap_addr[entry_idx].type = mmap->type;

			entry_idx++;

			newmmap_addr[entry_idx].size = mmap->size;
			newmmap_addr[entry_idx].addr = hide_mem_addr;
			newmmap_addr[entry_idx].len = hide_mem_size;
			newmmap_addr[entry_idx].type = MULTIBOOT_MEMORY_RESERVED;

			if ((hide_mem_addr + hide_mem_size) >
			    (mmap->addr + mmap->len)) {
				print_string(
					"ERROR: hide_mem_addr+hide_mem_size crossing two E820 entries!!\n");
				return FALSE;
			}

			if ((hide_mem_addr + hide_mem_size) <
			    (mmap->addr + mmap->len)) {
				/* need one more entry */
				entry_idx++;
				newmmap_addr[entry_idx].size = mmap->size;
				newmmap_addr[entry_idx].addr = hide_mem_addr +
							       hide_mem_size;
				newmmap_addr[entry_idx].len =
					(mmap->addr +
				 mmap->len) - (hide_mem_addr + hide_mem_size);
				newmmap_addr[entry_idx].type = mmap->type;
			} else {
				/* no need one more entry */
			}
		}
	}

	/* update map addr and len (entry_idx, using the exact entry num value) */
	mbi->mmap_addr = (uint32_t)newmmap_addr;
	mbi->mmap_length = sizeof(multiboot_memory_map_t) * entry_idx; /* do not use num_of_entries*/

	return TRUE;
}