Example #1
0
u32
prepare_for_sleep (u32 firmware_waking_vector)
{
	u8 *p;
	int wakeup_entry_len;

	/* Get the suspend-lock to make other processors stopping or staying
	   in the guest mode. */
	get_suspend_lock ();

	/* Now the VMM is executed by the current processor only.
	   Call suspend functions. */
	call_initfunc ("suspend");

	/* Initialize variables used by wakeup functions */
	wakeup_cpucount = 0;
	spinlock_init (&wakeup_cpucount_lock);
	waking_vector = firmware_waking_vector;
	wakeup_prepare ();

	/* Copy the wakeup_entry code. */
	wakeup_entry_len = wakeup_entry_end - wakeup_entry_start;
	p = mapmem_hphys (wakeup_entry_addr, wakeup_entry_len, MAPMEM_WRITE);
	memcpy (p, wakeup_entry_start, wakeup_entry_len);
	unmapmem (p, wakeup_entry_len);
	return wakeup_entry_addr;
}
Example #2
0
static void
loadcfg (void)
{
	struct loadcfg_data *d;
	u8 *pass, *data;
	ulong rbx;
	struct config_data *tmpbuf;

	if (!enable)
		return;

	current->vmctl.read_general_reg (GENERAL_REG_RBX, &rbx);
	rbx &= 0xFFFFFFFF;
	d = mapmem_hphys (rbx, sizeof *d, 0);
	ASSERT (d);
	if (d->len != sizeof *d)
		panic ("size mismatch: %d, %d\n", d->len,
		       (int)sizeof *d);
	pass = mapmem_hphys (d->pass, d->passlen, 0);
	ASSERT (pass);
	data = mapmem_hphys (d->data, d->datalen, 0);
	ASSERT (data);
	tmpbuf = alloc (d->datalen);
	ASSERT (tmpbuf);
#ifdef CRYPTO_VPN
	decryptcfg (pass, d->passlen, data, d->datalen, tmpbuf);
#else
	panic ("cannot decrypt");
#endif
	unmapmem (pass, d->passlen);
	unmapmem (data, d->datalen);
	unmapmem (d, sizeof *d);
	config.len = 0;
	if ((tmpbuf->len + 15) / 16 == d->datalen / 16) {
		if (tmpbuf->len != sizeof config)
			panic ("config size mismatch: %d, %d\n", tmpbuf->len,
			       (int)sizeof config);
		data = mapmem_hphys (d->data, sizeof config, MAPMEM_WRITE);
		ASSERT (data);
		memcpy (data, tmpbuf, sizeof config);
		unmapmem (data, d->datalen);
		current->vmctl.write_general_reg (GENERAL_REG_RAX, 1);
	} else {
		current->vmctl.write_general_reg (GENERAL_REG_RAX, 0);
	}
	free (tmpbuf);
}
Example #3
0
static void
copy_output_buffer (void *output, u16 length)
{
	void *p;

	if (!length)
		return;
	p = mapmem_hphys (OUTPUT_PARAM_BLK_ADDR, length, 0);
	memcpy (output, p, length);
	unmapmem (p, length);
}
Example #4
0
static void
copy_input_buffer (void *input, u16 length)
{
	void *p;

	if (!length)
		return;
	p = mapmem_hphys (INPUT_PARAM_BLK_ADDR, length, MAPMEM_WRITE);
	memcpy (p, input, length);
	unmapmem (p, length);
}
Example #5
0
void
memdump_hphys(u64 hphys){
  u8 * phphys;
  int length = 128;
  phphys = mapmem_hphys (hphys, length, 0);
  static char * hpdes; 
  hpdes = alloc(length);
  memset(hpdes, 0, length);
  memcpy(hpdes, phphys, length);
  printhex(hpdes, length, (u64)hpdes);
}
Example #6
0
void
tcg_measure (void *virt, u32 len)
{
	struct TCG_HashLogExtendEvent_input_param_blk input;
	struct {
		struct TCG_HashLogExtendEvent_output_param_blk output;
		char buf[32];
	} s;
	u32 *log;
	u32 log_phys, phys;
	u32 ret, feat, event, edi;
	u8 major, minor;
	void *tmp;

	if (!len)
		return;
	if (!int1a_TCG_StatusCheck (&ret, &major, &minor, &feat, &event,
				    &edi))
		return;
	phys = 0x100000;
	log_phys = phys + len;
	log = mapmem_hphys (log_phys, 32, MAPMEM_WRITE);
	tmp = mapmem_hphys (phys, len, MAPMEM_WRITE);
	memcpy (tmp, virt, len);
	unmapmem (tmp, len);
	memset (&input, 0, sizeof input);
	input.u.format_2.IPBLength = sizeof input.u.format_2;
	input.u.format_2.HashDataPtr = phys;
	input.u.format_2.HashDataLen = len;
	input.u.format_2.PCRIndex = 4;
	input.u.format_2.LogDataPtr = log_phys;
	input.u.format_2.LogDataLen = 32;
	memset (log, 0, 32);
	log[0] = input.u.format_2.PCRIndex;
	log[1] = 13;
	if (!int1a_TCG_HashLogExtendEvent (&input, &s.output, sizeof s, &ret))
		printf ("TCG_HashLogExtendEvent error\n");
	else
		printf ("EventNumber = %u\n", s.output.EventNumber);
	unmapmem (log, 32);
}
Example #7
0
static void
copy_output_param_blk (void *output, u16 size)
{
	void *p;
	u16 *length;

	p = mapmem_hphys (OUTPUT_PARAM_BLK_ADDR, 0x10000, 0);
	length = p;
	if (size > *length)
		size = *length;
	if (size)
		memcpy (output, p, size);
	unmapmem (p, 0x10000);
}
Example #8
0
// ページの確保
void *pro100_alloc_page(phys_t *ptr)
{
	void *vptr;
	void *vptr2;
	phys_t pptr;

	alloc_page(&vptr, &pptr);

	vptr2 = mapmem_hphys(pptr, PAGESIZE, MAPMEM_WRITE | MAPMEM_PCD | MAPMEM_PWT | MAPMEM_PAT);

	*ptr = pptr;

	return vptr2;
}
Example #9
0
static void
mmio_hphys_access (phys_t gphysaddr, bool wr, void *buf, uint len, u32 flags)
{
	void *p;

	if (!len)
		return;
	p = mapmem_hphys (gphysaddr, len, (wr ? MAPMEM_WRITE : 0) | flags);
	ASSERT (p);
	if (wr)
		memcpy (p, buf, len);
	else
		memcpy (buf, p, len);
	unmapmem (p, len);
}
Example #10
0
static void
copy_bios_area (void *save, void *load)
{
	void *p;

	if (save) {
		p = mapmem_hphys (0, BIOS_AREA_SIZE, 0);
		if (p) {
			memcpy (save, p, BIOS_AREA_SIZE);
			unmapmem (p, BIOS_AREA_SIZE);
		} else {
			printf ("map error\n");
		}
	}
	if (load) {
		p = mapmem_hphys (0, BIOS_AREA_SIZE, MAPMEM_WRITE);
		if (p) {
			memcpy (p, load, BIOS_AREA_SIZE);
			unmapmem (p, BIOS_AREA_SIZE);
		} else {
			printf ("map error\n");
		}
	}
}
Example #11
0
static void
wakeup_ap (void)
{
	u8 buf[5];
	u8 *p;

	/* Put a "ljmpw" instruction to the physical address 0 to
	   avoid the alignment restriction of the SIPI. */
	p = mapmem_hphys (0, 5, MAPMEM_WRITE);
	memcpy (buf, p, 5);
	p[0] = 0xEA;		/* ljmpw */
	p[1] = wakeup_entry_addr & 0xF;
	p[2] = 0;
	p[3] = wakeup_entry_addr >> 4;
	p[4] = wakeup_entry_addr >> 12;
	ap_start_addr (0, wakeup_ap_loopcond, NULL);
	memcpy (p, buf, 5);
	unmapmem (p, 5);
}
Example #12
0
static void
boot_guest (void)
{
	struct config_data *d;
	ulong rbx;

	if (!enable)
		return;

	if (currentcpu->cpunum != 0)
		panic ("boot from AP");
	current->vmctl.read_general_reg (GENERAL_REG_RBX, &rbx);
	rbx &= 0xFFFFFFFF;
	d = mapmem_hphys (rbx, sizeof *d, 0);
	ASSERT (d);
	if (d->len != sizeof *d)
		panic ("config size mismatch: %d, %d\n", d->len,
		       (int)sizeof *d);
	memcpy (&config, d, sizeof *d);
	unmapmem (d, sizeof *d);
	do_boot_guest ();
}
Example #13
0
static void
wakeup_ap (void)
{
	u8 buf[5];
	u8 *p;

	/* Do nothing if no APs were started before suspend.  It is
	 * true when there is only one logical processor for real or
	 * the guest OS uses BSP only on UEFI systems. */
	if (num_of_processors + 1 == 1)
		return;
	/* Put a "ljmpw" instruction to the physical address 0 to
	   avoid the alignment restriction of the SIPI. */
	p = mapmem_hphys (0, 5, MAPMEM_WRITE);
	memcpy (buf, p, 5);
	p[0] = 0xEA;		/* ljmpw */
	p[1] = wakeup_entry_addr & 0xF;
	p[2] = 0;
	p[3] = wakeup_entry_addr >> 4;
	p[4] = wakeup_entry_addr >> 12;
	ap_start_addr (0, wakeup_ap_loopcond, NULL);
	memcpy (p, buf, 5);
	unmapmem (p, 5);
}
Example #14
0
static int
memdump_msghandler (int m, int c, struct msgbuf *buf, int bufcnt)
{
	u8 *q, *tmp;
	struct memdump_data *d;
	void *recvbuf, *sendbuf;
	int recvlen, sendlen, errlen;
	char *errbuf;
	int num = -1;
	struct memdump_gphys_data gphys_data;
	struct memdump_gvirt_data gvirt_data;
	struct memdump_hvirt_data hvirt_data;

	if (m != 1)
		return -1;
	if (bufcnt < 3)
		return -1;
	recvbuf = buf[0].base;
	recvlen = buf[0].len;
	sendbuf = buf[1].base;
	sendlen = buf[1].len;
	errbuf = buf[2].base;
	errlen = buf[2].len;
	if (recvlen < sizeof (struct memdump_data))
		return -1;
	if (errlen > 0)
		errbuf[0] = '\0';
	d = (struct memdump_data *)recvbuf;
	q = sendbuf;
	switch ((enum memdump_type)c) {
	case MEMDUMP_GPHYS:
		gphys_data.physaddr = d->physaddr;
		gphys_data.q = q;
		gphys_data.sendlen = sendlen;
		num = callfunc_and_getint (memdump_gphys, &gphys_data);
		break;
	case MEMDUMP_HVIRT:
		hvirt_data.p = (u8 *)d->virtaddr;
		hvirt_data.q = q;
		hvirt_data.sendlen = sendlen;
		num = callfunc_and_getint (memdump_hvirt, &hvirt_data);
		break;
	case MEMDUMP_HPHYS:
		tmp = mapmem_hphys (d->physaddr, sendlen, 0);
		if (tmp) {
			hvirt_data.p = tmp;
			hvirt_data.q = q;
			hvirt_data.sendlen = sendlen;
			num = callfunc_and_getint (memdump_hvirt, &hvirt_data);
			unmapmem (tmp, sendlen);
		} else {
			snprintf (errbuf, errlen,
				  "mapmem_hphys failed (phys=0x%llX)",
				  d->physaddr);
		}
		break;
	case MEMDUMP_GVIRT:
		gvirt_data.d = d;
		gvirt_data.q = q;
		gvirt_data.sendlen = sendlen;
		gvirt_data.errbuf = errbuf;
		gvirt_data.errlen = errlen;
		num = callfunc_and_getint (memdump_gvirt, &gvirt_data);
		break;
	default:
		return -1;
	}
	if (num != -1)
		snprintf (errbuf, errlen, "exception %d", num);
	return 0;
}
Example #15
0
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);
}