struct jailhouse_system *config;
struct jailhouse_memory *hv_mem = &config_header.hypervisor_memory;
struct jailhouse_header *header;
+ void __iomem *uart = NULL;
unsigned long config_size;
const char *fw_name;
long max_cpus;
goto error_unmap;
}
+ if (config->debug_uart.flags & JAILHOUSE_MEM_IO) {
+ uart = ioremap(config->debug_uart.phys_start,
+ config->debug_uart.size);
+ if (!uart) {
+ err = -EINVAL;
+ pr_err("jailhouse: Unable to map hypervisor UART at "
+ "%08lx\n",
+ (unsigned long)config->debug_uart.phys_start);
+ goto error_unmap;
+ }
+ header->debug_uart_base = (void *)uart;
+ }
+
root_cell = create_cell(&config->root_cell);
if (IS_ERR(root_cell)) {
err = PTR_ERR(root_cell);
jailhouse_pci_do_all_devices(root_cell, JAILHOUSE_PCI_TYPE_IVSHMEM,
JAILHOUSE_PCI_ACTION_ADD);
+ if (uart)
+ iounmap(uart);
+
release_firmware(hypervisor);
enabled = true;
error_unmap:
vunmap(hypervisor_mem);
+ if (uart)
+ iounmap(uart);
error_release_fw:
release_firmware(hypervisor);
/*
* Jailhouse, a Linux-based partitioning hypervisor
*
- * Copyright (c) Siemens AG, 2013
+ * Copyright (c) Siemens AG, 2014
*
* Authors:
* Jan Kiszka <jan.kiszka@siemens.com>
struct jailhouse_system {
struct jailhouse_memory hypervisor_memory;
+ struct jailhouse_memory debug_uart;
union {
struct {
__u64 mmconfig_base;
/** Number of online CPUs that will call the entry function.
* @note Filled by Linux loader driver before entry. */
unsigned int online_cpus;
+ /** Virtual base address of debug UART (if used).
+ * @note Filled by Linux loader driver before entry. */
+ void *debug_uart_base;
};
*/
int paging_init(void)
{
- unsigned long n, per_cpu_pages, config_pages, bitmap_pages;
+ unsigned long n, per_cpu_pages, config_pages, bitmap_pages, vaddr;
int err;
per_cpu_pages = hypervisor_header.max_cpus *
if (err)
goto error_nomem;
+ if (system_config->debug_uart.flags & JAILHOUSE_MEM_IO) {
+ vaddr = (unsigned long)hypervisor_header.debug_uart_base;
+ if (vaddr + system_config->debug_uart.size >= REMAP_BASE &&
+ vaddr < REMAP_BASE + remap_pool.pages * PAGE_SIZE) {
+ printk("FATAL: UART overlaps remapping region\n");
+ return -EINVAL;
+ }
+ err = paging_create(&hv_paging_structs,
+ system_config->debug_uart.phys_start,
+ system_config->debug_uart.size, vaddr,
+ PAGE_DEFAULT_FLAGS | PAGE_FLAG_DEVICE,
+ PAGING_NON_COHERENT);
+ if (err)
+ goto error_nomem;
+ }
+
/* Make sure any remappings to the temporary regions can be performed
* without allocations of page table pages. */
err = paging_create(&hv_paging_structs, 0,