* [PATCH 0/2] RISC-V: KVM: Validate AIA MMIO ranges against GPA width @ 2026-08-12 5:39 ` Pengpeng Hou 0 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel The AIA device API currently checks only the alignment of userspace- supplied APLIC and IMSIC base addresses. This can publish a wrapping fixed-size MMIO interval or one that lies beyond the selected stage-2 guest physical address (GPA) width. There are two points to close because the GPA width is configurable: 1. Validate every complete range when it is stored and again immediately before AIA initialization publishes the first MMIO device. 2. Once AIA initialization has published those devices, prevent the GPA width from being reduced below their addresses. Both initialization and GPA-width changes are serialized by kvm->lock. The series was reviewed against the RISC-V KVM queue at dfdf1374fdeccb5b7e3d35186228e01ec5ea5f01. No build or runtime testing was performed. Pengpeng Hou (2): RISC-V: KVM: Validate AIA MMIO address ranges RISC-V: KVM: Disallow GPA-width changes after AIA init arch/riscv/kvm/aia_device.c | 79 +++++++++++++++++++++++++++++++------ arch/riscv/kvm/vm.c | 3 +- 2 files changed, 68 insertions(+), 14 deletions(-) -- 2.50.1 (Apple Git-155) ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 0/2] RISC-V: KVM: Validate AIA MMIO ranges against GPA width @ 2026-08-12 5:39 ` Pengpeng Hou 0 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel The AIA device API currently checks only the alignment of userspace- supplied APLIC and IMSIC base addresses. This can publish a wrapping fixed-size MMIO interval or one that lies beyond the selected stage-2 guest physical address (GPA) width. There are two points to close because the GPA width is configurable: 1. Validate every complete range when it is stored and again immediately before AIA initialization publishes the first MMIO device. 2. Once AIA initialization has published those devices, prevent the GPA width from being reduced below their addresses. Both initialization and GPA-width changes are serialized by kvm->lock. The series was reviewed against the RISC-V KVM queue at dfdf1374fdeccb5b7e3d35186228e01ec5ea5f01. No build or runtime testing was performed. Pengpeng Hou (2): RISC-V: KVM: Validate AIA MMIO address ranges RISC-V: KVM: Disallow GPA-width changes after AIA init arch/riscv/kvm/aia_device.c | 79 +++++++++++++++++++++++++++++++------ arch/riscv/kvm/vm.c | 3 +- 2 files changed, 68 insertions(+), 14 deletions(-) -- 2.50.1 (Apple Git-155) _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 0/2] RISC-V: KVM: Validate AIA MMIO ranges against GPA width @ 2026-08-12 5:39 ` Pengpeng Hou 0 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel The AIA device API currently checks only the alignment of userspace- supplied APLIC and IMSIC base addresses. This can publish a wrapping fixed-size MMIO interval or one that lies beyond the selected stage-2 guest physical address (GPA) width. There are two points to close because the GPA width is configurable: 1. Validate every complete range when it is stored and again immediately before AIA initialization publishes the first MMIO device. 2. Once AIA initialization has published those devices, prevent the GPA width from being reduced below their addresses. Both initialization and GPA-width changes are serialized by kvm->lock. The series was reviewed against the RISC-V KVM queue at dfdf1374fdeccb5b7e3d35186228e01ec5ea5f01. No build or runtime testing was performed. Pengpeng Hou (2): RISC-V: KVM: Validate AIA MMIO address ranges RISC-V: KVM: Disallow GPA-width changes after AIA init arch/riscv/kvm/aia_device.c | 79 +++++++++++++++++++++++++++++++------ arch/riscv/kvm/vm.c | 3 +- 2 files changed, 68 insertions(+), 14 deletions(-) -- 2.50.1 (Apple Git-155) -- kvm-riscv mailing list kvm-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kvm-riscv ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] RISC-V: KVM: Validate AIA MMIO address ranges 2026-08-12 5:39 ` Pengpeng Hou (?) @ 2026-08-12 5:39 ` Pengpeng Hou -1 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel Userspace supplies the APLIC and per-vCPU IMSIC base addresses through the AIA device API. The address setters currently reject only misaligned addresses. The regions are later registered on KVM's MMIO bus with fixed sizes. An aligned base near U64_MAX can therefore wrap when the range end is formed. A lower base can still place the range beyond the selected guest stage-2 physical address space. kvm_io_bus_cmp() assumes that registered ranges do not wrap. Validate the complete interval when an address is stored. Since KVM_CAP_VM_GPA_BITS can change the selected GPA width before AIA initialization, validate every address again before registering the first MMIO device. Return -EINVAL for misalignment or arithmetic overflow and -E2BIG when the end exceeds the stage-2 GPA limit, following the arm64 VGIC address-validation convention. Fixes: 89d01306e34d ("RISC-V: KVM: Implement device interface for AIA irqchip") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> --- arch/riscv/kvm/aia_device.c | 79 +++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/arch/riscv/kvm/aia_device.c b/arch/riscv/kvm/aia_device.c index efc7c0bcfba9..e969dbdc4b97 100644 --- a/arch/riscv/kvm/aia_device.c +++ b/arch/riscv/kvm/aia_device.c @@ -10,7 +10,9 @@ #include <linux/bits.h> #include <linux/irqchip/riscv-imsic.h> #include <linux/kvm_host.h> +#include <linux/overflow.h> #include <linux/uaccess.h> +#include <asm/kvm_gstage.h> #include <asm/kvm_isa.h> static int aia_create(struct kvm_device *dev, u32 type) @@ -142,17 +144,37 @@ static int aia_config(struct kvm *kvm, unsigned long type, return 0; } +static int aia_check_addr_range(struct kvm *kvm, u64 addr, u64 alignment, + u64 size) +{ + u64 end; + + if (!IS_ALIGNED(addr, alignment)) + return -EINVAL; + + if (check_add_overflow(addr, size, &end)) + return -EINVAL; + + if (end > kvm_riscv_gstage_gpa_size(kvm->arch.pgd_levels)) + return -E2BIG; + + return 0; +} + static int aia_aplic_addr(struct kvm *kvm, u64 *addr, bool write) { struct kvm_aia *aia = &kvm->arch.aia; + int ret; if (write) { /* Writes can only be done before irqchip is initialized */ if (kvm_riscv_aia_initialized(kvm)) return -EBUSY; - if (*addr & (KVM_DEV_RISCV_APLIC_ALIGN - 1)) - return -EINVAL; + ret = aia_check_addr_range(kvm, *addr, KVM_DEV_RISCV_APLIC_ALIGN, + KVM_DEV_RISCV_APLIC_SIZE); + if (ret) + return ret; aia->aplic_addr = *addr; } else @@ -166,6 +188,7 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, { struct kvm_vcpu *vcpu; struct kvm_vcpu_aia *vcpu_aia; + int ret; vcpu = kvm_get_vcpu(kvm, vcpu_idx); if (!vcpu) @@ -177,8 +200,10 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, if (kvm_riscv_aia_initialized(kvm)) return -EBUSY; - if (*addr & (KVM_DEV_RISCV_IMSIC_ALIGN - 1)) - return -EINVAL; + ret = aia_check_addr_range(kvm, *addr, KVM_DEV_RISCV_IMSIC_ALIGN, + KVM_DEV_RISCV_IMSIC_SIZE); + if (ret) + return ret; } mutex_lock(&vcpu->mutex); @@ -191,6 +216,40 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, return 0; } +static int aia_validate_addr_ranges(struct kvm *kvm) +{ + struct kvm_aia *aia = &kvm->arch.aia; + struct kvm_vcpu_aia *vaia; + struct kvm_vcpu *vcpu; + unsigned long idx; + int ret; + + if (aia->nr_sources) { + if (aia->aplic_addr == KVM_RISCV_AIA_UNDEF_ADDR) + return -EINVAL; + + ret = aia_check_addr_range(kvm, aia->aplic_addr, + KVM_DEV_RISCV_APLIC_ALIGN, + KVM_DEV_RISCV_APLIC_SIZE); + if (ret) + return ret; + } + + kvm_for_each_vcpu(idx, vcpu, kvm) { + vaia = &vcpu->arch.aia_context; + if (vaia->imsic_addr == KVM_RISCV_AIA_UNDEF_ADDR) + return -EINVAL; + + ret = aia_check_addr_range(kvm, vaia->imsic_addr, + KVM_DEV_RISCV_IMSIC_ALIGN, + KVM_DEV_RISCV_IMSIC_SIZE); + if (ret) + return ret; + } + + return 0; +} + static gpa_t aia_imsic_ppn(struct kvm_aia *aia, gpa_t addr) { u32 h, l; @@ -244,9 +303,9 @@ static int aia_init(struct kvm *kvm) if (aia->nr_ids < aia->nr_sources) return -EINVAL; - /* APLIC base is required for non-zero number of sources */ - if (aia->nr_sources && aia->aplic_addr == KVM_RISCV_AIA_UNDEF_ADDR) - return -EINVAL; + ret = aia_validate_addr_ranges(kvm); + if (ret) + return ret; /* Group index bits must not overlap guest and HART index bits. */ if (aia->nr_group_bits && @@ -263,12 +322,6 @@ static int aia_init(struct kvm *kvm) kvm_for_each_vcpu(idx, vcpu, kvm) { vaia = &vcpu->arch.aia_context; - /* IMSIC base is required */ - if (vaia->imsic_addr == KVM_RISCV_AIA_UNDEF_ADDR) { - ret = -EINVAL; - goto fail_cleanup_imsics; - } - /* All IMSICs should have matching base PPN */ if (base_ppn == KVM_RISCV_AIA_UNDEF_ADDR) base_ppn = aia_imsic_ppn(aia, vaia->imsic_addr); -- 2.50.1 (Apple Git-155) ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 1/2] RISC-V: KVM: Validate AIA MMIO address ranges @ 2026-08-12 5:39 ` Pengpeng Hou 0 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel Userspace supplies the APLIC and per-vCPU IMSIC base addresses through the AIA device API. The address setters currently reject only misaligned addresses. The regions are later registered on KVM's MMIO bus with fixed sizes. An aligned base near U64_MAX can therefore wrap when the range end is formed. A lower base can still place the range beyond the selected guest stage-2 physical address space. kvm_io_bus_cmp() assumes that registered ranges do not wrap. Validate the complete interval when an address is stored. Since KVM_CAP_VM_GPA_BITS can change the selected GPA width before AIA initialization, validate every address again before registering the first MMIO device. Return -EINVAL for misalignment or arithmetic overflow and -E2BIG when the end exceeds the stage-2 GPA limit, following the arm64 VGIC address-validation convention. Fixes: 89d01306e34d ("RISC-V: KVM: Implement device interface for AIA irqchip") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> --- arch/riscv/kvm/aia_device.c | 79 +++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/arch/riscv/kvm/aia_device.c b/arch/riscv/kvm/aia_device.c index efc7c0bcfba9..e969dbdc4b97 100644 --- a/arch/riscv/kvm/aia_device.c +++ b/arch/riscv/kvm/aia_device.c @@ -10,7 +10,9 @@ #include <linux/bits.h> #include <linux/irqchip/riscv-imsic.h> #include <linux/kvm_host.h> +#include <linux/overflow.h> #include <linux/uaccess.h> +#include <asm/kvm_gstage.h> #include <asm/kvm_isa.h> static int aia_create(struct kvm_device *dev, u32 type) @@ -142,17 +144,37 @@ static int aia_config(struct kvm *kvm, unsigned long type, return 0; } +static int aia_check_addr_range(struct kvm *kvm, u64 addr, u64 alignment, + u64 size) +{ + u64 end; + + if (!IS_ALIGNED(addr, alignment)) + return -EINVAL; + + if (check_add_overflow(addr, size, &end)) + return -EINVAL; + + if (end > kvm_riscv_gstage_gpa_size(kvm->arch.pgd_levels)) + return -E2BIG; + + return 0; +} + static int aia_aplic_addr(struct kvm *kvm, u64 *addr, bool write) { struct kvm_aia *aia = &kvm->arch.aia; + int ret; if (write) { /* Writes can only be done before irqchip is initialized */ if (kvm_riscv_aia_initialized(kvm)) return -EBUSY; - if (*addr & (KVM_DEV_RISCV_APLIC_ALIGN - 1)) - return -EINVAL; + ret = aia_check_addr_range(kvm, *addr, KVM_DEV_RISCV_APLIC_ALIGN, + KVM_DEV_RISCV_APLIC_SIZE); + if (ret) + return ret; aia->aplic_addr = *addr; } else @@ -166,6 +188,7 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, { struct kvm_vcpu *vcpu; struct kvm_vcpu_aia *vcpu_aia; + int ret; vcpu = kvm_get_vcpu(kvm, vcpu_idx); if (!vcpu) @@ -177,8 +200,10 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, if (kvm_riscv_aia_initialized(kvm)) return -EBUSY; - if (*addr & (KVM_DEV_RISCV_IMSIC_ALIGN - 1)) - return -EINVAL; + ret = aia_check_addr_range(kvm, *addr, KVM_DEV_RISCV_IMSIC_ALIGN, + KVM_DEV_RISCV_IMSIC_SIZE); + if (ret) + return ret; } mutex_lock(&vcpu->mutex); @@ -191,6 +216,40 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, return 0; } +static int aia_validate_addr_ranges(struct kvm *kvm) +{ + struct kvm_aia *aia = &kvm->arch.aia; + struct kvm_vcpu_aia *vaia; + struct kvm_vcpu *vcpu; + unsigned long idx; + int ret; + + if (aia->nr_sources) { + if (aia->aplic_addr == KVM_RISCV_AIA_UNDEF_ADDR) + return -EINVAL; + + ret = aia_check_addr_range(kvm, aia->aplic_addr, + KVM_DEV_RISCV_APLIC_ALIGN, + KVM_DEV_RISCV_APLIC_SIZE); + if (ret) + return ret; + } + + kvm_for_each_vcpu(idx, vcpu, kvm) { + vaia = &vcpu->arch.aia_context; + if (vaia->imsic_addr == KVM_RISCV_AIA_UNDEF_ADDR) + return -EINVAL; + + ret = aia_check_addr_range(kvm, vaia->imsic_addr, + KVM_DEV_RISCV_IMSIC_ALIGN, + KVM_DEV_RISCV_IMSIC_SIZE); + if (ret) + return ret; + } + + return 0; +} + static gpa_t aia_imsic_ppn(struct kvm_aia *aia, gpa_t addr) { u32 h, l; @@ -244,9 +303,9 @@ static int aia_init(struct kvm *kvm) if (aia->nr_ids < aia->nr_sources) return -EINVAL; - /* APLIC base is required for non-zero number of sources */ - if (aia->nr_sources && aia->aplic_addr == KVM_RISCV_AIA_UNDEF_ADDR) - return -EINVAL; + ret = aia_validate_addr_ranges(kvm); + if (ret) + return ret; /* Group index bits must not overlap guest and HART index bits. */ if (aia->nr_group_bits && @@ -263,12 +322,6 @@ static int aia_init(struct kvm *kvm) kvm_for_each_vcpu(idx, vcpu, kvm) { vaia = &vcpu->arch.aia_context; - /* IMSIC base is required */ - if (vaia->imsic_addr == KVM_RISCV_AIA_UNDEF_ADDR) { - ret = -EINVAL; - goto fail_cleanup_imsics; - } - /* All IMSICs should have matching base PPN */ if (base_ppn == KVM_RISCV_AIA_UNDEF_ADDR) base_ppn = aia_imsic_ppn(aia, vaia->imsic_addr); -- 2.50.1 (Apple Git-155) -- kvm-riscv mailing list kvm-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kvm-riscv ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 1/2] RISC-V: KVM: Validate AIA MMIO address ranges @ 2026-08-12 5:39 ` Pengpeng Hou 0 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel Userspace supplies the APLIC and per-vCPU IMSIC base addresses through the AIA device API. The address setters currently reject only misaligned addresses. The regions are later registered on KVM's MMIO bus with fixed sizes. An aligned base near U64_MAX can therefore wrap when the range end is formed. A lower base can still place the range beyond the selected guest stage-2 physical address space. kvm_io_bus_cmp() assumes that registered ranges do not wrap. Validate the complete interval when an address is stored. Since KVM_CAP_VM_GPA_BITS can change the selected GPA width before AIA initialization, validate every address again before registering the first MMIO device. Return -EINVAL for misalignment or arithmetic overflow and -E2BIG when the end exceeds the stage-2 GPA limit, following the arm64 VGIC address-validation convention. Fixes: 89d01306e34d ("RISC-V: KVM: Implement device interface for AIA irqchip") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> --- arch/riscv/kvm/aia_device.c | 79 +++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/arch/riscv/kvm/aia_device.c b/arch/riscv/kvm/aia_device.c index efc7c0bcfba9..e969dbdc4b97 100644 --- a/arch/riscv/kvm/aia_device.c +++ b/arch/riscv/kvm/aia_device.c @@ -10,7 +10,9 @@ #include <linux/bits.h> #include <linux/irqchip/riscv-imsic.h> #include <linux/kvm_host.h> +#include <linux/overflow.h> #include <linux/uaccess.h> +#include <asm/kvm_gstage.h> #include <asm/kvm_isa.h> static int aia_create(struct kvm_device *dev, u32 type) @@ -142,17 +144,37 @@ static int aia_config(struct kvm *kvm, unsigned long type, return 0; } +static int aia_check_addr_range(struct kvm *kvm, u64 addr, u64 alignment, + u64 size) +{ + u64 end; + + if (!IS_ALIGNED(addr, alignment)) + return -EINVAL; + + if (check_add_overflow(addr, size, &end)) + return -EINVAL; + + if (end > kvm_riscv_gstage_gpa_size(kvm->arch.pgd_levels)) + return -E2BIG; + + return 0; +} + static int aia_aplic_addr(struct kvm *kvm, u64 *addr, bool write) { struct kvm_aia *aia = &kvm->arch.aia; + int ret; if (write) { /* Writes can only be done before irqchip is initialized */ if (kvm_riscv_aia_initialized(kvm)) return -EBUSY; - if (*addr & (KVM_DEV_RISCV_APLIC_ALIGN - 1)) - return -EINVAL; + ret = aia_check_addr_range(kvm, *addr, KVM_DEV_RISCV_APLIC_ALIGN, + KVM_DEV_RISCV_APLIC_SIZE); + if (ret) + return ret; aia->aplic_addr = *addr; } else @@ -166,6 +188,7 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, { struct kvm_vcpu *vcpu; struct kvm_vcpu_aia *vcpu_aia; + int ret; vcpu = kvm_get_vcpu(kvm, vcpu_idx); if (!vcpu) @@ -177,8 +200,10 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, if (kvm_riscv_aia_initialized(kvm)) return -EBUSY; - if (*addr & (KVM_DEV_RISCV_IMSIC_ALIGN - 1)) - return -EINVAL; + ret = aia_check_addr_range(kvm, *addr, KVM_DEV_RISCV_IMSIC_ALIGN, + KVM_DEV_RISCV_IMSIC_SIZE); + if (ret) + return ret; } mutex_lock(&vcpu->mutex); @@ -191,6 +216,40 @@ static int aia_imsic_addr(struct kvm *kvm, u64 *addr, return 0; } +static int aia_validate_addr_ranges(struct kvm *kvm) +{ + struct kvm_aia *aia = &kvm->arch.aia; + struct kvm_vcpu_aia *vaia; + struct kvm_vcpu *vcpu; + unsigned long idx; + int ret; + + if (aia->nr_sources) { + if (aia->aplic_addr == KVM_RISCV_AIA_UNDEF_ADDR) + return -EINVAL; + + ret = aia_check_addr_range(kvm, aia->aplic_addr, + KVM_DEV_RISCV_APLIC_ALIGN, + KVM_DEV_RISCV_APLIC_SIZE); + if (ret) + return ret; + } + + kvm_for_each_vcpu(idx, vcpu, kvm) { + vaia = &vcpu->arch.aia_context; + if (vaia->imsic_addr == KVM_RISCV_AIA_UNDEF_ADDR) + return -EINVAL; + + ret = aia_check_addr_range(kvm, vaia->imsic_addr, + KVM_DEV_RISCV_IMSIC_ALIGN, + KVM_DEV_RISCV_IMSIC_SIZE); + if (ret) + return ret; + } + + return 0; +} + static gpa_t aia_imsic_ppn(struct kvm_aia *aia, gpa_t addr) { u32 h, l; @@ -244,9 +303,9 @@ static int aia_init(struct kvm *kvm) if (aia->nr_ids < aia->nr_sources) return -EINVAL; - /* APLIC base is required for non-zero number of sources */ - if (aia->nr_sources && aia->aplic_addr == KVM_RISCV_AIA_UNDEF_ADDR) - return -EINVAL; + ret = aia_validate_addr_ranges(kvm); + if (ret) + return ret; /* Group index bits must not overlap guest and HART index bits. */ if (aia->nr_group_bits && @@ -263,12 +322,6 @@ static int aia_init(struct kvm *kvm) kvm_for_each_vcpu(idx, vcpu, kvm) { vaia = &vcpu->arch.aia_context; - /* IMSIC base is required */ - if (vaia->imsic_addr == KVM_RISCV_AIA_UNDEF_ADDR) { - ret = -EINVAL; - goto fail_cleanup_imsics; - } - /* All IMSICs should have matching base PPN */ if (base_ppn == KVM_RISCV_AIA_UNDEF_ADDR) base_ppn = aia_imsic_ppn(aia, vaia->imsic_addr); -- 2.50.1 (Apple Git-155) _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] RISC-V: KVM: Disallow GPA-width changes after AIA init 2026-08-12 5:39 ` Pengpeng Hou (?) @ 2026-08-12 5:39 ` Pengpeng Hou -1 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel KVM_ENABLE_CAP(KVM_CAP_VM_GPA_BITS) allows userspace to reduce the stage-2 GPA width while a VM has no vCPUs or memory slots. AIA initialization can still complete with an APLIC and no vCPUs or memory slots. In that state, the APLIC MMIO device has already been registered, but the existing checks allow userspace to shrink the GPA width below its address. Reject GPA-width changes after AIA initialization. Both paths hold kvm->lock, so the check also closes the race between final AIA address validation and publication. Fixes: 7263b4fdb0b2 ("RISC-V: KVM: Reuse KVM_CAP_VM_GPA_BITS to select HGATP.MODE") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> --- arch/riscv/kvm/vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c index a9f083feeb76..66edfaa86243 100644 --- a/arch/riscv/kvm/vm.c +++ b/arch/riscv/kvm/vm.c @@ -250,7 +250,8 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) mutex_lock(&kvm->lock); mutex_lock(&kvm->slots_lock); - if (kvm->created_vcpus || !kvm_are_all_memslots_empty(kvm)) + if (kvm->created_vcpus || !kvm_are_all_memslots_empty(kvm) || + kvm_riscv_aia_initialized(kvm)) r = -EBUSY; else kvm->arch.pgd_levels = new_levels; -- 2.50.1 (Apple Git-155) ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] RISC-V: KVM: Disallow GPA-width changes after AIA init @ 2026-08-12 5:39 ` Pengpeng Hou 0 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel KVM_ENABLE_CAP(KVM_CAP_VM_GPA_BITS) allows userspace to reduce the stage-2 GPA width while a VM has no vCPUs or memory slots. AIA initialization can still complete with an APLIC and no vCPUs or memory slots. In that state, the APLIC MMIO device has already been registered, but the existing checks allow userspace to shrink the GPA width below its address. Reject GPA-width changes after AIA initialization. Both paths hold kvm->lock, so the check also closes the race between final AIA address validation and publication. Fixes: 7263b4fdb0b2 ("RISC-V: KVM: Reuse KVM_CAP_VM_GPA_BITS to select HGATP.MODE") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> --- arch/riscv/kvm/vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c index a9f083feeb76..66edfaa86243 100644 --- a/arch/riscv/kvm/vm.c +++ b/arch/riscv/kvm/vm.c @@ -250,7 +250,8 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) mutex_lock(&kvm->lock); mutex_lock(&kvm->slots_lock); - if (kvm->created_vcpus || !kvm_are_all_memslots_empty(kvm)) + if (kvm->created_vcpus || !kvm_are_all_memslots_empty(kvm) || + kvm_riscv_aia_initialized(kvm)) r = -EBUSY; else kvm->arch.pgd_levels = new_levels; -- 2.50.1 (Apple Git-155) -- kvm-riscv mailing list kvm-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kvm-riscv ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] RISC-V: KVM: Disallow GPA-width changes after AIA init @ 2026-08-12 5:39 ` Pengpeng Hou 0 siblings, 0 replies; 9+ messages in thread From: Pengpeng Hou @ 2026-08-12 5:39 UTC (permalink / raw) To: Anup Patel, Atish Patra Cc: Pengpeng Hou, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Fangyu Yu, Andrew Jones, Nutty Liu, Guo Ren, kvm, kvm-riscv, linux-riscv, linux-kernel KVM_ENABLE_CAP(KVM_CAP_VM_GPA_BITS) allows userspace to reduce the stage-2 GPA width while a VM has no vCPUs or memory slots. AIA initialization can still complete with an APLIC and no vCPUs or memory slots. In that state, the APLIC MMIO device has already been registered, but the existing checks allow userspace to shrink the GPA width below its address. Reject GPA-width changes after AIA initialization. Both paths hold kvm->lock, so the check also closes the race between final AIA address validation and publication. Fixes: 7263b4fdb0b2 ("RISC-V: KVM: Reuse KVM_CAP_VM_GPA_BITS to select HGATP.MODE") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> --- arch/riscv/kvm/vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c index a9f083feeb76..66edfaa86243 100644 --- a/arch/riscv/kvm/vm.c +++ b/arch/riscv/kvm/vm.c @@ -250,7 +250,8 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) mutex_lock(&kvm->lock); mutex_lock(&kvm->slots_lock); - if (kvm->created_vcpus || !kvm_are_all_memslots_empty(kvm)) + if (kvm->created_vcpus || !kvm_are_all_memslots_empty(kvm) || + kvm_riscv_aia_initialized(kvm)) r = -EBUSY; else kvm->arch.pgd_levels = new_levels; -- 2.50.1 (Apple Git-155) _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-08-12 5:40 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-12 5:39 [PATCH 0/2] RISC-V: KVM: Validate AIA MMIO ranges against GPA width Pengpeng Hou 2026-08-12 5:39 ` Pengpeng Hou 2026-08-12 5:39 ` Pengpeng Hou 2026-08-12 5:39 ` [PATCH 1/2] RISC-V: KVM: Validate AIA MMIO address ranges Pengpeng Hou 2026-08-12 5:39 ` Pengpeng Hou 2026-08-12 5:39 ` Pengpeng Hou 2026-08-12 5:39 ` [PATCH 2/2] RISC-V: KVM: Disallow GPA-width changes after AIA init Pengpeng Hou 2026-08-12 5:39 ` Pengpeng Hou 2026-08-12 5:39 ` Pengpeng Hou
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.