From 466f833362e25b2bceccab44b701db2c41584b00 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 15 Jul 2025 13:59:16 +0200 Subject: [PATCH] 6.15-stable patches added patches: ksmbd-fix-potential-use-after-free-in-oplock-lease-break-ack.patch net-wangxun-revert-the-adjustment-of-the-irq-vector-sequence.patch x86-sev-use-tsc_factor-for-secure-tsc-frequency-calculation.patch --- ...after-free-in-oplock-lease-break-ack.patch | 90 ++++++++++ ...djustment-of-the-irq-vector-sequence.patch | 162 ++++++++++++++++++ queue-6.15/series | 3 + ...for-secure-tsc-frequency-calculation.patch | 124 ++++++++++++++ 4 files changed, 379 insertions(+) create mode 100644 queue-6.15/ksmbd-fix-potential-use-after-free-in-oplock-lease-break-ack.patch create mode 100644 queue-6.15/net-wangxun-revert-the-adjustment-of-the-irq-vector-sequence.patch create mode 100644 queue-6.15/x86-sev-use-tsc_factor-for-secure-tsc-frequency-calculation.patch diff --git a/queue-6.15/ksmbd-fix-potential-use-after-free-in-oplock-lease-break-ack.patch b/queue-6.15/ksmbd-fix-potential-use-after-free-in-oplock-lease-break-ack.patch new file mode 100644 index 0000000000..2c8ab03e73 --- /dev/null +++ b/queue-6.15/ksmbd-fix-potential-use-after-free-in-oplock-lease-break-ack.patch @@ -0,0 +1,90 @@ +From 50f930db22365738d9387c974416f38a06e8057e Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Tue, 8 Jul 2025 07:47:40 +0900 +Subject: ksmbd: fix potential use-after-free in oplock/lease break ack + +From: Namjae Jeon + +commit 50f930db22365738d9387c974416f38a06e8057e upstream. + +If ksmbd_iov_pin_rsp return error, use-after-free can happen by +accessing opinfo->state and opinfo_put and ksmbd_fd_put could +called twice. + +Reported-by: Ziyan Xu +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/server/smb2pdu.c | 29 +++++++++-------------------- + 1 file changed, 9 insertions(+), 20 deletions(-) + +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -8535,11 +8535,6 @@ static void smb20_oplock_break_ack(struc + goto err_out; + } + +- opinfo->op_state = OPLOCK_STATE_NONE; +- wake_up_interruptible_all(&opinfo->oplock_q); +- opinfo_put(opinfo); +- ksmbd_fd_put(work, fp); +- + rsp->StructureSize = cpu_to_le16(24); + rsp->OplockLevel = rsp_oplevel; + rsp->Reserved = 0; +@@ -8547,16 +8542,15 @@ static void smb20_oplock_break_ack(struc + rsp->VolatileFid = volatile_id; + rsp->PersistentFid = persistent_id; + ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break)); +- if (!ret) +- return; +- ++ if (ret) { + err_out: ++ smb2_set_err_rsp(work); ++ } ++ + opinfo->op_state = OPLOCK_STATE_NONE; + wake_up_interruptible_all(&opinfo->oplock_q); +- + opinfo_put(opinfo); + ksmbd_fd_put(work, fp); +- smb2_set_err_rsp(work); + } + + static int check_lease_state(struct lease *lease, __le32 req_state) +@@ -8686,11 +8680,6 @@ static void smb21_lease_break_ack(struct + } + + lease_state = lease->state; +- opinfo->op_state = OPLOCK_STATE_NONE; +- wake_up_interruptible_all(&opinfo->oplock_q); +- atomic_dec(&opinfo->breaking_cnt); +- wake_up_interruptible_all(&opinfo->oplock_brk); +- opinfo_put(opinfo); + + rsp->StructureSize = cpu_to_le16(36); + rsp->Reserved = 0; +@@ -8699,16 +8688,16 @@ static void smb21_lease_break_ack(struct + rsp->LeaseState = lease_state; + rsp->LeaseDuration = 0; + ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack)); +- if (!ret) +- return; +- ++ if (ret) { + err_out: ++ smb2_set_err_rsp(work); ++ } ++ ++ opinfo->op_state = OPLOCK_STATE_NONE; + wake_up_interruptible_all(&opinfo->oplock_q); + atomic_dec(&opinfo->breaking_cnt); + wake_up_interruptible_all(&opinfo->oplock_brk); +- + opinfo_put(opinfo); +- smb2_set_err_rsp(work); + } + + /** diff --git a/queue-6.15/net-wangxun-revert-the-adjustment-of-the-irq-vector-sequence.patch b/queue-6.15/net-wangxun-revert-the-adjustment-of-the-irq-vector-sequence.patch new file mode 100644 index 0000000000..3e39731ebf --- /dev/null +++ b/queue-6.15/net-wangxun-revert-the-adjustment-of-the-irq-vector-sequence.patch @@ -0,0 +1,162 @@ +From e37546ad1f9b2c777d3a21d7e50ce265ee3dece8 Mon Sep 17 00:00:00 2001 +From: Jiawen Wu +Date: Tue, 1 Jul 2025 14:30:29 +0800 +Subject: net: wangxun: revert the adjustment of the IRQ vector sequence + +From: Jiawen Wu + +commit e37546ad1f9b2c777d3a21d7e50ce265ee3dece8 upstream. + +Due to hardware limitations of NGBE, queue IRQs can only be requested +on vector 0 to 7. When the number of queues is set to the maximum 8, +the PCI IRQ vectors are allocated from 0 to 8. The vector 0 is used by +MISC interrupt, and althrough the vector 8 is used by queue interrupt, +it is unable to receive packets. This will cause some packets to be +dropped when RSS is enabled and they are assigned to queue 8. + +So revert the adjustment of the MISC IRQ location, to make it be the +last one in IRQ vectors. + +Fixes: 937d46ecc5f9 ("net: wangxun: add ethtool_ops for channel number") +Cc: stable@vger.kernel.org +Signed-off-by: Jiawen Wu +Reviewed-by: Larysa Zaremba +Link: https://patch.msgid.link/20250701063030.59340-3-jiawenwu@trustnetic.com +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/wangxun/libwx/wx_lib.c | 16 ++++++++-------- + drivers/net/ethernet/wangxun/libwx/wx_type.h | 2 +- + drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 2 +- + drivers/net/ethernet/wangxun/ngbe/ngbe_type.h | 2 +- + drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c | 4 ++-- + drivers/net/ethernet/wangxun/txgbe/txgbe_type.h | 4 ++-- + 6 files changed, 15 insertions(+), 15 deletions(-) + +--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c ++++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c +@@ -1680,7 +1680,7 @@ static void wx_set_num_queues(struct wx + */ + static int wx_acquire_msix_vectors(struct wx *wx) + { +- struct irq_affinity affd = { .pre_vectors = 1 }; ++ struct irq_affinity affd = { .post_vectors = 1 }; + int nvecs, i; + + /* We start by asking for one vector per queue pair */ +@@ -1717,16 +1717,17 @@ static int wx_acquire_msix_vectors(struc + return nvecs; + } + +- wx->msix_entry->entry = 0; +- wx->msix_entry->vector = pci_irq_vector(wx->pdev, 0); + nvecs -= 1; + for (i = 0; i < nvecs; i++) { + wx->msix_q_entries[i].entry = i; +- wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i + 1); ++ wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i); + } + + wx->num_q_vectors = nvecs; + ++ wx->msix_entry->entry = nvecs; ++ wx->msix_entry->vector = pci_irq_vector(wx->pdev, nvecs); ++ + return 0; + } + +@@ -2182,7 +2183,6 @@ static void wx_set_ivar(struct wx *wx, s + wr32(wx, WX_PX_MISC_IVAR, ivar); + } else { + /* tx or rx causes */ +- msix_vector += 1; /* offset for queue vectors */ + msix_vector |= WX_PX_IVAR_ALLOC_VAL; + index = ((16 * (queue & 1)) + (8 * direction)); + ivar = rd32(wx, WX_PX_IVAR(queue >> 1)); +@@ -2220,7 +2220,7 @@ void wx_write_eitr(struct wx_q_vector *q + + itr_reg |= WX_PX_ITR_CNT_WDIS; + +- wr32(wx, WX_PX_ITR(v_idx + 1), itr_reg); ++ wr32(wx, WX_PX_ITR(v_idx), itr_reg); + } + + /** +@@ -2266,9 +2266,9 @@ void wx_configure_vectors(struct wx *wx) + wx_write_eitr(q_vector); + } + +- wx_set_ivar(wx, -1, 0, 0); ++ wx_set_ivar(wx, -1, 0, v_idx); + if (pdev->msix_enabled) +- wr32(wx, WX_PX_ITR(0), 1950); ++ wr32(wx, WX_PX_ITR(v_idx), 1950); + } + EXPORT_SYMBOL(wx_configure_vectors); + +--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h ++++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h +@@ -1242,7 +1242,7 @@ struct wx { + }; + + #define WX_INTR_ALL (~0ULL) +-#define WX_INTR_Q(i) BIT((i) + 1) ++#define WX_INTR_Q(i) BIT((i)) + + /* register operations */ + #define wr32(a, reg, value) writel((value), ((a)->hw_addr + (reg))) +--- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c ++++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c +@@ -155,7 +155,7 @@ static void ngbe_irq_enable(struct wx *w + if (queues) + wx_intr_enable(wx, NGBE_INTR_ALL); + else +- wx_intr_enable(wx, NGBE_INTR_MISC); ++ wx_intr_enable(wx, NGBE_INTR_MISC(wx)); + } + + /** +--- a/drivers/net/ethernet/wangxun/ngbe/ngbe_type.h ++++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_type.h +@@ -85,7 +85,7 @@ + #define NGBE_PX_MISC_IC_TIMESYNC BIT(11) /* time sync */ + + #define NGBE_INTR_ALL 0x1FF +-#define NGBE_INTR_MISC BIT(0) ++#define NGBE_INTR_MISC(A) BIT((A)->num_q_vectors) + + #define NGBE_PHY_CONFIG(reg_offset) (0x14000 + ((reg_offset) * 4)) + #define NGBE_CFG_LAN_SPEED 0x14440 +--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c ++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c +@@ -21,7 +21,7 @@ void txgbe_irq_enable(struct wx *wx, boo + wr32(wx, WX_PX_MISC_IEN, TXGBE_PX_MISC_IEN_MASK); + + /* unmask interrupt */ +- wx_intr_enable(wx, TXGBE_INTR_MISC); ++ wx_intr_enable(wx, TXGBE_INTR_MISC(wx)); + if (queues) + wx_intr_enable(wx, TXGBE_INTR_QALL(wx)); + } +@@ -147,7 +147,7 @@ static irqreturn_t txgbe_misc_irq_thread + nhandled++; + } + +- wx_intr_enable(wx, TXGBE_INTR_MISC); ++ wx_intr_enable(wx, TXGBE_INTR_MISC(wx)); + return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); + } + +--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h ++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h +@@ -280,8 +280,8 @@ struct txgbe_fdir_filter { + #define TXGBE_DEFAULT_RX_WORK 128 + #endif + +-#define TXGBE_INTR_MISC BIT(0) +-#define TXGBE_INTR_QALL(A) GENMASK((A)->num_q_vectors, 1) ++#define TXGBE_INTR_MISC(A) BIT((A)->num_q_vectors) ++#define TXGBE_INTR_QALL(A) (TXGBE_INTR_MISC(A) - 1) + + #define TXGBE_MAX_EITR GENMASK(11, 3) + diff --git a/queue-6.15/series b/queue-6.15/series index 93aab6482a..33c5247a3b 100644 --- a/queue-6.15/series +++ b/queue-6.15/series @@ -187,3 +187,6 @@ hid-add-ignore-quirk-for-smartlinktechnology.patch hid-quirks-add-quirk-for-2-chicony-electronics-hp-5m.patch hid-nintendo-avoid-bluetooth-suspend-resume-stalls.patch selftests-bpf-adapt-one-more-case-in-test_lru_map-to-the-new-target_free.patch +net-wangxun-revert-the-adjustment-of-the-irq-vector-sequence.patch +x86-sev-use-tsc_factor-for-secure-tsc-frequency-calculation.patch +ksmbd-fix-potential-use-after-free-in-oplock-lease-break-ack.patch diff --git a/queue-6.15/x86-sev-use-tsc_factor-for-secure-tsc-frequency-calculation.patch b/queue-6.15/x86-sev-use-tsc_factor-for-secure-tsc-frequency-calculation.patch new file mode 100644 index 0000000000..691db81aa1 --- /dev/null +++ b/queue-6.15/x86-sev-use-tsc_factor-for-secure-tsc-frequency-calculation.patch @@ -0,0 +1,124 @@ +From 52e1a03e6cf61ae165f59f41c44394a653a0a788 Mon Sep 17 00:00:00 2001 +From: Nikunj A Dadhania +Date: Mon, 30 Jun 2025 13:48:58 +0530 +Subject: x86/sev: Use TSC_FACTOR for Secure TSC frequency calculation + +From: Nikunj A Dadhania + +commit 52e1a03e6cf61ae165f59f41c44394a653a0a788 upstream. + +When using Secure TSC, the GUEST_TSC_FREQ MSR reports a frequency based on +the nominal P0 frequency, which deviates slightly (typically ~0.2%) from +the actual mean TSC frequency due to clocking parameters. + +Over extended VM uptime, this discrepancy accumulates, causing clock skew +between the hypervisor and a SEV-SNP VM, leading to early timer interrupts as +perceived by the guest. + +The guest kernel relies on the reported nominal frequency for TSC-based +timekeeping, while the actual frequency set during SNP_LAUNCH_START may +differ. This mismatch results in inaccurate time calculations, causing the +guest to perceive hrtimers as firing earlier than expected. + +Utilize the TSC_FACTOR from the SEV firmware's secrets page (see "Secrets +Page Format" in the SNP Firmware ABI Specification) to calculate the mean +TSC frequency, ensuring accurate timekeeping and mitigating clock skew in +SEV-SNP VMs. + +Use early_ioremap_encrypted() to map the secrets page as +ioremap_encrypted() uses kmalloc() which is not available during early TSC +initialization and causes a panic. + + [ bp: Drop the silly dummy var: + https://lore.kernel.org/r/20250630192726.GBaGLlHl84xIopx4Pt@fat_crate.local ] + +Fixes: 73bbf3b0fbba ("x86/tsc: Init the TSC for Secure TSC guests") +Signed-off-by: Nikunj A Dadhania +Signed-off-by: Borislav Petkov (AMD) +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/20250630081858.485187-1-nikunj@amd.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/coco/sev/core.c | 22 +++++++++++++++++++--- + arch/x86/include/asm/sev.h | 17 ++++++++++++++++- + 2 files changed, 35 insertions(+), 4 deletions(-) + +--- a/arch/x86/coco/sev/core.c ++++ b/arch/x86/coco/sev/core.c +@@ -103,7 +103,7 @@ static u64 secrets_pa __ro_after_init; + */ + static u64 snp_tsc_scale __ro_after_init; + static u64 snp_tsc_offset __ro_after_init; +-static u64 snp_tsc_freq_khz __ro_after_init; ++static unsigned long snp_tsc_freq_khz __ro_after_init; + + /* #VC handler runtime per-CPU data */ + struct sev_es_runtime_data { +@@ -3347,15 +3347,31 @@ static unsigned long securetsc_get_tsc_k + + void __init snp_secure_tsc_init(void) + { +- unsigned long long tsc_freq_mhz; ++ struct snp_secrets_page *secrets; ++ unsigned long tsc_freq_mhz; ++ void *mem; + + if (!cc_platform_has(CC_ATTR_GUEST_SNP_SECURE_TSC)) + return; + ++ mem = early_memremap_encrypted(secrets_pa, PAGE_SIZE); ++ if (!mem) { ++ pr_err("Unable to get TSC_FACTOR: failed to map the SNP secrets page.\n"); ++ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SECURE_TSC); ++ } ++ ++ secrets = (__force struct snp_secrets_page *)mem; ++ + setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ); + rdmsrl(MSR_AMD64_GUEST_TSC_FREQ, tsc_freq_mhz); +- snp_tsc_freq_khz = (unsigned long)(tsc_freq_mhz * 1000); ++ ++ /* Extract the GUEST TSC MHZ from BIT[17:0], rest is reserved space */ ++ tsc_freq_mhz &= GENMASK_ULL(17, 0); ++ ++ snp_tsc_freq_khz = SNP_SCALE_TSC_FREQ(tsc_freq_mhz * 1000, secrets->tsc_factor); + + x86_platform.calibrate_cpu = securetsc_get_tsc_khz; + x86_platform.calibrate_tsc = securetsc_get_tsc_khz; ++ ++ early_memunmap(mem, PAGE_SIZE); + } +--- a/arch/x86/include/asm/sev.h ++++ b/arch/x86/include/asm/sev.h +@@ -192,6 +192,18 @@ struct snp_tsc_info_resp { + u8 rsvd2[100]; + } __packed; + ++/* ++ * Obtain the mean TSC frequency by decreasing the nominal TSC frequency with ++ * TSC_FACTOR as documented in the SNP Firmware ABI specification: ++ * ++ * GUEST_TSC_FREQ * (1 - (TSC_FACTOR * 0.00001)) ++ * ++ * which is equivalent to: ++ * ++ * GUEST_TSC_FREQ -= (GUEST_TSC_FREQ * TSC_FACTOR) / 100000; ++ */ ++#define SNP_SCALE_TSC_FREQ(freq, factor) ((freq) - (freq) * (factor) / 100000) ++ + struct snp_guest_req { + void *req_buf; + size_t req_sz; +@@ -251,8 +263,11 @@ struct snp_secrets_page { + u8 svsm_guest_vmpl; + u8 rsvd3[3]; + ++ /* The percentage decrease from nominal to mean TSC frequency. */ ++ u32 tsc_factor; ++ + /* Remainder of page */ +- u8 rsvd4[3744]; ++ u8 rsvd4[3740]; + } __packed; + + struct snp_msg_desc { -- 2.47.2