On 26.07.19 15:59, Ralf Ramsauer wrote:
> Whitelist-based permissions align better with the Jailhouse philosophy.
>
> This patch switches the permission bitmap (which basically was (almost) a
> duplicate of the final io_bitmap) to a structure that whitelists a port range,
> given a base port and a length.
>
> As a side effect, this patch drastically reduces the size of config files:
> 8404 -> 224 apic-demo.cell
> 8488 -> 312 e1000-demo.cell
> 11450 -> 3290 f2a88xm-hd3.cell
> 11634 -> 3474 imb-a180.cell
> 8424 -> 252 ioapic-demo.cell
> 8480 -> 296 ivshmem-demo.cell
> 8788 -> 608 linux-x86-demo.cell
> 8488 -> 308 pci-demo.cell
> 9730 -> 1586 qemu-x86.cell
> 8392 -> 212 smp-demo.cell
> 8404 -> 224 tiny-demo.cell
>
> If no whitelist is given, all PIO access will be denied. Additionally,
> increase
> the config file revision header.
>
> Signed-off-by: Ralf Ramsauer <[email protected]>
> ---
> configs/x86/apic-demo.c | 16 +++----
> configs/x86/e1000-demo.c | 19 +++-----
> configs/x86/f2a88xm-hd3.c | 27 +++++------
> configs/x86/imb-a180.c | 27 +++++------
> configs/x86/ioapic-demo.c | 22 ++++-----
> configs/x86/ivshmem-demo.c | 13 ++----
> configs/x86/linux-x86-demo.c | 16 +++----
> configs/x86/pci-demo.c | 16 +++----
> configs/x86/qemu-x86.c | 41 ++++++----------
> configs/x86/smp-demo.c | 16 +++----
> configs/x86/tiny-demo.c | 16 +++----
> hypervisor/arch/x86/vcpu.c | 83 +++++++++++++++++++++------------
> include/jailhouse/cell-config.h | 17 +++----
> tools/jailhouse-hardware-check | 2 +-
> 14 files changed, 149 insertions(+), 182 deletions(-)
>
...
> diff --git a/hypervisor/arch/x86/vcpu.c b/hypervisor/arch/x86/vcpu.c
> index 2e3a1880..17a3a305 100644
> --- a/hypervisor/arch/x86/vcpu.c
> +++ b/hypervisor/arch/x86/vcpu.c
> @@ -26,6 +26,12 @@
> #include <jailhouse/percpu.h>
> #include <asm/vcpu.h>
>
> +#define for_each_pio(pio, config, counter) \
> + for ((pio) = jailhouse_cell_pio(config), \
> + (counter) = 0; \
> + (counter) < (config)->num_pio_regions; \
Renamed to for_each_pio_region on merge - and aligned the \.
> + (pio)++, (counter)++)
> +
> static u8 __attribute__((aligned(PAGE_SIZE))) parking_code[PAGE_SIZE] = {
> 0xfa, /* 1: cli */
> 0xf4, /* hlt */
> @@ -76,15 +82,23 @@ out_err:
> return NULL;
> }
>
> +static void pio_allow_access(u8 *bm, const struct jailhouse_pio *pio,
> + bool access)
> +{
> + void (*access_method)(unsigned int, volatile unsigned long*) =
> + access ? clear_bit : set_bit;
> + unsigned int length, start_bit = pio->base;
> +
> + for (length = pio->length; length > 0; length--, start_bit++)
> + access_method(start_bit, (unsigned long*)bm);
> +}
> +
> int vcpu_cell_init(struct cell *cell)
> {
> const unsigned int io_bitmap_pages = vcpu_vendor_get_io_bitmap_pages();
> - const u8 *pio_bitmap = jailhouse_cell_pio_bitmap(cell->config);
> - u32 pio_bitmap_size = cell->config->pio_bitmap_size;
> + const struct jailhouse_pio *pio;
> unsigned int n, pm_timer_addr;
> - u32 size, iobm_size;
> int err;
> - u8 *b;
>
> cell->arch.io_bitmap = page_alloc(&mem_pool, io_bitmap_pages);
> if (!cell->arch.io_bitmap)
> @@ -97,30 +111,30 @@ int vcpu_cell_init(struct cell *cell)
> }
>
> /* initialize io bitmap to trap all accesses */
> - iobm_size = io_bitmap_pages * PAGE_SIZE;
> - memset(cell->arch.io_bitmap, -1, iobm_size);
> + memset(cell->arch.io_bitmap, -1, io_bitmap_pages * PAGE_SIZE);
>
> - /* copy io bitmap from cell config */
> - size = pio_bitmap_size > iobm_size ? iobm_size : pio_bitmap_size;
> - memcpy(cell->arch.io_bitmap, pio_bitmap, size);
> + /* cells have no access to i8042, unless the port is whitelisted */
> + cell->arch.pio_i8042_allowed = false;
>
> - /* always intercept access to i8042 command register */
> - cell->arch.io_bitmap[I8042_CMD_REG / 8] |= 1 << (I8042_CMD_REG % 8);
> + for_each_pio(pio, cell->config, n) {
> + pio_allow_access(cell->arch.io_bitmap, pio, true);
>
> - /* but moderate only if the config allows i8042 access */
> - cell->arch.pio_i8042_allowed =
> - pio_bitmap_size >= (I8042_CMD_REG + 7) / 8 ?
> - !(pio_bitmap[I8042_CMD_REG / 8] & (1 << (I8042_CMD_REG % 8))) :
> - false;
> + /* moderate i8042 only if the config allows it */
> + if (pio->base <= I8042_CMD_REG &&
> + pio->base + pio->length > I8042_CMD_REG)
> + cell->arch.pio_i8042_allowed = true;
> + }
> +
> + /* but always intercept access to i8042 command register */
> + cell->arch.io_bitmap[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.
> */
> - for (b = root_cell.arch.io_bitmap; pio_bitmap_size > 0;
> - b++, pio_bitmap++, pio_bitmap_size--)
> - *b |= ~*pio_bitmap;
> + for_each_pio(pio, cell->config, n)
> + pio_allow_access(root_cell.arch.io_bitmap, pio, false);
> }
>
> /* permit access to the PM timer if there is any */
> @@ -135,18 +149,25 @@ int vcpu_cell_init(struct cell *cell)
>
> void vcpu_cell_exit(struct cell *cell)
> {
> - const u8 *root_pio_bitmap =
> - jailhouse_cell_pio_bitmap(root_cell.config);
> - const u8 *pio_bitmap = jailhouse_cell_pio_bitmap(cell->config);
> - u32 pio_bitmap_size = cell->config->pio_bitmap_size;
> - u8 *b;
> -
> - if (root_cell.config->pio_bitmap_size < pio_bitmap_size)
> - pio_bitmap_size = root_cell.config->pio_bitmap_size;
> -
> - for (b = root_cell.arch.io_bitmap; pio_bitmap_size > 0;
> - b++, pio_bitmap++, root_pio_bitmap++, pio_bitmap_size--)
> - *b &= *pio_bitmap | *root_pio_bitmap;
> + const struct jailhouse_pio *cell_wl, *root_wl;
> + unsigned int interval_start, interval_end, m, n;
> + struct jailhouse_pio refund;
> +
> + /* Hand back ports to the root cell. But only hand back those ports
> + * that overlap with the root cell's config. This is done by pairwise
> + * comparison of the cell's and the root cell's whitelist entries. */
> + for_each_pio(cell_wl, cell->config, m)
> + for_each_pio(root_wl, root_cell.config, n) {
> + interval_start = MAX(cell_wl->base, root_wl->base);
> + interval_end = MIN(cell_wl->base + cell_wl->length,
> + root_wl->base + root_wl->length);
> + if (interval_start < interval_end) {
> + refund.base = interval_start;
> + refund.length = interval_end - interval_start;
> + pio_allow_access(root_cell.arch.io_bitmap,
> + &refund, true);
> + }
> + }
>
> page_free(&mem_pool, cell->arch.io_bitmap,
> vcpu_vendor_get_io_bitmap_pages());
> diff --git a/include/jailhouse/cell-config.h b/include/jailhouse/cell-config.h
> index a95db470..4b69654a 100644
> --- a/include/jailhouse/cell-config.h
> +++ b/include/jailhouse/cell-config.h
> @@ -50,7 +50,7 @@
> * Incremented on any layout or semantic change of system or cell config.
> * Also update HEADER_REVISION in tools.
> */
> -#define JAILHOUSE_CONFIG_REVISION 10
> +#define JAILHOUSE_CONFIG_REVISION 11
>
> #define JAILHOUSE_CELL_NAME_MAXLEN 31
>
> @@ -92,7 +92,7 @@ struct jailhouse_cell_desc {
> __u32 num_memory_regions;
> __u32 num_cache_regions;
> __u32 num_irqchips;
> - __u32 pio_bitmap_size;
> + __u32 num_pio_regions;
> __u32 num_pci_devices;
> __u32 num_pci_caps;
>
> @@ -277,7 +277,7 @@ jailhouse_cell_config_size(struct jailhouse_cell_desc
> *cell)
> cell->num_memory_regions * sizeof(struct jailhouse_memory) +
> cell->num_cache_regions * sizeof(struct jailhouse_cache) +
> cell->num_irqchips * sizeof(struct jailhouse_irqchip) +
> - cell->pio_bitmap_size +
> + cell->num_pio_regions * sizeof(struct jailhouse_pio) +
> cell->num_pci_devices * sizeof(struct jailhouse_pci_device) +
> cell->num_pci_caps * sizeof(struct jailhouse_pci_capability);
> }
> @@ -319,10 +319,11 @@ jailhouse_cell_irqchips(const struct
> jailhouse_cell_desc *cell)
> cell->num_cache_regions * sizeof(struct jailhouse_cache));
> }
>
> -static inline const __u8 *
> -jailhouse_cell_pio_bitmap(const struct jailhouse_cell_desc *cell)
> +static inline const struct jailhouse_pio *
> +jailhouse_cell_pio(const struct jailhouse_cell_desc *cell)
> {
> - return (const __u8 *)((void *)jailhouse_cell_irqchips(cell) +
> + return (const struct jailhouse_pio *)
> + ((void *)jailhouse_cell_irqchips(cell) +
> cell->num_irqchips * sizeof(struct jailhouse_irqchip));
> }
>
> @@ -330,8 +331,8 @@ static inline const struct jailhouse_pci_device *
> jailhouse_cell_pci_devices(const struct jailhouse_cell_desc *cell)
> {
> return (const struct jailhouse_pci_device *)
> - ((void *)jailhouse_cell_pio_bitmap(cell) +
> - cell->pio_bitmap_size);
> + ((void *)jailhouse_cell_pio(cell) +
> + cell->num_pio_regions * sizeof(struct jailhouse_pio));
> }
>
> static inline const struct jailhouse_pci_capability *
> diff --git a/tools/jailhouse-hardware-check b/tools/jailhouse-hardware-check
> index b86756ac..afd1139b 100755
> --- a/tools/jailhouse-hardware-check
> +++ b/tools/jailhouse-hardware-check
> @@ -136,7 +136,7 @@ class Sysconfig:
> X86_MAX_IOMMU_UNITS = 8
> X86_IOMMU_SIZE = 20
>
> - HEADER_REVISION = 10
> + HEADER_REVISION = 11
> HEADER_FORMAT = '6sH'
>
> def __init__(self, path):
>
Jan
--
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux
--
You received this message because you are subscribed to the Google Groups
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/jailhouse-dev/1a9ff13b-9198-c8ff-a042-f8a05cc01baf%40siemens.com.