예제 #1
0
int arch_cell_create(struct cell *cell)
{
	int err;

	err = vcpu_cell_init(cell);
	if (err)
		return err;

	err = iommu_cell_init(cell);
	if (err)
		goto error_vm_exit;

	err = pci_cell_init(cell);
	if (err)
		goto error_iommu_exit;

	err = ioapic_cell_init(cell);
	if (err)
		goto error_pci_exit;

	cell->comm_page.comm_region.pm_timer_address =
		system_config->platform_info.x86.pm_timer_address;

	return 0;

error_pci_exit:
	pci_cell_exit(cell);
error_iommu_exit:
	iommu_cell_exit(cell);
error_vm_exit:
	vcpu_cell_exit(cell);
	return err;
}
예제 #2
0
void arch_cell_destroy(struct cell *cell)
{
	ioapic_cell_exit(cell);
	pci_cell_exit(cell);
	iommu_cell_exit(cell);
	vcpu_cell_exit(cell);
}
예제 #3
0
파일: vcpu.c 프로젝트: berte/jailhouse
int vcpu_cell_init(struct cell *cell)
{
	const u8 *pio_bitmap = jailhouse_cell_pio_bitmap(cell->config);
	u32 pio_bitmap_size = cell->config->pio_bitmap_size;
	struct vcpu_io_bitmap cell_iobm, root_cell_iobm;
	unsigned int n, pm_timer_addr;
	u32 size;
	int err;
	u8 *b;

	/* PM timer has to be provided */
	if (system_config->platform_info.x86.pm_timer_address == 0)
		return -EINVAL;

	err = vcpu_vendor_cell_init(cell);
	if (err) {
		vcpu_cell_exit(cell);
		return err;
	}

	vcpu_vendor_get_cell_io_bitmap(cell, &cell_iobm);
	memset(cell_iobm.data, -1, cell_iobm.size);

	for (n = 0; n < 2; n++) {
		size = pio_bitmap_size <= PAGE_SIZE ?
			pio_bitmap_size : PAGE_SIZE;
		memcpy(cell_iobm.data + n * PAGE_SIZE, pio_bitmap, size);
		pio_bitmap += size;
		pio_bitmap_size -= size;
	}

	/* moderation access to i8042 command register */
	cell_iobm.data[I8042_CMD_REG / 8] |= 1 << (I8042_CMD_REG % 8);

	if (cell != &root_cell) {
		/*
		 * Shrink PIO access of root cell corresponding to new cell's
		 * access rights.
		 */
		vcpu_vendor_get_cell_io_bitmap(&root_cell, &root_cell_iobm);
		pio_bitmap = jailhouse_cell_pio_bitmap(cell->config);
		pio_bitmap_size = cell->config->pio_bitmap_size;
		for (b = root_cell_iobm.data; pio_bitmap_size > 0;
		     b++, pio_bitmap++, pio_bitmap_size--)
			*b |= ~*pio_bitmap;
	}

	/* permit access to the PM timer */
	pm_timer_addr = system_config->platform_info.x86.pm_timer_address;
	for (n = 0; n < 4; n++, pm_timer_addr++) {
		b = cell_iobm.data;
		b[pm_timer_addr / 8] &= ~(1 << (pm_timer_addr % 8));
	}

	return 0;
}
예제 #4
0
int arch_cell_create(struct cell *cell)
{
	unsigned int cpu;
	int err;

	err = vcpu_cell_init(cell);
	if (err)
		return err;

	err = iommu_cell_init(cell);
	if (err)
		goto error_vm_exit;

	err = pci_cell_init(cell);
	if (err)
		goto error_iommu_exit;

	err = ioapic_cell_init(cell);
	if (err)
		goto error_pci_exit;

	err = cat_cell_init(cell);
	if (err)
		goto error_ioapic_exit;

	cell->comm_page.comm_region.pm_timer_address =
		system_config->platform_info.x86.pm_timer_address;
	cell->comm_page.comm_region.num_cpus = 0;
	for_each_cpu(cpu, cell->cpu_set)
		cell->comm_page.comm_region.num_cpus++;

	return 0;

error_ioapic_exit:
	ioapic_cell_exit(cell);
error_pci_exit:
	pci_cell_exit(cell);
error_iommu_exit:
	iommu_cell_exit(cell);
error_vm_exit:
	vcpu_cell_exit(cell);
	return err;
}