From a6fe51debdde03ef748214980e3aa4fb7f1760de Mon Sep 17 00:00:00 2001 From: Zide Chen Date: Fri, 28 May 2021 09:26:55 -0700 Subject: [PATCH] hv: deny access to HV owned legacy PIO UART from SOS We need to deny accesses from SOS to the HV owned UART device, otherwise SOS could have direct access to this physical device and mess up the HV console. If ACRN debug UART is configured as PIO based, For example, CONFIG_SERIAL_PIO_BASE is generated from acrn-config tool, or the UART config is overwritten by hypervisor parameter "uart=port@", it could run into problem if ACRN doesn't emulate this UART PIO port to SOS. For example: - none of the ACRN emulated vUART devices has same PIO port with the port of the debug UART device. - ACRN emulates PCI vUART for SOS (configure "console_vuart" with PCI_VUART in the scenario configuration) This patch fixes the above issue by masking PIO accesses from SOS. deny_hv_owned_devices() is moved after setup_io_bitmap() where vm->arch_vm.io_bitmap is initialized. Commit 50d852561 ("HV: deny HV owned PCI bar access from SOS") handles the case that ACRN debug UART is configured as a PCI device. e.g., hypervisor parameter "uart=bdf@" is appended. If the hypervisor debug UART is MMIO based, need to configured it as a PCI type device, so that it can be hidden from SOS. Tracked-On: #5923 Signed-off-by: Zide Chen Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vm.c | 14 +++++++++++--- hypervisor/debug/uart16550.c | 13 +++++++++++++ hypervisor/include/debug/uart16550.h | 1 + hypervisor/release/console.c | 1 - hypervisor/release/uart16550.c | 6 ++++++ 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 1a950a728..5b8672938 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -38,6 +38,7 @@ #include #include #include +#include /* Local variables */ @@ -354,13 +355,18 @@ static void deny_pdevs(struct acrn_vm *sos, struct acrn_vm_pci_dev_config *pci_d static void deny_hv_owned_devices(struct acrn_vm *sos) { - uint32_t i; + uint16_t pio_address; + uint32_t nbytes, i; const struct pci_pdev **hv_owned = get_hv_owned_pdevs(); for (i = 0U; i < get_hv_owned_pdev_num(); i++) { deny_pci_bar_access(sos, hv_owned[i]); } + + if (get_pio_dbg_uart_cfg(&pio_address, &nbytes)) { + deny_guest_pio_access(sos, pio_address, nbytes); + } } /** @@ -435,8 +441,6 @@ static void prepare_sos_vm_memmap(struct acrn_vm *vm) } } - deny_hv_owned_devices(vm); - /* unmap AP trampoline code for security * This buffer is guaranteed to be page aligned. */ @@ -579,6 +583,10 @@ int32_t create_vm(uint16_t vm_id, uint64_t pcpu_bitmap, struct acrn_vm_config *v vrtc_init(vm); } + if (is_sos_vm(vm)) { + deny_hv_owned_devices(vm); + } + init_vpci(vm); enable_iommu(); diff --git a/hypervisor/debug/uart16550.c b/hypervisor/debug/uart16550.c index 2509e4b37..b2dacaf2f 100644 --- a/hypervisor/debug/uart16550.c +++ b/hypervisor/debug/uart16550.c @@ -276,3 +276,16 @@ bool is_pci_dbg_uart(union pci_bdf bdf_value) return ret; } + +bool get_pio_dbg_uart_cfg(uint16_t *pio_address, uint32_t *nbytes) +{ + bool ret = false; + + if (uart.enabled && (uart.type == PIO)) { + *pio_address = uart.port_address; + *nbytes = 8U; + ret = true; + } + + return ret; +} diff --git a/hypervisor/include/debug/uart16550.h b/hypervisor/include/debug/uart16550.h index 15ae7e966..c6d7ac088 100644 --- a/hypervisor/include/debug/uart16550.h +++ b/hypervisor/include/debug/uart16550.h @@ -139,5 +139,6 @@ char uart16550_getc(void); size_t uart16550_puts(const char *buf, uint32_t len); void uart16550_set_property(bool enabled, enum serial_dev_type uart_type, uint64_t base_addr); bool is_pci_dbg_uart(union pci_bdf bdf_value); +bool get_pio_dbg_uart_cfg(uint16_t *pio_address, uint32_t *nbytes); #endif /* !UART16550_H */ diff --git a/hypervisor/release/console.c b/hypervisor/release/console.c index 8db625463..7866bca06 100644 --- a/hypervisor/release/console.c +++ b/hypervisor/release/console.c @@ -27,7 +27,6 @@ void suspend_console(void) {} void resume_console(void) {} bool handle_dbg_cmd(__unused const char *cmd, __unused int32_t len) { return false; } -bool is_pci_dbg_uart(__unused union pci_bdf bdf_value) { return false; } void shell_init(void) {} void shell_kick(void) {} diff --git a/hypervisor/release/uart16550.c b/hypervisor/release/uart16550.c index 852fde963..7608c8119 100644 --- a/hypervisor/release/uart16550.c +++ b/hypervisor/release/uart16550.c @@ -8,3 +8,9 @@ #include void uart16550_init(__unused bool early_boot) {} + +bool is_pci_dbg_uart(__unused union pci_bdf bdf_value) { return false; } + +bool get_pio_dbg_uart_cfg(__unused uint64_t *pio_address, __unused uint64_t *nbytes) { + return false; +}