From: Greg Kroah-Hartman Date: Thu, 12 Dec 2024 08:27:57 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v5.4.287~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5788ee7c29df281d62ed9f7d2818e25e7997bcdd;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch --- diff --git a/queue-5.4/kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch b/queue-5.4/kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch new file mode 100644 index 00000000000..2c17487e439 --- /dev/null +++ b/queue-5.4/kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch @@ -0,0 +1,148 @@ +From stable+bounces-98547-greg=kroah.com@vger.kernel.org Wed Dec 4 21:23:09 2024 +From: Jing Zhang +Date: Wed, 4 Dec 2024 12:22:59 -0800 +Subject: KVM: arm64: vgic-its: Add a data length check in vgic_its_save_* +To: stable@vger.kernel.org +Cc: Marc Zyngier , Oliver Upton , Kunkun Jiang , Jing Zhang +Message-ID: <20241204202301.2715933-1-jingzhangos@google.com> + +From: Jing Zhang + +commit 7fe28d7e68f92cc3d0668b8f2fbdf5c303ac3022 upstream. + +In all the vgic_its_save_*() functinos, they do not check whether +the data length is 8 bytes before calling vgic_write_guest_lock. +This patch adds the check. To prevent the kernel from being blown up +when the fault occurs, KVM_BUG_ON() is used. And the other BUG_ON()s +are replaced together. + +Cc: stable@vger.kernel.org +Signed-off-by: Kunkun Jiang +[Jing: Update with the new entry read/write helpers] +Signed-off-by: Jing Zhang +Link: https://lore.kernel.org/r/20241107214137.428439-4-jingzhangos@google.com +Signed-off-by: Oliver Upton +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/arm/vgic/vgic-its.c | 20 ++++++++------------ + virt/kvm/arm/vgic/vgic.h | 24 ++++++++++++++++++++++++ + 2 files changed, 32 insertions(+), 12 deletions(-) + +--- a/virt/kvm/arm/vgic/vgic-its.c ++++ b/virt/kvm/arm/vgic/vgic-its.c +@@ -2134,7 +2134,6 @@ static int scan_its_table(struct vgic_it + static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev, + struct its_ite *ite, gpa_t gpa, int ite_esz) + { +- struct kvm *kvm = its->dev->kvm; + u32 next_offset; + u64 val; + +@@ -2143,7 +2142,8 @@ static int vgic_its_save_ite(struct vgic + ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) | + ite->collection->collection_id; + val = cpu_to_le64(val); +- return kvm_write_guest_lock(kvm, gpa, &val, ite_esz); ++ ++ return vgic_its_write_entry_lock(its, gpa, val, ite_esz); + } + + /** +@@ -2279,7 +2279,6 @@ static int vgic_its_restore_itt(struct v + static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev, + gpa_t ptr, int dte_esz) + { +- struct kvm *kvm = its->dev->kvm; + u64 val, itt_addr_field; + u32 next_offset; + +@@ -2290,7 +2289,8 @@ static int vgic_its_save_dte(struct vgic + (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) | + (dev->num_eventid_bits - 1)); + val = cpu_to_le64(val); +- return kvm_write_guest_lock(kvm, ptr, &val, dte_esz); ++ ++ return vgic_its_write_entry_lock(its, ptr, val, dte_esz); + } + + /** +@@ -2470,7 +2470,8 @@ static int vgic_its_save_cte(struct vgic + ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) | + collection->collection_id); + val = cpu_to_le64(val); +- return kvm_write_guest_lock(its->dev->kvm, gpa, &val, esz); ++ ++ return vgic_its_write_entry_lock(its, gpa, val, esz); + } + + static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz) +@@ -2481,8 +2482,7 @@ static int vgic_its_restore_cte(struct v + u64 val; + int ret; + +- BUG_ON(esz > sizeof(val)); +- ret = kvm_read_guest_lock(kvm, gpa, &val, esz); ++ ret = vgic_its_read_entry_lock(its, gpa, &val, esz); + if (ret) + return ret; + val = le64_to_cpu(val); +@@ -2516,7 +2516,6 @@ static int vgic_its_save_collection_tabl + u64 baser = its->baser_coll_table; + gpa_t gpa = GITS_BASER_ADDR_48_to_52(baser); + struct its_collection *collection; +- u64 val; + size_t max_size, filled = 0; + int ret, cte_esz = abi->cte_esz; + +@@ -2540,10 +2539,7 @@ static int vgic_its_save_collection_tabl + * table is not fully filled, add a last dummy element + * with valid bit unset + */ +- val = 0; +- BUG_ON(cte_esz > sizeof(val)); +- ret = kvm_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz); +- return ret; ++ return vgic_its_write_entry_lock(its, gpa, 0, cte_esz); + } + + /** +--- a/virt/kvm/arm/vgic/vgic.h ++++ b/virt/kvm/arm/vgic/vgic.h +@@ -6,6 +6,7 @@ + #define __KVM_ARM_VGIC_NEW_H__ + + #include ++#include + + #define PRODUCT_ID_KVM 0x4b /* ASCII code K */ + #define IMPLEMENTER_ARM 0x43b +@@ -126,6 +127,29 @@ static inline bool vgic_irq_is_multi_sgi + return vgic_irq_get_lr_count(irq) > 1; + } + ++static inline int vgic_its_read_entry_lock(struct vgic_its *its, gpa_t eaddr, ++ u64 *eval, unsigned long esize) ++{ ++ struct kvm *kvm = its->dev->kvm; ++ ++ if (KVM_BUG_ON(esize != sizeof(*eval), kvm)) ++ return -EINVAL; ++ ++ return kvm_read_guest_lock(kvm, eaddr, eval, esize); ++ ++} ++ ++static inline int vgic_its_write_entry_lock(struct vgic_its *its, gpa_t eaddr, ++ u64 eval, unsigned long esize) ++{ ++ struct kvm *kvm = its->dev->kvm; ++ ++ if (KVM_BUG_ON(esize != sizeof(eval), kvm)) ++ return -EINVAL; ++ ++ return kvm_write_guest_lock(kvm, eaddr, &eval, esize); ++} ++ + /* + * This struct provides an intermediate representation of the fields contained + * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC diff --git a/queue-5.4/kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch b/queue-5.4/kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch new file mode 100644 index 00000000000..458c8a88dd2 --- /dev/null +++ b/queue-5.4/kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch @@ -0,0 +1,62 @@ +From stable+bounces-98548-greg=kroah.com@vger.kernel.org Wed Dec 4 22:39:42 2024 +From: Jing Zhang +Date: Wed, 4 Dec 2024 12:23:00 -0800 +Subject: KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device +To: stable@vger.kernel.org +Cc: Marc Zyngier , Oliver Upton , Kunkun Jiang , Shusen Li , Jing Zhang +Message-ID: <20241204202301.2715933-2-jingzhangos@google.com> + +From: Kunkun Jiang + +commit e9649129d33dca561305fc590a7c4ba8c3e5675a upstream. + +vgic_its_save_device_tables will traverse its->device_list to +save DTE for each device. vgic_its_restore_device_tables will +traverse each entry of device table and check if it is valid. +Restore if valid. + +But when MAPD unmaps a device, it does not invalidate the +corresponding DTE. In the scenario of continuous saves +and restores, there may be a situation where a device's DTE +is not saved but is restored. This is unreasonable and may +cause restore to fail. This patch clears the corresponding +DTE when MAPD unmaps a device. + +Cc: stable@vger.kernel.org +Fixes: 57a9a117154c ("KVM: arm64: vgic-its: Device table save/restore") +Co-developed-by: Shusen Li +Signed-off-by: Shusen Li +Signed-off-by: Kunkun Jiang +[Jing: Update with entry write helper] +Signed-off-by: Jing Zhang +Link: https://lore.kernel.org/r/20241107214137.428439-5-jingzhangos@google.com +Signed-off-by: Oliver Upton +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/arm/vgic/vgic-its.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/virt/kvm/arm/vgic/vgic-its.c ++++ b/virt/kvm/arm/vgic/vgic-its.c +@@ -1181,9 +1181,11 @@ static int vgic_its_cmd_handle_mapd(stru + bool valid = its_cmd_get_validbit(its_cmd); + u8 num_eventid_bits = its_cmd_get_size(its_cmd); + gpa_t itt_addr = its_cmd_get_ittaddr(its_cmd); ++ int dte_esz = vgic_its_get_abi(its)->dte_esz; + struct its_device *device; ++ gpa_t gpa; + +- if (!vgic_its_check_id(its, its->baser_device_table, device_id, NULL)) ++ if (!vgic_its_check_id(its, its->baser_device_table, device_id, &gpa)) + return E_ITS_MAPD_DEVICE_OOR; + + if (valid && num_eventid_bits > VITS_TYPER_IDBITS) +@@ -1204,7 +1206,7 @@ static int vgic_its_cmd_handle_mapd(stru + * is an error, so we are done in any case. + */ + if (!valid) +- return 0; ++ return vgic_its_write_entry_lock(its, gpa, 0, dte_esz); + + device = vgic_its_alloc_device(its, device_id, itt_addr, + num_eventid_bits); diff --git a/queue-5.4/kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch b/queue-5.4/kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch new file mode 100644 index 00000000000..b235c8fe4ff --- /dev/null +++ b/queue-5.4/kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch @@ -0,0 +1,53 @@ +From stable+bounces-98549-greg=kroah.com@vger.kernel.org Wed Dec 4 21:23:12 2024 +From: Jing Zhang +Date: Wed, 4 Dec 2024 12:23:01 -0800 +Subject: KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE +To: stable@vger.kernel.org +Cc: Marc Zyngier , Oliver Upton , Kunkun Jiang , Jing Zhang +Message-ID: <20241204202301.2715933-3-jingzhangos@google.com> + +From: Kunkun Jiang + +commit 7602ffd1d5e8927fadd5187cb4aed2fdc9c47143 upstream. + +When DISCARD frees an ITE, it does not invalidate the +corresponding ITE. In the scenario of continuous saves and +restores, there may be a situation where an ITE is not saved +but is restored. This is unreasonable and may cause restore +to fail. This patch clears the corresponding ITE when DISCARD +frees an ITE. + +Cc: stable@vger.kernel.org +Fixes: eff484e0298d ("KVM: arm64: vgic-its: ITT save and restore") +Signed-off-by: Kunkun Jiang +[Jing: Update with entry write helper] +Signed-off-by: Jing Zhang +Link: https://lore.kernel.org/r/20241107214137.428439-6-jingzhangos@google.com +Signed-off-by: Oliver Upton +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/arm/vgic/vgic-its.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/virt/kvm/arm/vgic/vgic-its.c ++++ b/virt/kvm/arm/vgic/vgic-its.c +@@ -854,6 +854,9 @@ static int vgic_its_cmd_handle_discard(s + + ite = find_ite(its, device_id, event_id); + if (ite && ite->collection) { ++ struct its_device *device = find_its_device(its, device_id); ++ int ite_esz = vgic_its_get_abi(its)->ite_esz; ++ gpa_t gpa = device->itt_addr + ite->event_id * ite_esz; + /* + * Though the spec talks about removing the pending state, we + * don't bother here since we clear the ITTE anyway and the +@@ -862,7 +865,8 @@ static int vgic_its_cmd_handle_discard(s + vgic_its_invalidate_cache(kvm); + + its_free_ite(kvm, ite); +- return 0; ++ ++ return vgic_its_write_entry_lock(its, gpa, 0, ite_esz); + } + + return E_ITS_DISCARD_UNMAPPED_INTERRUPT; diff --git a/queue-5.4/series b/queue-5.4/series index ed3150be600..fe172423109 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -310,3 +310,6 @@ xdp-simplify-devmap-cleanup.patch bpf-fix-oob-devmap-writes-when-deleting-elements.patch revert-unicode-don-t-special-case-ignorable-code-points.patch perf-x86-intel-pt-fix-buffer-full-but-size-is-0-case.patch +kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch +kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch +kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch