Similar to ARM systems. Idea is as follows: If the MSI(-X) is masked, then allow any write to the underlying register. If a MSI(-X) is unmasked, then check its target address and add the offset of the vs-file.
The original value is stored in the shadow register, and will be restored when jailhouse is disabled. Signed-off-by: Ralf Ramsauer <ralf.ramsa...@oth-regensburg.de> --- hypervisor/arch/riscv/pci.c | 86 ++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/hypervisor/arch/riscv/pci.c b/hypervisor/arch/riscv/pci.c index 067a7651..39e1e4cb 100644 --- a/hypervisor/arch/riscv/pci.c +++ b/hypervisor/arch/riscv/pci.c @@ -1,16 +1,20 @@ /* * Jailhouse, a Linux-based partitioning hypervisor * - * Copyright (c) Siemens AG, 2020 + * Copyright (c) OTH Regensburg, 2023 * * Authors: - * Jan Kiszka <jan.kis...@siemens.com> + * Ralf Ramsauer <ralf.ramsa...@oth-regensburg.de> + * Stefan Huber <stefan.hu...@oth-regensburg.de> * * This work is licensed under the terms of the GNU GPL, version 2. See * the COPYING file in the top-level directory. */ -#include <jailhouse/entry.h> +#include <jailhouse/cell.h> +#include <jailhouse/percpu.h> +#include <jailhouse/control.h> +#include <jailhouse/mmio.h> #include <jailhouse/pci.h> u32 arch_pci_read_config(u16 bdf, u16 address, unsigned int size) @@ -24,7 +28,7 @@ void arch_pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size) int arch_pci_add_physical_device(struct cell *cell, struct pci_device *device) { - return -ENOSYS; + return 0; } void arch_pci_remove_physical_device(struct pci_device *device) @@ -40,10 +44,80 @@ void arch_pci_set_suppress_msi(struct pci_device *device, int arch_pci_update_msi(struct pci_device *device, const struct jailhouse_pci_capability *cap) { - return -ENOSYS; + const struct jailhouse_pci_device *info = device->info; + union pci_msi_registers target; + struct public_per_cpu *ppc; + unsigned short vs_file; + unsigned int cpu; + unsigned int n; + + /* If the MSI is masked, allow to write any address */ + target = device->msi_registers; + if (!device->msi_registers.msg32.enable) + goto passthru; + + /* Only allow non-masked access, if vs-file is set */ + vs_file = this_cell()->arch.vs_file; + if (!vs_file) + return -EINVAL; + + for_each_cpu(cpu, &this_cell()->cpu_set) { + ppc = public_per_cpu(cpu); + /* + * If the MSI is unmasked, only allow if the address is + * on the S-Mode file and calculate the VS-mode offset. + */ + if (ppc->imsic_base == device->msi_registers.msg64.address) { + target.msg64.address += vs_file * 0x1000; + goto passthru; + } + } + + return -EINVAL; + +passthru: + for (n = 1; n < (info->msi_64bits ? 4 : 3); n++) + pci_write_config(info->bdf, cap->start + n * 4, + target.raw[n], 4); + + return 0; } int arch_pci_update_msix_vector(struct pci_device *device, unsigned int index) { - return -ENOSYS; + struct public_per_cpu *ppc; + unsigned short vs_file; + unsigned int cpu; + u64 vs_offset = 0; + + vs_file = this_cell()->arch.vs_file; + + /* If the MSI is masked, allow to write any address */ + if (device->msix_vectors[index].masked) + goto passthru; + + /* Only allow non-masked access, if vs-file is set */ + if (!vs_file) + return -EINVAL; + + /* + * If the MSI is unmasked, only allow if the address is on the S-Mode + * file and calculate the VS-mode offset. + */ + for_each_cpu(cpu, &this_cell()->cpu_set) { + ppc = public_per_cpu(cpu); + if (ppc->imsic_base == device->msix_vectors[index].address) { + vs_offset = vs_file * 0x1000; + goto passthru; + } + } + + return -EINVAL; + +passthru: + mmio_write64_split(&device->msix_table[index].address, + device->msix_vectors[index].address + vs_offset); + mmio_write32(&device->msix_table[index].data, + device->msix_vectors[index].data); + return 0; } -- 2.40.1 -- 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 jailhouse-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/jailhouse-dev/20230519204033.643200-71-ralf.ramsauer%40oth-regensburg.de.