From 89ad75747d03f4c9d7ad7aeec4fe68ffe35fbf10 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 12 Dec 2024 09:28:07 +0100 Subject: [PATCH] 5.10-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 --- ...-data-length-check-in-vgic_its_save_.patch | 148 ++++++++++++++++++ ...-clear-dte-when-mapd-unmaps-a-device.patch | 62 ++++++++ ...-clear-ite-when-discard-frees-an-ite.patch | 53 +++++++ queue-5.10/series | 3 + 4 files changed, 266 insertions(+) create mode 100644 queue-5.10/kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch create mode 100644 queue-5.10/kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch create mode 100644 queue-5.10/kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch diff --git a/queue-5.10/kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch b/queue-5.10/kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch new file mode 100644 index 00000000000..dde2f93f96a --- /dev/null +++ b/queue-5.10/kvm-arm64-vgic-its-add-a-data-length-check-in-vgic_its_save_.patch @@ -0,0 +1,148 @@ +From stable+bounces-98550-greg=kroah.com@vger.kernel.org Wed Dec 4 21:23:31 2024 +From: Jing Zhang +Date: Wed, 4 Dec 2024 12:23:16 -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: <20241204202318.2716633-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 +--- + arch/arm64/kvm/vgic/vgic-its.c | 20 ++++++++------------ + arch/arm64/kvm/vgic/vgic.h | 24 ++++++++++++++++++++++++ + 2 files changed, 32 insertions(+), 12 deletions(-) + +--- a/arch/arm64/kvm/vgic/vgic-its.c ++++ b/arch/arm64/kvm/vgic/vgic-its.c +@@ -2135,7 +2135,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; + +@@ -2144,7 +2143,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); + } + + /** +@@ -2280,7 +2280,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; + +@@ -2291,7 +2290,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); + } + + /** +@@ -2471,7 +2471,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) +@@ -2482,8 +2483,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); +@@ -2517,7 +2517,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; + +@@ -2541,10 +2540,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/arch/arm64/kvm/vgic/vgic.h ++++ b/arch/arm64/kvm/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.10/kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch b/queue-5.10/kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch new file mode 100644 index 00000000000..8730e7c7baf --- /dev/null +++ b/queue-5.10/kvm-arm64-vgic-its-clear-dte-when-mapd-unmaps-a-device.patch @@ -0,0 +1,62 @@ +From stable+bounces-98551-greg=kroah.com@vger.kernel.org Wed Dec 4 22:57:56 2024 +From: Jing Zhang +Date: Wed, 4 Dec 2024 12:23:17 -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: <20241204202318.2716633-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 +--- + arch/arm64/kvm/vgic/vgic-its.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/arm64/kvm/vgic/vgic-its.c ++++ b/arch/arm64/kvm/vgic/vgic-its.c +@@ -1182,9 +1182,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) +@@ -1205,7 +1207,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.10/kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch b/queue-5.10/kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch new file mode 100644 index 00000000000..a28c13de109 --- /dev/null +++ b/queue-5.10/kvm-arm64-vgic-its-clear-ite-when-discard-frees-an-ite.patch @@ -0,0 +1,53 @@ +From stable+bounces-98552-greg=kroah.com@vger.kernel.org Wed Dec 4 22:04:48 2024 +From: Jing Zhang +Date: Wed, 4 Dec 2024 12:23:18 -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: <20241204202318.2716633-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 +--- + arch/arm64/kvm/vgic/vgic-its.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/arch/arm64/kvm/vgic/vgic-its.c ++++ b/arch/arm64/kvm/vgic/vgic-its.c +@@ -855,6 +855,9 @@ static int vgic_its_cmd_handle_discard(s + + ite = find_ite(its, device_id, event_id); + if (ite && its_is_collection_mapped(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 +@@ -863,7 +866,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.10/series b/queue-5.10/series index 37e100f4902..e9ef1ae93a3 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -442,3 +442,6 @@ sched-fair-check-idle_cpu-before-need_resched-to-det.patch sched-core-prevent-wakeup-of-ksoftirqd-during-idle-l.patch btrfs-fix-missing-snapshot-drew-unlock-when-root-is-.patch revert-unicode-don-t-special-case-ignorable-code-points.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 -- 2.47.2