diff options
Diffstat (limited to 'debian/patches/features')
64 files changed, 7352 insertions, 0 deletions
diff --git a/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch new file mode 100644 index 000000000..f2278ce63 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch @@ -0,0 +1,130 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:02 +0800 +Subject: [PATCH 3/4] MODSIGN: checking the blacklisted hash before loading a + kernel module +Origin: https://lore.kernel.org/patchwork/patch/933175/ + +This patch adds the logic for checking the kernel module's hash +base on blacklist. The hash must be generated by sha256 and enrolled +to dbx/mokx. + +For example: + sha256sum sample.ko + mokutil --mokx --import-hash $HASH_RESULT + +Whether the signature on ko file is stripped or not, the hash can be +compared by kernel. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +[bwh: Forward-ported to 5.19: + - The type parameter to is_hash_blacklisted() is now an enumeration + rather than a string + - Adjust filename, context] +--- + kernel/module/signing.c | 59 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 57 insertions(+), 2 deletions(-) + +--- a/kernel/module/signing.c ++++ b/kernel/module/signing.c +@@ -13,6 +13,8 @@ + #include <linux/verification.h> + #include <linux/security.h> + #include <crypto/public_key.h> ++#include <crypto/hash.h> ++#include <keys/system_keyring.h> + #include <uapi/linux/module.h> + #include "internal.h" + +@@ -37,13 +39,60 @@ + sig_enforce = true; + } + ++static int mod_is_hash_blacklisted(const void *mod, size_t verifylen) ++{ ++ struct crypto_shash *tfm; ++ struct shash_desc *desc; ++ size_t digest_size, desc_size; ++ u8 *digest; ++ int ret; ++ ++ tfm = crypto_alloc_shash("sha256", 0, 0); ++ if (IS_ERR(tfm)) { ++ ret = PTR_ERR(tfm); ++ goto error_return; ++ } ++ ++ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); ++ digest_size = crypto_shash_digestsize(tfm); ++ digest = kzalloc(digest_size + desc_size, GFP_KERNEL); ++ if (!digest) { ++ pr_err("digest memory buffer allocate fail\n"); ++ ret = -ENOMEM; ++ goto error_digest; ++ } ++ desc = (void *)digest + digest_size; ++ desc->tfm = tfm; ++ ret = crypto_shash_init(desc); ++ if (ret < 0) ++ goto error_shash; ++ ++ ret = crypto_shash_finup(desc, mod, verifylen, digest); ++ if (ret < 0) ++ goto error_shash; ++ ++ pr_debug("%ld digest: %*phN\n", verifylen, (int) digest_size, digest); ++ ++ ret = is_hash_blacklisted(digest, digest_size, BLACKLIST_HASH_BINARY); ++ if (ret == -EKEYREJECTED) ++ pr_err("Module hash %*phN is blacklisted\n", ++ (int) digest_size, digest); ++ ++error_shash: ++ kfree(digest); ++error_digest: ++ crypto_free_shash(tfm); ++error_return: ++ return ret; ++} ++ + /* + * Verify the signature on a module. + */ + int mod_verify_sig(const void *mod, struct load_info *info) + { + struct module_signature ms; +- size_t sig_len, modlen = info->len; ++ size_t sig_len, modlen = info->len, wholelen; + int ret; + + pr_devel("==>%s(,%zu)\n", __func__, modlen); +@@ -51,6 +100,7 @@ + if (modlen <= sizeof(ms)) + return -EBADMSG; + ++ wholelen = modlen + sizeof(MODULE_SIG_STRING) - 1; + memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); + + ret = mod_check_sig(&ms, modlen, "module"); +@@ -61,10 +111,17 @@ + modlen -= sig_len + sizeof(ms); + info->len = modlen; + +- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, ++ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, + VERIFY_USE_SECONDARY_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); ++ pr_devel("verify_pkcs7_signature() = %d\n", ret); ++ ++ /* checking hash of module is in blacklist */ ++ if (!ret) ++ ret = mod_is_hash_blacklisted(mod, wholelen); ++ ++ return ret; + } + + int module_sig_check(struct load_info *info, int flags) diff --git a/debian/patches/features/all/db-mok-keyring/KEYS-Make-use-of-platform-keyring-for-module-signature.patch b/debian/patches/features/all/db-mok-keyring/KEYS-Make-use-of-platform-keyring-for-module-signature.patch new file mode 100644 index 000000000..e46aefe4d --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/KEYS-Make-use-of-platform-keyring-for-module-signature.patch @@ -0,0 +1,33 @@ +From: Robert Holmes <robeholmes@gmail.com> +Date: Tue, 23 Apr 2019 07:39:29 +0000 +Subject: [PATCH] KEYS: Make use of platform keyring for module signature + verify +Bug-Debian: https://bugs.debian.org/935945 +Bug-Debian: https://bugs.debian.org/1030200 +Origin: https://src.fedoraproject.org/rpms/kernel/raw/master/f/KEYS-Make-use-of-platform-keyring-for-module-signature.patch +Forwarded: https://lore.kernel.org/linux-modules/qvgp2il2co4iyxkzxvcs4p2bpyilqsbfgcprtpfrsajwae2etc@3z2s2o52i3xg/t/#u + +This allows a cert in DB to be used to sign modules, +in addition to certs in the MoK and built-in keyrings. + +Signed-off-by: Robert Holmes <robeholmes@gmail.com> +Signed-off-by: Jeremy Cline <jcline@redhat.com> +[bwh: Forward-ported to 5.19: adjust filename] +[наб: reinstate for 6.1, re-write description] +--- +--- a/kernel/module/signing.c ++++ b/kernel/module/signing.c +@@ -116,6 +116,13 @@ int mod_verify_sig(const void *mod, stru + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); + pr_devel("verify_pkcs7_signature() = %d\n", ret); ++ if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) { ++ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, ++ VERIFY_USE_PLATFORM_KEYRING, ++ VERIFYING_MODULE_SIGNATURE, ++ NULL, NULL); ++ pr_devel("verify_pkcs7_signature() = %d\n", ret); ++ } + + /* checking hash of module is in blacklist */ + if (!ret) diff --git a/debian/patches/features/all/db-mok-keyring/trust-machine-keyring-by-default.patch b/debian/patches/features/all/db-mok-keyring/trust-machine-keyring-by-default.patch new file mode 100644 index 000000000..7c32a018f --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/trust-machine-keyring-by-default.patch @@ -0,0 +1,16 @@ +Author: Luca Boccassi <bluca@debian.org> +Description: trust machine keyring (MoK) by default + Debian always trusted keys in MoK by default. Upstream made it conditional on + a new EFI variable being set. To keep backward compatibility skip this check. +--- a/security/integrity/platform_certs/machine_keyring.c ++++ b/security/integrity/platform_certs/machine_keyring.c +@@ -69,8 +69,7 @@ + if (!initialized) { + initialized = true; + +- if (uefi_check_trust_mok_keys()) +- trust_mok = true; ++ trust_mok = true; + } + + return trust_mok; diff --git a/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch b/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch new file mode 100644 index 000000000..a24ba17ef --- /dev/null +++ b/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch @@ -0,0 +1,149 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 24 Aug 2009 23:19:58 +0100 +Subject: af9005: Use request_firmware() to load register init script +Forwarded: no + +Read the register init script from the Windows driver. This is sick +but should avoid the potential copyright infringement in distributing +a version of the script which is directly derived from the driver. +--- + drivers/media/dvb/dvb-usb/Kconfig | 2 +- + drivers/media/dvb/dvb-usb/af9005-fe.c | 66 ++++++++++++++++++++++++++------ + 2 files changed, 54 insertions(+), 14 deletions(-) + +Index: debian-kernel/drivers/media/usb/dvb-usb/Kconfig +=================================================================== +--- debian-kernel.orig/drivers/media/usb/dvb-usb/Kconfig ++++ debian-kernel/drivers/media/usb/dvb-usb/Kconfig +@@ -260,10 +260,10 @@ config DVB_USB_OPERA1 + + config DVB_USB_AF9005 + tristate "Afatech AF9005 DVB-T USB1.1 support" +- depends on BROKEN + depends on DVB_USB + select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT ++ select FW_LOADER + help + Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver + and the TerraTec Cinergy T USB XE (Rev.1) +Index: debian-kernel/drivers/media/usb/dvb-usb/af9005-fe.c +=================================================================== +--- debian-kernel.orig/drivers/media/usb/dvb-usb/af9005-fe.c ++++ debian-kernel/drivers/media/usb/dvb-usb/af9005-fe.c +@@ -9,10 +9,26 @@ + * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information + */ + #include "af9005.h" +-#include "af9005-script.h" + #include "mt2060.h" + #include "qt1010.h" + #include <asm/div64.h> ++#include <linux/firmware.h> ++ ++/* Register initialisation script to be extracted from the Windows driver */ ++ ++typedef struct { ++ __le16 reg; ++ u8 pos; ++ u8 len; ++ u8 val; ++ u8 pad; ++} __packed RegDesc; ++ ++#define WIN_DRV_NAME "AF05BDA.sys" ++#define WIN_DRV_VERSION "6.3.2.1" ++#define WIN_DRV_SIZE 133504 ++#define WIN_DRV_SCRIPT_OFFSET 88316 ++#define WIN_DRV_SCRIPT_SIZE 1110 + + struct af9005_fe_state { + struct dvb_usb_device *d; +@@ -804,6 +820,8 @@ static int af9005_fe_init(struct dvb_fro + { + struct af9005_fe_state *state = fe->demodulator_priv; + struct dvb_usb_adapter *adap = fe->dvb->priv; ++ const struct firmware *fw; ++ const RegDesc *script; + int ret, i, scriptlen; + u8 temp, temp0 = 0, temp1 = 0, temp2 = 0; + u8 buf[2]; +@@ -956,37 +974,55 @@ static int af9005_fe_init(struct dvb_fro + if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01))) + return ret; + +- /* load init script */ +- deb_info("load init script\n"); +- scriptlen = sizeof(script) / sizeof(RegDesc); ++ /* load and validate init script */ ++ deb_info("load init script from Windows driver\n"); ++ ret = request_firmware(&fw, WIN_DRV_NAME, &state->d->udev->dev); ++ if (ret) ++ return ret; ++ BUILD_BUG_ON(sizeof(RegDesc) != 6); ++ if (fw->size != WIN_DRV_SIZE || ++ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET, ++ "\x80\xa1\x00\x08\x0a\x00", 6) || ++ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET + WIN_DRV_SCRIPT_SIZE - 6, ++ "\x49\xa3\x00\x06\x02\x00", 6)) { ++ err("%s is invalid - should be version %s, size %u bytes\n", ++ WIN_DRV_NAME, WIN_DRV_VERSION, WIN_DRV_SIZE); ++ ret = -EINVAL; ++ goto fail_release; ++ } ++ ++ script = (const RegDesc *)(fw->data + WIN_DRV_SCRIPT_OFFSET); ++ scriptlen = WIN_DRV_SCRIPT_SIZE / sizeof(RegDesc); + for (i = 0; i < scriptlen; i++) { ++ u16 reg = le16_to_cpu(script[i].reg); + if ((ret = +- af9005_write_register_bits(state->d, script[i].reg, ++ af9005_write_register_bits(state->d, reg, + script[i].pos, + script[i].len, script[i].val))) +- return ret; ++ goto fail_release; + /* save 3 bytes of original fcw */ +- if (script[i].reg == 0xae18) ++ if (reg == 0xae18) + temp2 = script[i].val; +- if (script[i].reg == 0xae19) ++ if (reg == 0xae19) + temp1 = script[i].val; +- if (script[i].reg == 0xae1a) ++ if (reg == 0xae1a) + temp0 = script[i].val; + + /* save original unplug threshold */ +- if (script[i].reg == xd_p_reg_unplug_th) ++ if (reg == xd_p_reg_unplug_th) + state->original_if_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_rf_gain_th) ++ if (reg == xd_p_reg_unplug_rf_gain_th) + state->original_rf_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th) ++ if (reg == xd_p_reg_unplug_dtop_if_gain_th) + state->original_dtop_if_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th) ++ if (reg == xd_p_reg_unplug_dtop_rf_gain_th) + state->original_dtop_rf_unplug_th = script[i].val; + + } + state->original_fcw = + ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0; + ++ release_firmware(fw); + + /* save original TOPs */ + deb_info("save original TOPs\n"); +@@ -1066,6 +1102,10 @@ static int af9005_fe_init(struct dvb_fro + + deb_info("profit!\n"); + return 0; ++ ++fail_release: ++ release_firmware(fw); ++ return ret; + } + + static int af9005_fe_sleep(struct dvb_frontend *fe) diff --git a/debian/patches/features/all/ethernet-microsoft/0001-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch b/debian/patches/features/all/ethernet-microsoft/0001-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch new file mode 100644 index 000000000..f17692d6c --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0001-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch @@ -0,0 +1,89 @@ +From 7c765fdf86fc9089b75d15ee33cdf30d9d9115d6 Mon Sep 17 00:00:00 2001 +From: Bastian Blank <waldi@debian.org> +Date: Wed, 12 Jul 2023 14:13:14 +0000 +Subject: [PATCH 01/23] net: Remove the obsolte u64_stats_fetch_*_irq() users + (drivers). + +Now that the 32bit UP oddity is gone and 32bit uses always a sequence +count, there is no need for the fetch_irq() variants anymore. + +Convert to the regular interface. + +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +(cherry picked from commit 068c38ad88ccb09e5e966d4db5cedab0e02b3b95) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 8 ++++---- + drivers/net/ethernet/microsoft/mana/mana_ethtool.c | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 27a0f3af8aab..aec4bab6be56 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -315,10 +315,10 @@ static void mana_get_stats64(struct net_device *ndev, + rx_stats = &apc->rxqs[q]->stats; + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + st->rx_packets += packets; + st->rx_bytes += bytes; +@@ -328,10 +328,10 @@ static void mana_get_stats64(struct net_device *ndev, + tx_stats = &apc->tx_qp[q].txq.stats; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + st->tx_packets += packets; + st->tx_bytes += bytes; +diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +index c530db76880f..96d55c91c969 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +@@ -90,13 +90,13 @@ static void mana_get_ethtool_stats(struct net_device *ndev, + rx_stats = &apc->rxqs[q]->stats; + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; + xdp_drop = rx_stats->xdp_drop; + xdp_tx = rx_stats->xdp_tx; + xdp_redirect = rx_stats->xdp_redirect; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + data[i++] = packets; + data[i++] = bytes; +@@ -109,11 +109,11 @@ static void mana_get_ethtool_stats(struct net_device *ndev, + tx_stats = &apc->tx_qp[q].txq.stats; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; + xdp_xmit = tx_stats->xdp_xmit; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + data[i++] = packets; + data[i++] = bytes; +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0002-net-mana-Assign-interrupts-to-CPUs-based-on-NUMA-nod.patch b/debian/patches/features/all/ethernet-microsoft/0002-net-mana-Assign-interrupts-to-CPUs-based-on-NUMA-nod.patch new file mode 100644 index 000000000..6fc9d9cc7 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0002-net-mana-Assign-interrupts-to-CPUs-based-on-NUMA-nod.patch @@ -0,0 +1,114 @@ +From 8bdc2e0b4963e7cfd41b43ed117e8f0dec13fe29 Mon Sep 17 00:00:00 2001 +From: Saurabh Sengar <ssengar@linux.microsoft.com> +Date: Mon, 31 Oct 2022 23:06:01 -0700 +Subject: [PATCH 02/23] net: mana: Assign interrupts to CPUs based on NUMA + nodes + +In large VMs with multiple NUMA nodes, network performance is usually +best if network interrupts are all assigned to the same virtual NUMA +node. This patch assigns online CPU according to a numa aware policy, +local cpus are returned first, followed by non-local ones, then it wraps +around. + +Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com> +Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> +Link: https://lore.kernel.org/r/1667282761-11547-1-git-send-email-ssengar@linux.microsoft.com +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +(cherry picked from commit 71fa6887eeca7b631528f9c7a39815498de8028c) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/gdma.h | 1 + + .../net/ethernet/microsoft/mana/gdma_main.c | 30 +++++++++++++++++-- + 2 files changed, 28 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma.h b/drivers/net/ethernet/microsoft/mana/gdma.h +index 48b0ab56bdb0..68684a8bcead 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma.h ++++ b/drivers/net/ethernet/microsoft/mana/gdma.h +@@ -356,6 +356,7 @@ struct gdma_context { + void __iomem *shm_base; + void __iomem *db_page_base; + u32 db_page_size; ++ int numa_node; + + /* Shared memory chanenl (used to bootstrap HWC) */ + struct shm_channel shm_channel; +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index d674ebda2053..abe9888a40aa 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -1208,8 +1208,10 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev) + struct gdma_context *gc = pci_get_drvdata(pdev); + struct gdma_irq_context *gic; + unsigned int max_irqs; ++ u16 *cpus; ++ cpumask_var_t req_mask; + int nvec, irq; +- int err, i, j; ++ int err, i = 0, j; + + if (max_queues_per_port > MANA_MAX_NUM_QUEUES) + max_queues_per_port = MANA_MAX_NUM_QUEUES; +@@ -1228,7 +1230,21 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev) + goto free_irq_vector; + } + ++ if (!zalloc_cpumask_var(&req_mask, GFP_KERNEL)) { ++ err = -ENOMEM; ++ goto free_irq; ++ } ++ ++ cpus = kcalloc(nvec, sizeof(*cpus), GFP_KERNEL); ++ if (!cpus) { ++ err = -ENOMEM; ++ goto free_mask; ++ } ++ for (i = 0; i < nvec; i++) ++ cpus[i] = cpumask_local_spread(i, gc->numa_node); ++ + for (i = 0; i < nvec; i++) { ++ cpumask_set_cpu(cpus[i], req_mask); + gic = &gc->irq_contexts[i]; + gic->handler = NULL; + gic->arg = NULL; +@@ -1243,13 +1259,17 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev) + irq = pci_irq_vector(pdev, i); + if (irq < 0) { + err = irq; +- goto free_irq; ++ goto free_mask; + } + + err = request_irq(irq, mana_gd_intr, 0, gic->name, gic); + if (err) +- goto free_irq; ++ goto free_mask; ++ irq_set_affinity_and_hint(irq, req_mask); ++ cpumask_clear(req_mask); + } ++ free_cpumask_var(req_mask); ++ kfree(cpus); + + err = mana_gd_alloc_res_map(nvec, &gc->msix_resource); + if (err) +@@ -1260,6 +1280,9 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev) + + return 0; + ++free_mask: ++ free_cpumask_var(req_mask); ++ kfree(cpus); + free_irq: + for (j = i - 1; j >= 0; j--) { + irq = pci_irq_vector(pdev, j); +@@ -1389,6 +1412,7 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + if (!bar0_va) + goto free_gc; + ++ gc->numa_node = dev_to_node(&pdev->dev); + gc->is_pf = mana_is_pf(pdev->device); + gc->bar0_va = bar0_va; + gc->dev = &pdev->dev; +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0003-net-mana-Add-support-for-auxiliary-device.patch b/debian/patches/features/all/ethernet-microsoft/0003-net-mana-Add-support-for-auxiliary-device.patch new file mode 100644 index 000000000..a639b69c9 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0003-net-mana-Add-support-for-auxiliary-device.patch @@ -0,0 +1,178 @@ +From 63ea159035f1c00da99016a1c71380d90f156ad4 Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:19 -0700 +Subject: [PATCH 03/23] net: mana: Add support for auxiliary device + +In preparation for supporting MANA RDMA driver, add support for auxiliary +device in the Ethernet driver. The RDMA device is modeled as an auxiliary +device to the Ethernet device. + +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-2-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit a69839d4327d053b18d8e1b0e7ddeee78db78f4f) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/Kconfig | 1 + + drivers/net/ethernet/microsoft/mana/gdma.h | 2 + + .../ethernet/microsoft/mana/mana_auxiliary.h | 10 +++ + drivers/net/ethernet/microsoft/mana/mana_en.c | 83 ++++++++++++++++++- + 4 files changed, 95 insertions(+), 1 deletion(-) + create mode 100644 drivers/net/ethernet/microsoft/mana/mana_auxiliary.h + +--- a/drivers/net/ethernet/microsoft/Kconfig ++++ b/drivers/net/ethernet/microsoft/Kconfig +@@ -19,6 +19,7 @@ config MICROSOFT_MANA + tristate "Microsoft Azure Network Adapter (MANA) support" + depends on PCI_MSI && X86_64 + depends on PCI_HYPERV ++ select AUXILIARY_BUS + select PAGE_POOL + help + This driver supports Microsoft Azure Network Adapter (MANA). +--- a/drivers/net/ethernet/microsoft/mana/gdma.h ++++ b/drivers/net/ethernet/microsoft/mana/gdma.h +@@ -204,6 +204,8 @@ struct gdma_dev { + + /* GDMA driver specific pointer */ + void *driver_data; ++ ++ struct auxiliary_device *adev; + }; + + #define MINIMUM_SUPPORTED_PAGE_SIZE PAGE_SIZE +--- /dev/null ++++ b/drivers/net/ethernet/microsoft/mana/mana_auxiliary.h +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* Copyright (c) 2022, Microsoft Corporation. */ ++ ++#include "mana.h" ++#include <linux/auxiliary_bus.h> ++ ++struct mana_adev { ++ struct auxiliary_device adev; ++ struct gdma_dev *mdev; ++}; +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -14,6 +14,19 @@ + #include <net/ip6_checksum.h> + + #include "mana.h" ++#include "mana_auxiliary.h" ++ ++static DEFINE_IDA(mana_adev_ida); ++ ++static int mana_adev_idx_alloc(void) ++{ ++ return ida_alloc(&mana_adev_ida, GFP_KERNEL); ++} ++ ++static void mana_adev_idx_free(int idx) ++{ ++ ida_free(&mana_adev_ida, idx); ++} + + /* Microsoft Azure Network Adapter (MANA) functions */ + +@@ -2145,6 +2158,69 @@ free_net: + return err; + } + ++static void adev_release(struct device *dev) ++{ ++ struct mana_adev *madev = container_of(dev, struct mana_adev, adev.dev); ++ ++ kfree(madev); ++} ++ ++static void remove_adev(struct gdma_dev *gd) ++{ ++ struct auxiliary_device *adev = gd->adev; ++ int id = adev->id; ++ ++ auxiliary_device_delete(adev); ++ auxiliary_device_uninit(adev); ++ ++ mana_adev_idx_free(id); ++ gd->adev = NULL; ++} ++ ++static int add_adev(struct gdma_dev *gd) ++{ ++ struct auxiliary_device *adev; ++ struct mana_adev *madev; ++ int ret; ++ ++ madev = kzalloc(sizeof(*madev), GFP_KERNEL); ++ if (!madev) ++ return -ENOMEM; ++ ++ adev = &madev->adev; ++ ret = mana_adev_idx_alloc(); ++ if (ret < 0) ++ goto idx_fail; ++ adev->id = ret; ++ ++ adev->name = "rdma"; ++ adev->dev.parent = gd->gdma_context->dev; ++ adev->dev.release = adev_release; ++ madev->mdev = gd; ++ ++ ret = auxiliary_device_init(adev); ++ if (ret) ++ goto init_fail; ++ ++ ret = auxiliary_device_add(adev); ++ if (ret) ++ goto add_fail; ++ ++ gd->adev = adev; ++ return 0; ++ ++add_fail: ++ auxiliary_device_uninit(adev); ++ ++init_fail: ++ mana_adev_idx_free(adev->id); ++ ++idx_fail: ++ kfree(madev); ++ ++ return ret; ++} ++ + int mana_probe(struct gdma_dev *gd, bool resuming) + { + struct gdma_context *gc = gd->gdma_context; +@@ -2212,6 +2288,8 @@ int mana_probe(struct gdma_dev *gd, bool + break; + } + } ++ ++ err = add_adev(gd); + out: + if (err) + mana_remove(gd, false); +@@ -2228,6 +2306,10 @@ void mana_remove(struct gdma_dev *gd, bo + int err; + int i; + ++ /* adev currently doesn't support suspending, always remove it */ ++ if (gd->adev) ++ remove_adev(gd); ++ + for (i = 0; i < ac->num_ports; i++) { + ndev = ac->ports[i]; + if (!ndev) { +@@ -2260,7 +2342,6 @@ void mana_remove(struct gdma_dev *gd, bo + } + + mana_destroy_eq(ac); +- + out: + mana_gd_deregister_device(gd); + diff --git a/debian/patches/features/all/ethernet-microsoft/0004-net-mana-Record-the-physical-address-for-doorbell-pa.patch b/debian/patches/features/all/ethernet-microsoft/0004-net-mana-Record-the-physical-address-for-doorbell-pa.patch new file mode 100644 index 000000000..21568f6aa --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0004-net-mana-Record-the-physical-address-for-doorbell-pa.patch @@ -0,0 +1,63 @@ +From 108ed3960c8f1e65ad64b22a4a073c4e42204132 Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:20 -0700 +Subject: [PATCH 04/23] net: mana: Record the physical address for doorbell + page region + +For supporting RDMA device with multiple user contexts with their +individual doorbell pages, record the start address of doorbell page +region for use by the RDMA driver to allocate user context doorbell IDs. + +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-3-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit f3dc096246091048677c45cfc0e24ad512927b52) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/gdma.h | 2 ++ + drivers/net/ethernet/microsoft/mana/gdma_main.c | 4 ++++ + 2 files changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma.h b/drivers/net/ethernet/microsoft/mana/gdma.h +index df0ffe35db92..86d8a9e36005 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma.h ++++ b/drivers/net/ethernet/microsoft/mana/gdma.h +@@ -354,9 +354,11 @@ struct gdma_context { + u32 test_event_eq_id; + + bool is_pf; ++ phys_addr_t bar0_pa; + void __iomem *bar0_va; + void __iomem *shm_base; + void __iomem *db_page_base; ++ phys_addr_t phys_db_page_base; + u32 db_page_size; + int numa_node; + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index abe9888a40aa..a00bd88443d3 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -44,6 +44,9 @@ static void mana_gd_init_vf_regs(struct pci_dev *pdev) + gc->db_page_base = gc->bar0_va + + mana_gd_r64(gc, GDMA_REG_DB_PAGE_OFFSET); + ++ gc->phys_db_page_base = gc->bar0_pa + ++ mana_gd_r64(gc, GDMA_REG_DB_PAGE_OFFSET); ++ + gc->shm_base = gc->bar0_va + mana_gd_r64(gc, GDMA_REG_SHM_OFFSET); + } + +@@ -1407,6 +1410,7 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + + mutex_init(&gc->eq_test_event_mutex); + pci_set_drvdata(pdev, gc); ++ gc->bar0_pa = pci_resource_start(pdev, 0); + + bar0_va = pci_iomap(pdev, bar, 0); + if (!bar0_va) +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0005-net-mana-Handle-vport-sharing-between-devices.patch b/debian/patches/features/all/ethernet-microsoft/0005-net-mana-Handle-vport-sharing-between-devices.patch new file mode 100644 index 000000000..f02172221 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0005-net-mana-Handle-vport-sharing-between-devices.patch @@ -0,0 +1,150 @@ +From 35238c1a74198a73e35ed386a7a3992522de804d Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:21 -0700 +Subject: [PATCH 05/23] net: mana: Handle vport sharing between devices + +For outgoing packets, the PF requires the VF to configure the vport with +corresponding protection domain and doorbell ID for the kernel or user +context. The vport can't be shared between different contexts. + +Implement the logic to exclusively take over the vport by either the +Ethernet device or RDMA device. + +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-4-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit b5c1c9855be3b5b978fde975a63df3cabc273faa) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana.h | 7 +++ + drivers/net/ethernet/microsoft/mana/mana_en.c | 53 ++++++++++++++++++- + 2 files changed, 58 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana.h b/drivers/net/ethernet/microsoft/mana/mana.h +index d58be64374c8..2883a08dbfb5 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana.h ++++ b/drivers/net/ethernet/microsoft/mana/mana.h +@@ -380,6 +380,10 @@ struct mana_port_context { + mana_handle_t port_handle; + mana_handle_t pf_filter_handle; + ++ /* Mutex for sharing access to vport_use_count */ ++ struct mutex vport_mutex; ++ int vport_use_count; ++ + u16 port_idx; + + bool port_is_up; +@@ -631,4 +635,7 @@ struct mana_tx_package { + struct gdma_posted_wqe_info wqe_info; + }; + ++int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id, ++ u32 doorbell_pg_id); ++void mana_uncfg_vport(struct mana_port_context *apc); + #endif /* _MANA_H */ +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index b9e2723ce167..c5ab5cb63cb7 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -646,13 +646,48 @@ static int mana_query_vport_cfg(struct mana_port_context *apc, u32 vport_index, + return 0; + } + +-static int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id, +- u32 doorbell_pg_id) ++void mana_uncfg_vport(struct mana_port_context *apc) ++{ ++ mutex_lock(&apc->vport_mutex); ++ apc->vport_use_count--; ++ WARN_ON(apc->vport_use_count < 0); ++ mutex_unlock(&apc->vport_mutex); ++} ++EXPORT_SYMBOL_NS(mana_uncfg_vport, NET_MANA); ++ ++int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id, ++ u32 doorbell_pg_id) + { + struct mana_config_vport_resp resp = {}; + struct mana_config_vport_req req = {}; + int err; + ++ /* This function is used to program the Ethernet port in the hardware ++ * table. It can be called from the Ethernet driver or the RDMA driver. ++ * ++ * For Ethernet usage, the hardware supports only one active user on a ++ * physical port. The driver checks on the port usage before programming ++ * the hardware when creating the RAW QP (RDMA driver) or exposing the ++ * device to kernel NET layer (Ethernet driver). ++ * ++ * Because the RDMA driver doesn't know in advance which QP type the ++ * user will create, it exposes the device with all its ports. The user ++ * may not be able to create RAW QP on a port if this port is already ++ * in used by the Ethernet driver from the kernel. ++ * ++ * This physical port limitation only applies to the RAW QP. For RC QP, ++ * the hardware doesn't have this limitation. The user can create RC ++ * QPs on a physical port up to the hardware limits independent of the ++ * Ethernet usage on the same port. ++ */ ++ mutex_lock(&apc->vport_mutex); ++ if (apc->vport_use_count > 0) { ++ mutex_unlock(&apc->vport_mutex); ++ return -EBUSY; ++ } ++ apc->vport_use_count++; ++ mutex_unlock(&apc->vport_mutex); ++ + mana_gd_init_req_hdr(&req.hdr, MANA_CONFIG_VPORT_TX, + sizeof(req), sizeof(resp)); + req.vport = apc->port_handle; +@@ -679,9 +714,16 @@ static int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id, + + apc->tx_shortform_allowed = resp.short_form_allowed; + apc->tx_vp_offset = resp.tx_vport_offset; ++ ++ netdev_info(apc->ndev, "Configured vPort %llu PD %u DB %u\n", ++ apc->port_handle, protection_dom_id, doorbell_pg_id); + out: ++ if (err) ++ mana_uncfg_vport(apc); ++ + return err; + } ++EXPORT_SYMBOL_NS(mana_cfg_vport, NET_MANA); + + static int mana_cfg_vport_steering(struct mana_port_context *apc, + enum TRI_STATE rx, +@@ -742,6 +784,9 @@ static int mana_cfg_vport_steering(struct mana_port_context *apc, + resp.hdr.status); + err = -EPROTO; + } ++ ++ netdev_info(ndev, "Configured steering vPort %llu entries %u\n", ++ apc->port_handle, num_entries); + out: + kfree(req); + return err; +@@ -1810,6 +1855,7 @@ static void mana_destroy_vport(struct mana_port_context *apc) + } + + mana_destroy_txq(apc); ++ mana_uncfg_vport(apc); + + if (gd->gdma_context->is_pf) + mana_pf_deregister_hw_vport(apc); +@@ -2082,6 +2128,9 @@ static int mana_probe_port(struct mana_context *ac, int port_idx, + apc->pf_filter_handle = INVALID_MANA_HANDLE; + apc->port_idx = port_idx; + ++ mutex_init(&apc->vport_mutex); ++ apc->vport_use_count = 0; ++ + ndev->netdev_ops = &mana_devops; + ndev->ethtool_ops = &mana_ethtool_ops; + ndev->mtu = ETH_DATA_LEN; +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0006-net-mana-Set-the-DMA-device-max-segment-size.patch b/debian/patches/features/all/ethernet-microsoft/0006-net-mana-Set-the-DMA-device-max-segment-size.patch new file mode 100644 index 000000000..6ac8249d0 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0006-net-mana-Set-the-DMA-device-max-segment-size.patch @@ -0,0 +1,40 @@ +From 09b5391c16655893159fe8a58c8b7e31499ef107 Mon Sep 17 00:00:00 2001 +From: Ajay Sharma <sharmaajay@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:22 -0700 +Subject: [PATCH 06/23] net: mana: Set the DMA device max segment size + +MANA hardware doesn't have any restrictions on the DMA segment size, set it +to the max allowed value. + +Signed-off-by: Ajay Sharma <sharmaajay@microsoft.com> +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-5-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit 6fe254160bd033a1e62dbad9b734183b31144678) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/gdma_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index a00bd88443d3..bc00a7d07232 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -1403,6 +1403,12 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + if (err) + goto release_region; + ++ err = dma_set_max_seg_size(&pdev->dev, UINT_MAX); ++ if (err) { ++ dev_err(&pdev->dev, "Failed to set dma device segment size\n"); ++ goto release_region; ++ } ++ + err = -ENOMEM; + gc = vzalloc(sizeof(*gc)); + if (!gc) +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0007-net-mana-Export-Work-Queue-functions-for-use-by-RDMA.patch b/debian/patches/features/all/ethernet-microsoft/0007-net-mana-Export-Work-Queue-functions-for-use-by-RDMA.patch new file mode 100644 index 000000000..c846badc8 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0007-net-mana-Export-Work-Queue-functions-for-use-by-RDMA.patch @@ -0,0 +1,100 @@ +From 8334d5a28eb711b8f464e0bd3ec0f76b0594bf95 Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:23 -0700 +Subject: [PATCH 07/23] net: mana: Export Work Queue functions for use by RDMA + driver + +RDMA device may need to create Ethernet device queues for use by Queue +Pair type RAW. This allows a user-mode context accesses Ethernet hardware +queues. Export the supporting functions for use by the RDMA driver. + +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-6-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit 4c0ff7a106e16ab63e0b597557255c012f179578) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/gdma_main.c | 1 + + drivers/net/ethernet/microsoft/mana/mana.h | 9 +++++++++ + drivers/net/ethernet/microsoft/mana/mana_en.c | 16 +++++++++------- + 3 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index bc00a7d07232..d9be0f3044ea 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -152,6 +152,7 @@ int mana_gd_send_request(struct gdma_context *gc, u32 req_len, const void *req, + + return mana_hwc_send_request(hwc, req_len, req, resp_len, resp); + } ++EXPORT_SYMBOL_NS(mana_gd_send_request, NET_MANA); + + int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length, + struct gdma_mem_info *gmi) +diff --git a/drivers/net/ethernet/microsoft/mana/mana.h b/drivers/net/ethernet/microsoft/mana/mana.h +index 2883a08dbfb5..6e9e86fb4c02 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana.h ++++ b/drivers/net/ethernet/microsoft/mana/mana.h +@@ -635,6 +635,15 @@ struct mana_tx_package { + struct gdma_posted_wqe_info wqe_info; + }; + ++int mana_create_wq_obj(struct mana_port_context *apc, ++ mana_handle_t vport, ++ u32 wq_type, struct mana_obj_spec *wq_spec, ++ struct mana_obj_spec *cq_spec, ++ mana_handle_t *wq_obj); ++ ++void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type, ++ mana_handle_t wq_obj); ++ + int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id, + u32 doorbell_pg_id); + void mana_uncfg_vport(struct mana_port_context *apc); +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index c5ab5cb63cb7..a526657f4edb 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -792,11 +792,11 @@ static int mana_cfg_vport_steering(struct mana_port_context *apc, + return err; + } + +-static int mana_create_wq_obj(struct mana_port_context *apc, +- mana_handle_t vport, +- u32 wq_type, struct mana_obj_spec *wq_spec, +- struct mana_obj_spec *cq_spec, +- mana_handle_t *wq_obj) ++int mana_create_wq_obj(struct mana_port_context *apc, ++ mana_handle_t vport, ++ u32 wq_type, struct mana_obj_spec *wq_spec, ++ struct mana_obj_spec *cq_spec, ++ mana_handle_t *wq_obj) + { + struct mana_create_wqobj_resp resp = {}; + struct mana_create_wqobj_req req = {}; +@@ -845,9 +845,10 @@ static int mana_create_wq_obj(struct mana_port_context *apc, + out: + return err; + } ++EXPORT_SYMBOL_NS(mana_create_wq_obj, NET_MANA); + +-static void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type, +- mana_handle_t wq_obj) ++void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type, ++ mana_handle_t wq_obj) + { + struct mana_destroy_wqobj_resp resp = {}; + struct mana_destroy_wqobj_req req = {}; +@@ -872,6 +873,7 @@ static void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type, + netdev_err(ndev, "Failed to destroy WQ object: %d, 0x%x\n", err, + resp.hdr.status); + } ++EXPORT_SYMBOL_NS(mana_destroy_wq_obj, NET_MANA); + + static void mana_destroy_eq(struct mana_context *ac) + { +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0008-net-mana-Record-port-number-in-netdev.patch b/debian/patches/features/all/ethernet-microsoft/0008-net-mana-Record-port-number-in-netdev.patch new file mode 100644 index 000000000..11a680a25 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0008-net-mana-Record-port-number-in-netdev.patch @@ -0,0 +1,34 @@ +From 026293abc2d3962ebd7d9a4bc9375fa1bddc2995 Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:24 -0700 +Subject: [PATCH 08/23] net: mana: Record port number in netdev + +The port number is useful for user-mode application to identify this +net device based on port index. Set to the correct value in ndev. + +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-7-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit d44089e555ffe63a49cc6e94d0c03d933e413059) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index a526657f4edb..5b7aae9bf983 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -2139,6 +2139,7 @@ static int mana_probe_port(struct mana_context *ac, int port_idx, + ndev->max_mtu = ndev->mtu; + ndev->min_mtu = ndev->mtu; + ndev->needed_headroom = MANA_HEADROOM; ++ ndev->dev_port = port_idx; + SET_NETDEV_DEV(ndev, gc->dev); + + netif_carrier_off(ndev); +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0009-net-mana-Move-header-files-to-a-common-location.patch b/debian/patches/features/all/ethernet-microsoft/0009-net-mana-Move-header-files-to-a-common-location.patch new file mode 100644 index 000000000..e83e38049 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0009-net-mana-Move-header-files-to-a-common-location.patch @@ -0,0 +1,152 @@ +From 36187c02914640d8c2e2ef9f11213842b5082671 Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:25 -0700 +Subject: [PATCH 09/23] net: mana: Move header files to a common location + +In preparation to add MANA RDMA driver, move all the required header files +to a common location for use by both Ethernet and RDMA drivers. + +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-8-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit fd325cd648f15eb9a8b32a68de3bafc72bcfe753) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + MAINTAINERS | 1 + + drivers/net/ethernet/microsoft/mana/gdma_main.c | 2 +- + drivers/net/ethernet/microsoft/mana/hw_channel.c | 4 ++-- + drivers/net/ethernet/microsoft/mana/mana_bpf.c | 2 +- + drivers/net/ethernet/microsoft/mana/mana_en.c | 4 ++-- + drivers/net/ethernet/microsoft/mana/mana_ethtool.c | 2 +- + drivers/net/ethernet/microsoft/mana/shm_channel.c | 2 +- + {drivers/net/ethernet/microsoft => include/net}/mana/gdma.h | 0 + .../net/ethernet/microsoft => include/net}/mana/hw_channel.h | 0 + {drivers/net/ethernet/microsoft => include/net}/mana/mana.h | 0 + .../ethernet/microsoft => include/net}/mana/mana_auxiliary.h | 0 + .../net/ethernet/microsoft => include/net}/mana/shm_channel.h | 0 + 12 files changed, 9 insertions(+), 8 deletions(-) + rename {drivers/net/ethernet/microsoft => include/net}/mana/gdma.h (100%) + rename {drivers/net/ethernet/microsoft => include/net}/mana/hw_channel.h (100%) + rename {drivers/net/ethernet/microsoft => include/net}/mana/mana.h (100%) + rename {drivers/net/ethernet/microsoft => include/net}/mana/mana_auxiliary.h (100%) + rename {drivers/net/ethernet/microsoft => include/net}/mana/shm_channel.h (100%) + +diff --git a/MAINTAINERS b/MAINTAINERS +index 379387e20a96..a923933bbe82 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -9536,6 +9536,7 @@ F: include/asm-generic/hyperv-tlfs.h + F: include/asm-generic/mshyperv.h + F: include/clocksource/hyperv_timer.h + F: include/linux/hyperv.h ++F: include/net/mana + F: include/uapi/linux/hyperv.h + F: net/vmw_vsock/hyperv_transport.c + F: tools/hv/ +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index d9be0f3044ea..b114c31d70ba 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -6,7 +6,7 @@ + #include <linux/utsname.h> + #include <linux/version.h> + +-#include "mana.h" ++#include <net/mana/mana.h> + + static u32 mana_gd_r32(struct gdma_context *g, u64 offset) + { +diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c +index 543a5d5c304f..76829ab43d40 100644 +--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c ++++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c +@@ -1,8 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + /* Copyright (c) 2021, Microsoft Corporation. */ + +-#include "gdma.h" +-#include "hw_channel.h" ++#include <net/mana/gdma.h> ++#include <net/mana/hw_channel.h> + + static int mana_hwc_get_msg_index(struct hw_channel_context *hwc, u16 *msg_id) + { +diff --git a/drivers/net/ethernet/microsoft/mana/mana_bpf.c b/drivers/net/ethernet/microsoft/mana/mana_bpf.c +index 421fd39ff3a8..3caea631229c 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_bpf.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_bpf.c +@@ -8,7 +8,7 @@ + #include <linux/bpf_trace.h> + #include <net/xdp.h> + +-#include "mana.h" ++#include <net/mana/mana.h> + + void mana_xdp_tx(struct sk_buff *skb, struct net_device *ndev) + { +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 5b7aae9bf983..c0421c4a80d4 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -12,8 +12,8 @@ + #include <net/checksum.h> + #include <net/ip6_checksum.h> + +-#include "mana.h" +-#include "mana_auxiliary.h" ++#include <net/mana/mana.h> ++#include <net/mana/mana_auxiliary.h> + + static DEFINE_IDA(mana_adev_ida); + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +index 96d55c91c969..5b776a33a817 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +@@ -5,7 +5,7 @@ + #include <linux/etherdevice.h> + #include <linux/ethtool.h> + +-#include "mana.h" ++#include <net/mana/mana.h> + + static const struct { + char name[ETH_GSTRING_LEN]; +diff --git a/drivers/net/ethernet/microsoft/mana/shm_channel.c b/drivers/net/ethernet/microsoft/mana/shm_channel.c +index da255da62176..5553af9c8085 100644 +--- a/drivers/net/ethernet/microsoft/mana/shm_channel.c ++++ b/drivers/net/ethernet/microsoft/mana/shm_channel.c +@@ -6,7 +6,7 @@ + #include <linux/io.h> + #include <linux/mm.h> + +-#include "shm_channel.h" ++#include <net/mana/shm_channel.h> + + #define PAGE_FRAME_L48_WIDTH_BYTES 6 + #define PAGE_FRAME_L48_WIDTH_BITS (PAGE_FRAME_L48_WIDTH_BYTES * 8) +diff --git a/drivers/net/ethernet/microsoft/mana/gdma.h b/include/net/mana/gdma.h +similarity index 100% +rename from drivers/net/ethernet/microsoft/mana/gdma.h +rename to include/net/mana/gdma.h +diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.h b/include/net/mana/hw_channel.h +similarity index 100% +rename from drivers/net/ethernet/microsoft/mana/hw_channel.h +rename to include/net/mana/hw_channel.h +diff --git a/drivers/net/ethernet/microsoft/mana/mana.h b/include/net/mana/mana.h +similarity index 100% +rename from drivers/net/ethernet/microsoft/mana/mana.h +rename to include/net/mana/mana.h +diff --git a/drivers/net/ethernet/microsoft/mana/mana_auxiliary.h b/include/net/mana/mana_auxiliary.h +similarity index 100% +rename from drivers/net/ethernet/microsoft/mana/mana_auxiliary.h +rename to include/net/mana/mana_auxiliary.h +diff --git a/drivers/net/ethernet/microsoft/mana/shm_channel.h b/include/net/mana/shm_channel.h +similarity index 100% +rename from drivers/net/ethernet/microsoft/mana/shm_channel.h +rename to include/net/mana/shm_channel.h +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0010-net-mana-Define-max-values-for-SGL-entries.patch b/debian/patches/features/all/ethernet-microsoft/0010-net-mana-Define-max-values-for-SGL-entries.patch new file mode 100644 index 000000000..25af5ac09 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0010-net-mana-Define-max-values-for-SGL-entries.patch @@ -0,0 +1,79 @@ +From 5e6b27eabf53e70c084cf61e3d3860cd6ed1c321 Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:26 -0700 +Subject: [PATCH 10/23] net: mana: Define max values for SGL entries + +The number of maximum SGl entries should be computed from the maximum +WQE size for the intended queue type and the corresponding OOB data +size. This guarantees the hardware queue can successfully queue requests +up to the queue depth exposed to the upper layer. + +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-9-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit aa56549792fb348892fbbae67f6f0c71bb750b65) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 2 +- + include/net/mana/gdma.h | 7 +++++++ + include/net/mana/mana.h | 4 +--- + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index c0421c4a80d4..958e55c936b5 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -189,7 +189,7 @@ int mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) + pkg.wqe_req.client_data_unit = 0; + + pkg.wqe_req.num_sge = 1 + skb_shinfo(skb)->nr_frags; +- WARN_ON_ONCE(pkg.wqe_req.num_sge > 30); ++ WARN_ON_ONCE(pkg.wqe_req.num_sge > MAX_TX_WQE_SGL_ENTRIES); + + if (pkg.wqe_req.num_sge <= ARRAY_SIZE(pkg.sgl_array)) { + pkg.wqe_req.sgl = pkg.sgl_array; +diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h +index 86d8a9e36005..11fc1cc67c01 100644 +--- a/include/net/mana/gdma.h ++++ b/include/net/mana/gdma.h +@@ -431,6 +431,13 @@ struct gdma_wqe { + #define MAX_TX_WQE_SIZE 512 + #define MAX_RX_WQE_SIZE 256 + ++#define MAX_TX_WQE_SGL_ENTRIES ((GDMA_MAX_SQE_SIZE - \ ++ sizeof(struct gdma_sge) - INLINE_OOB_SMALL_SIZE) / \ ++ sizeof(struct gdma_sge)) ++ ++#define MAX_RX_WQE_SGL_ENTRIES ((GDMA_MAX_RQE_SIZE - \ ++ sizeof(struct gdma_sge)) / sizeof(struct gdma_sge)) ++ + struct gdma_cqe { + u32 cqe_data[GDMA_COMP_DATA_SIZE / 4]; + +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index 6e9e86fb4c02..713a8f8cca9a 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -265,8 +265,6 @@ struct mana_cq { + int budget; + }; + +-#define GDMA_MAX_RQE_SGES 15 +- + struct mana_recv_buf_oob { + /* A valid GDMA work request representing the data buffer. */ + struct gdma_wqe_request wqe_req; +@@ -276,7 +274,7 @@ struct mana_recv_buf_oob { + + /* SGL of the buffer going to be sent has part of the work request. */ + u32 num_sge; +- struct gdma_sge sgl[GDMA_MAX_RQE_SGES]; ++ struct gdma_sge sgl[MAX_RX_WQE_SGL_ENTRIES]; + + /* Required to store the result of mana_gd_post_work_request. + * gdma_posted_wqe_info.wqe_size_in_bu is required for progressing the +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0011-net-mana-Define-and-process-GDMA-response-code-GDMA_.patch b/debian/patches/features/all/ethernet-microsoft/0011-net-mana-Define-and-process-GDMA-response-code-GDMA_.patch new file mode 100644 index 000000000..539f450c0 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0011-net-mana-Define-and-process-GDMA-response-code-GDMA_.patch @@ -0,0 +1,52 @@ +From 71b611192d6e5c0aa276eba89c4ac0b15ca1851b Mon Sep 17 00:00:00 2001 +From: Ajay Sharma <sharmaajay@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:27 -0700 +Subject: [PATCH 11/23] net: mana: Define and process GDMA response code + GDMA_STATUS_MORE_ENTRIES + +When doing memory registration, the PF may respond with +GDMA_STATUS_MORE_ENTRIES to indicate a follow request is needed. This is +not an error and should be processed as expected. + +Signed-off-by: Ajay Sharma <sharmaajay@microsoft.com> +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-10-git-send-email-longli@linuxonhyperv.com +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit de372f2a9ca7ada2698ecac7df8f02407cd98fa0) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/hw_channel.c | 2 +- + include/net/mana/gdma.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c +index 76829ab43d40..9d1507eba5b9 100644 +--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c ++++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c +@@ -836,7 +836,7 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len, + goto out; + } + +- if (ctx->status_code) { ++ if (ctx->status_code && ctx->status_code != GDMA_STATUS_MORE_ENTRIES) { + dev_err(hwc->dev, "HWC: Failed hw_channel req: 0x%x\n", + ctx->status_code); + err = -EPROTO; +diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h +index 11fc1cc67c01..202ac405ab59 100644 +--- a/include/net/mana/gdma.h ++++ b/include/net/mana/gdma.h +@@ -9,6 +9,8 @@ + + #include "shm_channel.h" + ++#define GDMA_STATUS_MORE_ENTRIES 0x00000105 ++ + /* Structures labeled with "HW DATA" are exchanged with the hardware. All of + * them are naturally aligned and hence don't need __packed. + */ +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0012-net-mana-Define-data-structures-for-protection-domai.patch b/debian/patches/features/all/ethernet-microsoft/0012-net-mana-Define-data-structures-for-protection-domai.patch new file mode 100644 index 000000000..fb9a2a84d --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0012-net-mana-Define-data-structures-for-protection-domai.patch @@ -0,0 +1,353 @@ +From b6589e00fed6f5a53bd4ffd172b7e4d2d300447c Mon Sep 17 00:00:00 2001 +From: Ajay Sharma <sharmaajay@microsoft.com> +Date: Thu, 3 Nov 2022 12:16:29 -0700 +Subject: [PATCH 12/23] net: mana: Define data structures for protection domain + and memory registration + +The MANA hardware support protection domain and memory registration for use +in RDMA environment. Add those definitions and expose them for use by the +RDMA driver. + +Signed-off-by: Ajay Sharma <sharmaajay@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1667502990-2559-12-git-send-email-longli@linuxonhyperv.com +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Acked-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Leon Romanovsky <leonro@nvidia.com> +(cherry picked from commit 28c66cfa45388af1126985d1114e0ed762eb2abd) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + .../net/ethernet/microsoft/mana/gdma_main.c | 27 ++-- + drivers/net/ethernet/microsoft/mana/mana_en.c | 18 +-- + include/net/mana/gdma.h | 121 +++++++++++++++++- + 3 files changed, 143 insertions(+), 23 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index b114c31d70ba..690691e3e86c 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -198,7 +198,7 @@ static int mana_gd_create_hw_eq(struct gdma_context *gc, + req.type = queue->type; + req.pdid = queue->gdma_dev->pdid; + req.doolbell_id = queue->gdma_dev->doorbell; +- req.gdma_region = queue->mem_info.gdma_region; ++ req.gdma_region = queue->mem_info.dma_region_handle; + req.queue_size = queue->queue_size; + req.log2_throttle_limit = queue->eq.log2_throttle_limit; + req.eq_pci_msix_index = queue->eq.msix_index; +@@ -212,7 +212,7 @@ static int mana_gd_create_hw_eq(struct gdma_context *gc, + + queue->id = resp.queue_index; + queue->eq.disable_needed = true; +- queue->mem_info.gdma_region = GDMA_INVALID_DMA_REGION; ++ queue->mem_info.dma_region_handle = GDMA_INVALID_DMA_REGION; + return 0; + } + +@@ -671,24 +671,30 @@ int mana_gd_create_hwc_queue(struct gdma_dev *gd, + return err; + } + +-static void mana_gd_destroy_dma_region(struct gdma_context *gc, u64 gdma_region) ++int mana_gd_destroy_dma_region(struct gdma_context *gc, ++ gdma_obj_handle_t dma_region_handle) + { + struct gdma_destroy_dma_region_req req = {}; + struct gdma_general_resp resp = {}; + int err; + +- if (gdma_region == GDMA_INVALID_DMA_REGION) +- return; ++ if (dma_region_handle == GDMA_INVALID_DMA_REGION) ++ return 0; + + mana_gd_init_req_hdr(&req.hdr, GDMA_DESTROY_DMA_REGION, sizeof(req), + sizeof(resp)); +- req.gdma_region = gdma_region; ++ req.dma_region_handle = dma_region_handle; + + err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); +- if (err || resp.hdr.status) ++ if (err || resp.hdr.status) { + dev_err(gc->dev, "Failed to destroy DMA region: %d, 0x%x\n", + err, resp.hdr.status); ++ return -EPROTO; ++ } ++ ++ return 0; + } ++EXPORT_SYMBOL_NS(mana_gd_destroy_dma_region, NET_MANA); + + static int mana_gd_create_dma_region(struct gdma_dev *gd, + struct gdma_mem_info *gmi) +@@ -733,14 +739,15 @@ static int mana_gd_create_dma_region(struct gdma_dev *gd, + if (err) + goto out; + +- if (resp.hdr.status || resp.gdma_region == GDMA_INVALID_DMA_REGION) { ++ if (resp.hdr.status || ++ resp.dma_region_handle == GDMA_INVALID_DMA_REGION) { + dev_err(gc->dev, "Failed to create DMA region: 0x%x\n", + resp.hdr.status); + err = -EPROTO; + goto out; + } + +- gmi->gdma_region = resp.gdma_region; ++ gmi->dma_region_handle = resp.dma_region_handle; + out: + kfree(req); + return err; +@@ -863,7 +870,7 @@ void mana_gd_destroy_queue(struct gdma_context *gc, struct gdma_queue *queue) + return; + } + +- mana_gd_destroy_dma_region(gc, gmi->gdma_region); ++ mana_gd_destroy_dma_region(gc, gmi->dma_region_handle); + mana_gd_free_memory(gmi); + kfree(queue); + } +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 958e55c936b5..9bce13714b25 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1529,10 +1529,10 @@ static int mana_create_txq(struct mana_port_context *apc, + memset(&wq_spec, 0, sizeof(wq_spec)); + memset(&cq_spec, 0, sizeof(cq_spec)); + +- wq_spec.gdma_region = txq->gdma_sq->mem_info.gdma_region; ++ wq_spec.gdma_region = txq->gdma_sq->mem_info.dma_region_handle; + wq_spec.queue_size = txq->gdma_sq->queue_size; + +- cq_spec.gdma_region = cq->gdma_cq->mem_info.gdma_region; ++ cq_spec.gdma_region = cq->gdma_cq->mem_info.dma_region_handle; + cq_spec.queue_size = cq->gdma_cq->queue_size; + cq_spec.modr_ctx_id = 0; + cq_spec.attached_eq = cq->gdma_cq->cq.parent->id; +@@ -1547,8 +1547,10 @@ static int mana_create_txq(struct mana_port_context *apc, + txq->gdma_sq->id = wq_spec.queue_index; + cq->gdma_cq->id = cq_spec.queue_index; + +- txq->gdma_sq->mem_info.gdma_region = GDMA_INVALID_DMA_REGION; +- cq->gdma_cq->mem_info.gdma_region = GDMA_INVALID_DMA_REGION; ++ txq->gdma_sq->mem_info.dma_region_handle = ++ GDMA_INVALID_DMA_REGION; ++ cq->gdma_cq->mem_info.dma_region_handle = ++ GDMA_INVALID_DMA_REGION; + + txq->gdma_txq_id = txq->gdma_sq->id; + +@@ -1759,10 +1761,10 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc, + + memset(&wq_spec, 0, sizeof(wq_spec)); + memset(&cq_spec, 0, sizeof(cq_spec)); +- wq_spec.gdma_region = rxq->gdma_rq->mem_info.gdma_region; ++ wq_spec.gdma_region = rxq->gdma_rq->mem_info.dma_region_handle; + wq_spec.queue_size = rxq->gdma_rq->queue_size; + +- cq_spec.gdma_region = cq->gdma_cq->mem_info.gdma_region; ++ cq_spec.gdma_region = cq->gdma_cq->mem_info.dma_region_handle; + cq_spec.queue_size = cq->gdma_cq->queue_size; + cq_spec.modr_ctx_id = 0; + cq_spec.attached_eq = cq->gdma_cq->cq.parent->id; +@@ -1775,8 +1777,8 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc, + rxq->gdma_rq->id = wq_spec.queue_index; + cq->gdma_cq->id = cq_spec.queue_index; + +- rxq->gdma_rq->mem_info.gdma_region = GDMA_INVALID_DMA_REGION; +- cq->gdma_cq->mem_info.gdma_region = GDMA_INVALID_DMA_REGION; ++ rxq->gdma_rq->mem_info.dma_region_handle = GDMA_INVALID_DMA_REGION; ++ cq->gdma_cq->mem_info.dma_region_handle = GDMA_INVALID_DMA_REGION; + + rxq->gdma_id = rxq->gdma_rq->id; + cq->gdma_id = cq->gdma_cq->id; +diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h +index 202ac405ab59..aabc7cea8a49 100644 +--- a/include/net/mana/gdma.h ++++ b/include/net/mana/gdma.h +@@ -27,6 +27,10 @@ enum gdma_request_type { + GDMA_CREATE_DMA_REGION = 25, + GDMA_DMA_REGION_ADD_PAGES = 26, + GDMA_DESTROY_DMA_REGION = 27, ++ GDMA_CREATE_PD = 29, ++ GDMA_DESTROY_PD = 30, ++ GDMA_CREATE_MR = 31, ++ GDMA_DESTROY_MR = 32, + }; + + enum gdma_queue_type { +@@ -57,6 +61,8 @@ enum { + GDMA_DEVICE_MANA = 2, + }; + ++typedef u64 gdma_obj_handle_t; ++ + struct gdma_resource { + /* Protect the bitmap */ + spinlock_t lock; +@@ -190,7 +196,7 @@ struct gdma_mem_info { + u64 length; + + /* Allocated by the PF driver */ +- u64 gdma_region; ++ gdma_obj_handle_t dma_region_handle; + }; + + #define REGISTER_ATB_MST_MKEY_LOWER_SIZE 8 +@@ -605,7 +611,7 @@ struct gdma_create_queue_req { + u32 reserved1; + u32 pdid; + u32 doolbell_id; +- u64 gdma_region; ++ gdma_obj_handle_t gdma_region; + u32 reserved2; + u32 queue_size; + u32 log2_throttle_limit; +@@ -632,6 +638,28 @@ struct gdma_disable_queue_req { + u32 alloc_res_id_on_creation; + }; /* HW DATA */ + ++enum atb_page_size { ++ ATB_PAGE_SIZE_4K, ++ ATB_PAGE_SIZE_8K, ++ ATB_PAGE_SIZE_16K, ++ ATB_PAGE_SIZE_32K, ++ ATB_PAGE_SIZE_64K, ++ ATB_PAGE_SIZE_128K, ++ ATB_PAGE_SIZE_256K, ++ ATB_PAGE_SIZE_512K, ++ ATB_PAGE_SIZE_1M, ++ ATB_PAGE_SIZE_2M, ++ ATB_PAGE_SIZE_MAX, ++}; ++ ++enum gdma_mr_access_flags { ++ GDMA_ACCESS_FLAG_LOCAL_READ = BIT_ULL(0), ++ GDMA_ACCESS_FLAG_LOCAL_WRITE = BIT_ULL(1), ++ GDMA_ACCESS_FLAG_REMOTE_READ = BIT_ULL(2), ++ GDMA_ACCESS_FLAG_REMOTE_WRITE = BIT_ULL(3), ++ GDMA_ACCESS_FLAG_REMOTE_ATOMIC = BIT_ULL(4), ++}; ++ + /* GDMA_CREATE_DMA_REGION */ + struct gdma_create_dma_region_req { + struct gdma_req_hdr hdr; +@@ -658,14 +686,14 @@ struct gdma_create_dma_region_req { + + struct gdma_create_dma_region_resp { + struct gdma_resp_hdr hdr; +- u64 gdma_region; ++ gdma_obj_handle_t dma_region_handle; + }; /* HW DATA */ + + /* GDMA_DMA_REGION_ADD_PAGES */ + struct gdma_dma_region_add_pages_req { + struct gdma_req_hdr hdr; + +- u64 gdma_region; ++ gdma_obj_handle_t dma_region_handle; + + u32 page_addr_list_len; + u32 reserved3; +@@ -677,9 +705,88 @@ struct gdma_dma_region_add_pages_req { + struct gdma_destroy_dma_region_req { + struct gdma_req_hdr hdr; + +- u64 gdma_region; ++ gdma_obj_handle_t dma_region_handle; + }; /* HW DATA */ + ++enum gdma_pd_flags { ++ GDMA_PD_FLAG_INVALID = 0, ++}; ++ ++struct gdma_create_pd_req { ++ struct gdma_req_hdr hdr; ++ enum gdma_pd_flags flags; ++ u32 reserved; ++};/* HW DATA */ ++ ++struct gdma_create_pd_resp { ++ struct gdma_resp_hdr hdr; ++ gdma_obj_handle_t pd_handle; ++ u32 pd_id; ++ u32 reserved; ++};/* HW DATA */ ++ ++struct gdma_destroy_pd_req { ++ struct gdma_req_hdr hdr; ++ gdma_obj_handle_t pd_handle; ++};/* HW DATA */ ++ ++struct gdma_destory_pd_resp { ++ struct gdma_resp_hdr hdr; ++};/* HW DATA */ ++ ++enum gdma_mr_type { ++ /* Guest Virtual Address - MRs of this type allow access ++ * to memory mapped by PTEs associated with this MR using a virtual ++ * address that is set up in the MST ++ */ ++ GDMA_MR_TYPE_GVA = 2, ++}; ++ ++struct gdma_create_mr_params { ++ gdma_obj_handle_t pd_handle; ++ enum gdma_mr_type mr_type; ++ union { ++ struct { ++ gdma_obj_handle_t dma_region_handle; ++ u64 virtual_address; ++ enum gdma_mr_access_flags access_flags; ++ } gva; ++ }; ++}; ++ ++struct gdma_create_mr_request { ++ struct gdma_req_hdr hdr; ++ gdma_obj_handle_t pd_handle; ++ enum gdma_mr_type mr_type; ++ u32 reserved_1; ++ ++ union { ++ struct { ++ gdma_obj_handle_t dma_region_handle; ++ u64 virtual_address; ++ enum gdma_mr_access_flags access_flags; ++ } gva; ++ ++ }; ++ u32 reserved_2; ++};/* HW DATA */ ++ ++struct gdma_create_mr_response { ++ struct gdma_resp_hdr hdr; ++ gdma_obj_handle_t mr_handle; ++ u32 lkey; ++ u32 rkey; ++};/* HW DATA */ ++ ++struct gdma_destroy_mr_request { ++ struct gdma_req_hdr hdr; ++ gdma_obj_handle_t mr_handle; ++};/* HW DATA */ ++ ++struct gdma_destroy_mr_response { ++ struct gdma_resp_hdr hdr; ++};/* HW DATA */ ++ + int mana_gd_verify_vf_version(struct pci_dev *pdev); + + int mana_gd_register_device(struct gdma_dev *gd); +@@ -706,4 +813,8 @@ void mana_gd_free_memory(struct gdma_mem_info *gmi); + + int mana_gd_send_request(struct gdma_context *gc, u32 req_len, const void *req, + u32 resp_len, void *resp); ++ ++int mana_gd_destroy_dma_region(struct gdma_context *gc, ++ gdma_obj_handle_t dma_region_handle); ++ + #endif /* _GDMA_H */ +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0013-net-mana-Fix-return-type-of-mana_start_xmit.patch b/debian/patches/features/all/ethernet-microsoft/0013-net-mana-Fix-return-type-of-mana_start_xmit.patch new file mode 100644 index 000000000..8f966405a --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0013-net-mana-Fix-return-type-of-mana_start_xmit.patch @@ -0,0 +1,66 @@ +From 37ec026c96afe1091f91d40515a91463ea50c150 Mon Sep 17 00:00:00 2001 +From: Nathan Huckleberry <nhuck@google.com> +Date: Tue, 8 Nov 2022 17:26:30 -0700 +Subject: [PATCH 13/23] net: mana: Fix return type of mana_start_xmit() + +The ndo_start_xmit field in net_device_ops is expected to be of type +netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev). + +The mismatched return type breaks forward edge kCFI since the underlying +function definition does not match the function hook definition. A new +warning in clang will catch this at compile time: + + drivers/net/ethernet/microsoft/mana/mana_en.c:382:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .ndo_start_xmit = mana_start_xmit, + ^~~~~~~~~~~~~~~ + 1 error generated. + +The return type of mana_start_xmit should be changed from int to +netdev_tx_t. + +Reported-by: Dan Carpenter <error27@gmail.com> +Link: https://github.com/ClangBuiltLinux/linux/issues/1703 +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Signed-off-by: Nathan Huckleberry <nhuck@google.com> +Reviewed-by: Dexuan Cui <decui@microsoft.com> +[nathan: Rebase on net-next and resolve conflicts + Add note about new clang warning] +Signed-off-by: Nathan Chancellor <nathan@kernel.org> +Link: https://lore.kernel.org/r/20221109002629.1446680-1-nathan@kernel.org +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +(cherry picked from commit 0c9ef08a4d0fd6c5e6000597b506235d71a85a61) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 2 +- + include/net/mana/mana.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 9bce13714b25..2f6a048dee90 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -141,7 +141,7 @@ static int mana_map_skb(struct sk_buff *skb, struct mana_port_context *apc, + return -ENOMEM; + } + +-int mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) ++netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) + { + enum mana_tx_pkt_format pkt_fmt = MANA_SHORT_PKT_FMT; + struct mana_port_context *apc = netdev_priv(ndev); +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index 713a8f8cca9a..575ea36ce606 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -390,7 +390,7 @@ struct mana_port_context { + struct mana_ethtool_stats eth_stats; + }; + +-int mana_start_xmit(struct sk_buff *skb, struct net_device *ndev); ++netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev); + int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx, + bool update_hash, bool update_tab); + +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0014-net-mana-Fix-accessing-freed-irq-affinity_hint.patch b/debian/patches/features/all/ethernet-microsoft/0014-net-mana-Fix-accessing-freed-irq-affinity_hint.patch new file mode 100644 index 000000000..2aa627612 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0014-net-mana-Fix-accessing-freed-irq-affinity_hint.patch @@ -0,0 +1,135 @@ +From 1b71f96ff9b962c904cefc9a57500869fa0d1d44 Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Mon, 6 Feb 2023 13:28:49 -0800 +Subject: [PATCH 14/23] net: mana: Fix accessing freed irq affinity_hint + +After calling irq_set_affinity_and_hint(), the cpumask pointer is +saved in desc->affinity_hint, and will be used later when reading +/proc/irq/<num>/affinity_hint. So the cpumask variable needs to be +persistent. Otherwise, we are accessing freed memory when reading +the affinity_hint file. + +Also, need to clear affinity_hint before free_irq(), otherwise there +is a one-time warning and stack trace during module unloading: + + [ 243.948687] WARNING: CPU: 10 PID: 1589 at kernel/irq/manage.c:1913 free_irq+0x318/0x360 + ... + [ 243.948753] Call Trace: + [ 243.948754] <TASK> + [ 243.948760] mana_gd_remove_irqs+0x78/0xc0 [mana] + [ 243.948767] mana_gd_remove+0x3e/0x80 [mana] + [ 243.948773] pci_device_remove+0x3d/0xb0 + [ 243.948778] device_remove+0x46/0x70 + [ 243.948782] device_release_driver_internal+0x1fe/0x280 + [ 243.948785] driver_detach+0x4e/0xa0 + [ 243.948787] bus_remove_driver+0x70/0xf0 + [ 243.948789] driver_unregister+0x35/0x60 + [ 243.948792] pci_unregister_driver+0x44/0x90 + [ 243.948794] mana_driver_exit+0x14/0x3fe [mana] + [ 243.948800] __do_sys_delete_module.constprop.0+0x185/0x2f0 + +To fix the bug, use the persistent mask, cpumask_of(cpu#), and set +affinity_hint to NULL before freeing the IRQ, as required by free_irq(). + +Cc: stable@vger.kernel.org +Fixes: 71fa6887eeca ("net: mana: Assign interrupts to CPUs based on NUMA nodes") +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Michael Kelley <mikelley@microsoft.com> +Reviewed-by: Leon Romanovsky <leonro@nvidia.com> +Link: https://lore.kernel.org/r/1675718929-19565-1-git-send-email-haiyangz@microsoft.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +(cherry picked from commit 18a048370b06a3a521219e9e5b10bdc2178ef19c) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + .../net/ethernet/microsoft/mana/gdma_main.c | 37 ++++++------------- + 1 file changed, 11 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index 690691e3e86c..5b7fddfc9ff1 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -1218,9 +1218,7 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev) + unsigned int max_queues_per_port = num_online_cpus(); + struct gdma_context *gc = pci_get_drvdata(pdev); + struct gdma_irq_context *gic; +- unsigned int max_irqs; +- u16 *cpus; +- cpumask_var_t req_mask; ++ unsigned int max_irqs, cpu; + int nvec, irq; + int err, i = 0, j; + +@@ -1241,21 +1239,7 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev) + goto free_irq_vector; + } + +- if (!zalloc_cpumask_var(&req_mask, GFP_KERNEL)) { +- err = -ENOMEM; +- goto free_irq; +- } +- +- cpus = kcalloc(nvec, sizeof(*cpus), GFP_KERNEL); +- if (!cpus) { +- err = -ENOMEM; +- goto free_mask; +- } +- for (i = 0; i < nvec; i++) +- cpus[i] = cpumask_local_spread(i, gc->numa_node); +- + for (i = 0; i < nvec; i++) { +- cpumask_set_cpu(cpus[i], req_mask); + gic = &gc->irq_contexts[i]; + gic->handler = NULL; + gic->arg = NULL; +@@ -1270,17 +1254,16 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev) + irq = pci_irq_vector(pdev, i); + if (irq < 0) { + err = irq; +- goto free_mask; ++ goto free_irq; + } + + err = request_irq(irq, mana_gd_intr, 0, gic->name, gic); + if (err) +- goto free_mask; +- irq_set_affinity_and_hint(irq, req_mask); +- cpumask_clear(req_mask); ++ goto free_irq; ++ ++ cpu = cpumask_local_spread(i, gc->numa_node); ++ irq_set_affinity_and_hint(irq, cpumask_of(cpu)); + } +- free_cpumask_var(req_mask); +- kfree(cpus); + + err = mana_gd_alloc_res_map(nvec, &gc->msix_resource); + if (err) +@@ -1291,13 +1274,12 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev) + + return 0; + +-free_mask: +- free_cpumask_var(req_mask); +- kfree(cpus); + free_irq: + for (j = i - 1; j >= 0; j--) { + irq = pci_irq_vector(pdev, j); + gic = &gc->irq_contexts[j]; ++ ++ irq_update_affinity_hint(irq, NULL); + free_irq(irq, gic); + } + +@@ -1325,6 +1307,9 @@ static void mana_gd_remove_irqs(struct pci_dev *pdev) + continue; + + gic = &gc->irq_contexts[i]; ++ ++ /* Need to clear the hint before free_irq */ ++ irq_update_affinity_hint(irq, NULL); + free_irq(irq, gic); + } + +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0015-net-mana-Add-new-MANA-VF-performance-counters-for-ea.patch b/debian/patches/features/all/ethernet-microsoft/0015-net-mana-Add-new-MANA-VF-performance-counters-for-ea.patch new file mode 100644 index 000000000..0ada4dca6 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0015-net-mana-Add-new-MANA-VF-performance-counters-for-ea.patch @@ -0,0 +1,334 @@ +From fbefc731a4cc001fe7ce5786e08053d707dde85f Mon Sep 17 00:00:00 2001 +From: Shradha Gupta <shradhagupta@linux.microsoft.com> +Date: Wed, 15 Mar 2023 04:55:13 -0700 +Subject: [PATCH 15/23] net: mana: Add new MANA VF performance counters for + easier troubleshooting + +Extended performance counter stats in 'ethtool -S <interface>' output +for MANA VF to facilitate troubleshooting. + +Tested-on: Ubuntu22 +Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit bd7fc6e1957c2102866f9e464c1f2302e891b7e9) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 62 ++++++++++++++++++- + .../ethernet/microsoft/mana/mana_ethtool.c | 52 +++++++++++++++- + include/net/mana/mana.h | 18 ++++++ + 3 files changed, 128 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -157,6 +157,7 @@ netdev_tx_t mana_start_xmit(struct sk_bu + struct mana_txq *txq; + struct mana_cq *cq; + int err, len; ++ u16 ihs; + + if (unlikely(!apc->port_is_up)) + goto tx_drop; +@@ -167,6 +168,7 @@ netdev_tx_t mana_start_xmit(struct sk_bu + txq = &apc->tx_qp[txq_idx].txq; + gdma_sq = txq->gdma_sq; + cq = &apc->tx_qp[txq_idx].tx_cq; ++ tx_stats = &txq->stats; + + pkg.tx_oob.s_oob.vcq_num = cq->gdma_id; + pkg.tx_oob.s_oob.vsq_frame = txq->vsq_frame; +@@ -180,10 +182,17 @@ netdev_tx_t mana_start_xmit(struct sk_bu + + pkg.tx_oob.s_oob.pkt_fmt = pkt_fmt; + +- if (pkt_fmt == MANA_SHORT_PKT_FMT) ++ if (pkt_fmt == MANA_SHORT_PKT_FMT) { + pkg.wqe_req.inline_oob_size = sizeof(struct mana_tx_short_oob); +- else ++ u64_stats_update_begin(&tx_stats->syncp); ++ tx_stats->short_pkt_fmt++; ++ u64_stats_update_end(&tx_stats->syncp); ++ } else { + pkg.wqe_req.inline_oob_size = sizeof(struct mana_tx_oob); ++ u64_stats_update_begin(&tx_stats->syncp); ++ tx_stats->long_pkt_fmt++; ++ u64_stats_update_end(&tx_stats->syncp); ++ } + + pkg.wqe_req.inline_oob_data = &pkg.tx_oob; + pkg.wqe_req.flags = 0; +@@ -233,9 +242,35 @@ netdev_tx_t mana_start_xmit(struct sk_bu + &ipv6_hdr(skb)->daddr, 0, + IPPROTO_TCP, 0); + } ++ ++ if (skb->encapsulation) { ++ ihs = skb_inner_tcp_all_headers(skb); ++ u64_stats_update_begin(&tx_stats->syncp); ++ tx_stats->tso_inner_packets++; ++ tx_stats->tso_inner_bytes += skb->len - ihs; ++ u64_stats_update_end(&tx_stats->syncp); ++ } else { ++ if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) { ++ ihs = skb_transport_offset(skb) + sizeof(struct udphdr); ++ } else { ++ ihs = skb_tcp_all_headers(skb); ++ if (ipv6_has_hopopt_jumbo(skb)) ++ ihs -= sizeof(struct hop_jumbo_hdr); ++ } ++ ++ u64_stats_update_begin(&tx_stats->syncp); ++ tx_stats->tso_packets++; ++ tx_stats->tso_bytes += skb->len - ihs; ++ u64_stats_update_end(&tx_stats->syncp); ++ } ++ + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + csum_type = mana_checksum_info(skb); + ++ u64_stats_update_begin(&tx_stats->syncp); ++ tx_stats->csum_partial++; ++ u64_stats_update_end(&tx_stats->syncp); ++ + if (csum_type == IPPROTO_TCP) { + pkg.tx_oob.s_oob.is_outer_ipv4 = ipv4; + pkg.tx_oob.s_oob.is_outer_ipv6 = ipv6; +@@ -255,8 +290,12 @@ netdev_tx_t mana_start_xmit(struct sk_bu + } + } + +- if (mana_map_skb(skb, apc, &pkg)) ++ if (mana_map_skb(skb, apc, &pkg)) { ++ u64_stats_update_begin(&tx_stats->syncp); ++ tx_stats->mana_map_err++; ++ u64_stats_update_end(&tx_stats->syncp); + goto free_sgl_ptr; ++ } + + skb_queue_tail(&txq->pending_skbs, skb); + +@@ -1039,6 +1078,8 @@ static void mana_poll_tx_cq(struct mana_ + if (comp_read < 1) + return; + ++ apc->eth_stats.tx_cqes = comp_read; ++ + for (i = 0; i < comp_read; i++) { + struct mana_tx_comp_oob *cqe_oob; + +@@ -1067,6 +1108,7 @@ static void mana_poll_tx_cq(struct mana_ + netdev_err(ndev, "TX: CQE error %d\n", + cqe_oob->cqe_hdr.cqe_type); + ++ apc->eth_stats.tx_cqe_err++; + break; + + default: +@@ -1077,6 +1119,7 @@ static void mana_poll_tx_cq(struct mana_ + netdev_err(ndev, "TX: unknown CQE type %d\n", + cqe_oob->cqe_hdr.cqe_type); + ++ apc->eth_stats.tx_cqe_unknown_type++; + break; + } + +@@ -1123,6 +1166,8 @@ static void mana_poll_tx_cq(struct mana_ + WARN_ON_ONCE(1); + + cq->work_done = pkt_transmitted; ++ ++ apc->eth_stats.tx_cqes -= pkt_transmitted; + } + + static void mana_post_pkt_rxq(struct mana_rxq *rxq) +@@ -1257,12 +1302,15 @@ static void mana_process_rx_cqe(struct m + struct gdma_context *gc = rxq->gdma_rq->gdma_dev->gdma_context; + struct net_device *ndev = rxq->ndev; + struct mana_recv_buf_oob *rxbuf_oob; ++ struct mana_port_context *apc; + struct device *dev = gc->dev; + void *new_buf, *old_buf; + struct page *new_page; + u32 curr, pktlen; + dma_addr_t da; + ++ apc = netdev_priv(ndev); ++ + switch (oob->cqe_hdr.cqe_type) { + case CQE_RX_OKAY: + break; +@@ -1275,6 +1323,7 @@ static void mana_process_rx_cqe(struct m + + case CQE_RX_COALESCED_4: + netdev_err(ndev, "RX coalescing is unsupported\n"); ++ apc->eth_stats.rx_coalesced_err++; + return; + + case CQE_RX_OBJECT_FENCE: +@@ -1284,6 +1333,7 @@ static void mana_process_rx_cqe(struct m + default: + netdev_err(ndev, "Unknown RX CQE type = %d\n", + oob->cqe_hdr.cqe_type); ++ apc->eth_stats.rx_cqe_unknown_type++; + return; + } + +@@ -1346,11 +1396,15 @@ static void mana_poll_rx_cq(struct mana_ + { + struct gdma_comp *comp = cq->gdma_comp_buf; + struct mana_rxq *rxq = cq->rxq; ++ struct mana_port_context *apc; + int comp_read, i; + ++ apc = netdev_priv(rxq->ndev); ++ + comp_read = mana_gd_poll_cq(cq->gdma_cq, comp, CQE_POLLING_BUFFER); + WARN_ON_ONCE(comp_read > CQE_POLLING_BUFFER); + ++ apc->eth_stats.rx_cqes = comp_read; + rxq->xdp_flush = false; + + for (i = 0; i < comp_read; i++) { +@@ -1362,6 +1416,8 @@ static void mana_poll_rx_cq(struct mana_ + return; + + mana_process_rx_cqe(rxq, cq, &comp[i]); ++ ++ apc->eth_stats.rx_cqes--; + } + + if (rxq->xdp_flush) +--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +@@ -13,6 +13,15 @@ static const struct { + } mana_eth_stats[] = { + {"stop_queue", offsetof(struct mana_ethtool_stats, stop_queue)}, + {"wake_queue", offsetof(struct mana_ethtool_stats, wake_queue)}, ++ {"tx_cqes", offsetof(struct mana_ethtool_stats, tx_cqes)}, ++ {"tx_cq_err", offsetof(struct mana_ethtool_stats, tx_cqe_err)}, ++ {"tx_cqe_unknown_type", offsetof(struct mana_ethtool_stats, ++ tx_cqe_unknown_type)}, ++ {"rx_cqes", offsetof(struct mana_ethtool_stats, rx_cqes)}, ++ {"rx_coalesced_err", offsetof(struct mana_ethtool_stats, ++ rx_coalesced_err)}, ++ {"rx_cqe_unknown_type", offsetof(struct mana_ethtool_stats, ++ rx_cqe_unknown_type)}, + }; + + static int mana_get_sset_count(struct net_device *ndev, int stringset) +@@ -23,7 +32,8 @@ static int mana_get_sset_count(struct ne + if (stringset != ETH_SS_STATS) + return -EINVAL; + +- return ARRAY_SIZE(mana_eth_stats) + num_queues * 8; ++ return ARRAY_SIZE(mana_eth_stats) + num_queues * ++ (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT); + } + + static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data) +@@ -61,6 +71,22 @@ static void mana_get_strings(struct net_ + p += ETH_GSTRING_LEN; + sprintf(p, "tx_%d_xdp_xmit", i); + p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_tso_packets", i); ++ p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_tso_bytes", i); ++ p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_tso_inner_packets", i); ++ p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_tso_inner_bytes", i); ++ p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_long_pkt_fmt", i); ++ p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_short_pkt_fmt", i); ++ p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_csum_partial", i); ++ p += ETH_GSTRING_LEN; ++ sprintf(p, "tx_%d_mana_map_err", i); ++ p += ETH_GSTRING_LEN; + } + } + +@@ -78,6 +104,14 @@ static void mana_get_ethtool_stats(struc + u64 xdp_xmit; + u64 xdp_drop; + u64 xdp_tx; ++ u64 tso_packets; ++ u64 tso_bytes; ++ u64 tso_inner_packets; ++ u64 tso_inner_bytes; ++ u64 long_pkt_fmt; ++ u64 short_pkt_fmt; ++ u64 csum_partial; ++ u64 mana_map_err; + int q, i = 0; + + if (!apc->port_is_up) +@@ -113,11 +147,27 @@ static void mana_get_ethtool_stats(struc + packets = tx_stats->packets; + bytes = tx_stats->bytes; + xdp_xmit = tx_stats->xdp_xmit; ++ tso_packets = tx_stats->tso_packets; ++ tso_bytes = tx_stats->tso_bytes; ++ tso_inner_packets = tx_stats->tso_inner_packets; ++ tso_inner_bytes = tx_stats->tso_inner_bytes; ++ long_pkt_fmt = tx_stats->long_pkt_fmt; ++ short_pkt_fmt = tx_stats->short_pkt_fmt; ++ csum_partial = tx_stats->csum_partial; ++ mana_map_err = tx_stats->mana_map_err; + } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + data[i++] = packets; + data[i++] = bytes; + data[i++] = xdp_xmit; ++ data[i++] = tso_packets; ++ data[i++] = tso_bytes; ++ data[i++] = tso_inner_packets; ++ data[i++] = tso_inner_bytes; ++ data[i++] = long_pkt_fmt; ++ data[i++] = short_pkt_fmt; ++ data[i++] = csum_partial; ++ data[i++] = mana_map_err; + } + } + +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -48,6 +48,10 @@ enum TRI_STATE { + + #define MAX_PORTS_IN_MANA_DEV 256 + ++/* Update this count whenever the respective structures are changed */ ++#define MANA_STATS_RX_COUNT 5 ++#define MANA_STATS_TX_COUNT 11 ++ + struct mana_stats_rx { + u64 packets; + u64 bytes; +@@ -61,6 +65,14 @@ struct mana_stats_tx { + u64 packets; + u64 bytes; + u64 xdp_xmit; ++ u64 tso_packets; ++ u64 tso_bytes; ++ u64 tso_inner_packets; ++ u64 tso_inner_bytes; ++ u64 short_pkt_fmt; ++ u64 long_pkt_fmt; ++ u64 csum_partial; ++ u64 mana_map_err; + struct u64_stats_sync syncp; + }; + +@@ -331,6 +343,12 @@ struct mana_tx_qp { + struct mana_ethtool_stats { + u64 stop_queue; + u64 wake_queue; ++ u64 tx_cqes; ++ u64 tx_cqe_err; ++ u64 tx_cqe_unknown_type; ++ u64 rx_cqes; ++ u64 rx_coalesced_err; ++ u64 rx_cqe_unknown_type; + }; + + struct mana_context { diff --git a/debian/patches/features/all/ethernet-microsoft/0016-net-mana-Remove-redundant-pci_clear_master.patch b/debian/patches/features/all/ethernet-microsoft/0016-net-mana-Remove-redundant-pci_clear_master.patch new file mode 100644 index 000000000..c0bd34da8 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0016-net-mana-Remove-redundant-pci_clear_master.patch @@ -0,0 +1,54 @@ +From 0022db71934d56cc601cacee4c1e414d7f3cbb37 Mon Sep 17 00:00:00 2001 +From: Cai Huoqing <cai.huoqing@linux.dev> +Date: Thu, 23 Mar 2023 17:03:05 +0800 +Subject: [PATCH 16/23] net: mana: Remove redundant pci_clear_master + +Remove pci_clear_master to simplify the code, +the bus-mastering is also cleared in do_pci_disable_device, +like this: +./drivers/pci/pci.c:2197 +static void do_pci_disable_device(struct pci_dev *dev) +{ + u16 pci_command; + + pci_read_config_word(dev, PCI_COMMAND, &pci_command); + if (pci_command & PCI_COMMAND_MASTER) { + pci_command &= ~PCI_COMMAND_MASTER; + pci_write_config_word(dev, PCI_COMMAND, pci_command); + } + + pcibios_disable_device(dev); +}. +And dev->is_busmaster is set to 0 in pci_disable_device. + +Signed-off-by: Cai Huoqing <cai.huoqing@linux.dev> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 2d59af8307526f2829fdec9c5c5898a857d55180) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/gdma_main.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index 5b7fddfc9ff1..97a1845c676a 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -1440,7 +1440,6 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + release_region: + pci_release_regions(pdev); + disable_dev: +- pci_clear_master(pdev); + pci_disable_device(pdev); + dev_err(&pdev->dev, "gdma probe failed: err = %d\n", err); + return err; +@@ -1459,7 +1458,6 @@ static void mana_gd_remove(struct pci_dev *pdev) + vfree(gc); + + pci_release_regions(pdev); +- pci_clear_master(pdev); + pci_disable_device(pdev); + } + +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0017-net-mana-Use-napi_build_skb-in-RX-path.patch b/debian/patches/features/all/ethernet-microsoft/0017-net-mana-Use-napi_build_skb-in-RX-path.patch new file mode 100644 index 000000000..c8f0f4588 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0017-net-mana-Use-napi_build_skb-in-RX-path.patch @@ -0,0 +1,33 @@ +From a8796c5278b15a55111d43ccd622b745945ca3d4 Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Wed, 12 Apr 2023 14:16:00 -0700 +Subject: [PATCH 17/23] net: mana: Use napi_build_skb in RX path + +Use napi_build_skb() instead of build_skb() to take advantage of the +NAPI percpu caches to obtain skbuff_head. + +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit ce518bc3e9ca342309995c9270c3ec4892963695) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 55bf40e5ee71..a1b7905ed2f7 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1188,7 +1188,7 @@ static void mana_post_pkt_rxq(struct mana_rxq *rxq) + static struct sk_buff *mana_build_skb(void *buf_va, uint pkt_len, + struct xdp_buff *xdp) + { +- struct sk_buff *skb = build_skb(buf_va, PAGE_SIZE); ++ struct sk_buff *skb = napi_build_skb(buf_va, PAGE_SIZE); + + if (!skb) + return NULL; +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0018-net-mana-Refactor-RX-buffer-allocation-code-to-prepa.patch b/debian/patches/features/all/ethernet-microsoft/0018-net-mana-Refactor-RX-buffer-allocation-code-to-prepa.patch new file mode 100644 index 000000000..7c072d77c --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0018-net-mana-Refactor-RX-buffer-allocation-code-to-prepa.patch @@ -0,0 +1,289 @@ +From cf9f102448044cea851cb97666bf6e853c8963e3 Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Wed, 12 Apr 2023 14:16:01 -0700 +Subject: [PATCH 18/23] net: mana: Refactor RX buffer allocation code to + prepare for various MTU + +Move out common buffer allocation code from mana_process_rx_cqe() and +mana_alloc_rx_wqe() to helper functions. +Refactor related variables so they can be changed in one place, and buffer +sizes are in sync. + +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit a2917b23497e4205db32271e4e06e142a9f8a6aa) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 154 ++++++++++-------- + include/net/mana/mana.h | 6 +- + 2 files changed, 91 insertions(+), 69 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index a1b7905ed2f7..af0c0ee95d87 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1282,14 +1282,64 @@ static void mana_rx_skb(void *buf_va, struct mana_rxcomp_oob *cqe, + u64_stats_update_end(&rx_stats->syncp); + + drop: +- WARN_ON_ONCE(rxq->xdp_save_page); +- rxq->xdp_save_page = virt_to_page(buf_va); ++ WARN_ON_ONCE(rxq->xdp_save_va); ++ /* Save for reuse */ ++ rxq->xdp_save_va = buf_va; + + ++ndev->stats.rx_dropped; + + return; + } + ++static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev, ++ dma_addr_t *da, bool is_napi) ++{ ++ struct page *page; ++ void *va; ++ ++ /* Reuse XDP dropped page if available */ ++ if (rxq->xdp_save_va) { ++ va = rxq->xdp_save_va; ++ rxq->xdp_save_va = NULL; ++ } else { ++ page = dev_alloc_page(); ++ if (!page) ++ return NULL; ++ ++ va = page_to_virt(page); ++ } ++ ++ *da = dma_map_single(dev, va + XDP_PACKET_HEADROOM, rxq->datasize, ++ DMA_FROM_DEVICE); ++ ++ if (dma_mapping_error(dev, *da)) { ++ put_page(virt_to_head_page(va)); ++ return NULL; ++ } ++ ++ return va; ++} ++ ++/* Allocate frag for rx buffer, and save the old buf */ ++static void mana_refill_rxoob(struct device *dev, struct mana_rxq *rxq, ++ struct mana_recv_buf_oob *rxoob, void **old_buf) ++{ ++ dma_addr_t da; ++ void *va; ++ ++ va = mana_get_rxfrag(rxq, dev, &da, true); ++ ++ if (!va) ++ return; ++ ++ dma_unmap_single(dev, rxoob->sgl[0].address, rxq->datasize, ++ DMA_FROM_DEVICE); ++ *old_buf = rxoob->buf_va; ++ ++ rxoob->buf_va = va; ++ rxoob->sgl[0].address = da; ++} ++ + static void mana_process_rx_cqe(struct mana_rxq *rxq, struct mana_cq *cq, + struct gdma_comp *cqe) + { +@@ -1299,10 +1349,8 @@ static void mana_process_rx_cqe(struct mana_rxq *rxq, struct mana_cq *cq, + struct mana_recv_buf_oob *rxbuf_oob; + struct mana_port_context *apc; + struct device *dev = gc->dev; +- void *new_buf, *old_buf; +- struct page *new_page; ++ void *old_buf = NULL; + u32 curr, pktlen; +- dma_addr_t da; + + apc = netdev_priv(ndev); + +@@ -1345,40 +1393,11 @@ static void mana_process_rx_cqe(struct mana_rxq *rxq, struct mana_cq *cq, + rxbuf_oob = &rxq->rx_oobs[curr]; + WARN_ON_ONCE(rxbuf_oob->wqe_inf.wqe_size_in_bu != 1); + +- /* Reuse XDP dropped page if available */ +- if (rxq->xdp_save_page) { +- new_page = rxq->xdp_save_page; +- rxq->xdp_save_page = NULL; +- } else { +- new_page = alloc_page(GFP_ATOMIC); +- } +- +- if (new_page) { +- da = dma_map_page(dev, new_page, XDP_PACKET_HEADROOM, rxq->datasize, +- DMA_FROM_DEVICE); +- +- if (dma_mapping_error(dev, da)) { +- __free_page(new_page); +- new_page = NULL; +- } +- } +- +- new_buf = new_page ? page_to_virt(new_page) : NULL; +- +- if (new_buf) { +- dma_unmap_page(dev, rxbuf_oob->buf_dma_addr, rxq->datasize, +- DMA_FROM_DEVICE); +- +- old_buf = rxbuf_oob->buf_va; +- +- /* refresh the rxbuf_oob with the new page */ +- rxbuf_oob->buf_va = new_buf; +- rxbuf_oob->buf_dma_addr = da; +- rxbuf_oob->sgl[0].address = rxbuf_oob->buf_dma_addr; +- } else { +- old_buf = NULL; /* drop the packet if no memory */ +- } ++ mana_refill_rxoob(dev, rxq, rxbuf_oob, &old_buf); + ++ /* Unsuccessful refill will have old_buf == NULL. ++ * In this case, mana_rx_skb() will drop the packet. ++ */ + mana_rx_skb(old_buf, oob, rxq); + + drop: +@@ -1659,8 +1678,8 @@ static void mana_destroy_rxq(struct mana_port_context *apc, + + mana_deinit_cq(apc, &rxq->rx_cq); + +- if (rxq->xdp_save_page) +- __free_page(rxq->xdp_save_page); ++ if (rxq->xdp_save_va) ++ put_page(virt_to_head_page(rxq->xdp_save_va)); + + for (i = 0; i < rxq->num_rx_buf; i++) { + rx_oob = &rxq->rx_oobs[i]; +@@ -1668,10 +1687,10 @@ static void mana_destroy_rxq(struct mana_port_context *apc, + if (!rx_oob->buf_va) + continue; + +- dma_unmap_page(dev, rx_oob->buf_dma_addr, rxq->datasize, +- DMA_FROM_DEVICE); ++ dma_unmap_single(dev, rx_oob->sgl[0].address, ++ rx_oob->sgl[0].size, DMA_FROM_DEVICE); + +- free_page((unsigned long)rx_oob->buf_va); ++ put_page(virt_to_head_page(rx_oob->buf_va)); + rx_oob->buf_va = NULL; + } + +@@ -1681,6 +1700,26 @@ static void mana_destroy_rxq(struct mana_port_context *apc, + kfree(rxq); + } + ++static int mana_fill_rx_oob(struct mana_recv_buf_oob *rx_oob, u32 mem_key, ++ struct mana_rxq *rxq, struct device *dev) ++{ ++ dma_addr_t da; ++ void *va; ++ ++ va = mana_get_rxfrag(rxq, dev, &da, false); ++ ++ if (!va) ++ return -ENOMEM; ++ ++ rx_oob->buf_va = va; ++ ++ rx_oob->sgl[0].address = da; ++ rx_oob->sgl[0].size = rxq->datasize; ++ rx_oob->sgl[0].mem_key = mem_key; ++ ++ return 0; ++} ++ + #define MANA_WQE_HEADER_SIZE 16 + #define MANA_WQE_SGE_SIZE 16 + +@@ -1690,9 +1729,8 @@ static int mana_alloc_rx_wqe(struct mana_port_context *apc, + struct gdma_context *gc = apc->ac->gdma_dev->gdma_context; + struct mana_recv_buf_oob *rx_oob; + struct device *dev = gc->dev; +- struct page *page; +- dma_addr_t da; + u32 buf_idx; ++ int ret; + + WARN_ON(rxq->datasize == 0 || rxq->datasize > PAGE_SIZE); + +@@ -1703,25 +1741,12 @@ static int mana_alloc_rx_wqe(struct mana_port_context *apc, + rx_oob = &rxq->rx_oobs[buf_idx]; + memset(rx_oob, 0, sizeof(*rx_oob)); + +- page = alloc_page(GFP_KERNEL); +- if (!page) +- return -ENOMEM; +- +- da = dma_map_page(dev, page, XDP_PACKET_HEADROOM, rxq->datasize, +- DMA_FROM_DEVICE); +- +- if (dma_mapping_error(dev, da)) { +- __free_page(page); +- return -ENOMEM; +- } +- +- rx_oob->buf_va = page_to_virt(page); +- rx_oob->buf_dma_addr = da; +- + rx_oob->num_sge = 1; +- rx_oob->sgl[0].address = rx_oob->buf_dma_addr; +- rx_oob->sgl[0].size = rxq->datasize; +- rx_oob->sgl[0].mem_key = apc->ac->gdma_dev->gpa_mkey; ++ ++ ret = mana_fill_rx_oob(rx_oob, apc->ac->gdma_dev->gpa_mkey, rxq, ++ dev); ++ if (ret) ++ return ret; + + rx_oob->wqe_req.sgl = rx_oob->sgl; + rx_oob->wqe_req.num_sge = rx_oob->num_sge; +@@ -1780,9 +1805,10 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc, + rxq->ndev = ndev; + rxq->num_rx_buf = RX_BUFFERS_PER_QUEUE; + rxq->rxq_idx = rxq_idx; +- rxq->datasize = ALIGN(MAX_FRAME_SIZE, 64); + rxq->rxobj = INVALID_MANA_HANDLE; + ++ rxq->datasize = ALIGN(ETH_FRAME_LEN, 64); ++ + err = mana_alloc_rx_wqe(apc, rxq, &rq_size, &cq_size); + if (err) + goto out; +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index 343ace6de20e..da556246233e 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -36,9 +36,6 @@ enum TRI_STATE { + + #define COMP_ENTRY_SIZE 64 + +-#define ADAPTER_MTU_SIZE 1500 +-#define MAX_FRAME_SIZE (ADAPTER_MTU_SIZE + 14) +- + #define RX_BUFFERS_PER_QUEUE 512 + + #define MAX_SEND_BUFFERS_PER_QUEUE 256 +@@ -282,7 +279,6 @@ struct mana_recv_buf_oob { + struct gdma_wqe_request wqe_req; + + void *buf_va; +- dma_addr_t buf_dma_addr; + + /* SGL of the buffer going to be sent has part of the work request. */ + u32 num_sge; +@@ -322,7 +318,7 @@ struct mana_rxq { + + struct bpf_prog __rcu *bpf_prog; + struct xdp_rxq_info xdp_rxq; +- struct page *xdp_save_page; ++ void *xdp_save_va; /* for reusing */ + bool xdp_flush; + int xdp_rc; /* XDP redirect return code */ + +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0019-net-mana-Enable-RX-path-to-handle-various-MTU-sizes.patch b/debian/patches/features/all/ethernet-microsoft/0019-net-mana-Enable-RX-path-to-handle-various-MTU-sizes.patch new file mode 100644 index 000000000..7fb93c495 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0019-net-mana-Enable-RX-path-to-handle-various-MTU-sizes.patch @@ -0,0 +1,147 @@ +From 8640f747acafd65c43be07bd7db9a431b5926db3 Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Wed, 12 Apr 2023 14:16:02 -0700 +Subject: [PATCH 19/23] net: mana: Enable RX path to handle various MTU sizes + +Update RX data path to allocate and use RX queue DMA buffers with +proper size based on potentially various MTU sizes. + +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 2fbbd712baf1c60996554326728bbdbef5616e12) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 38 ++++++++++++++----- + include/net/mana/mana.h | 7 ++++ + 2 files changed, 35 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index af0c0ee95d87..afbbe447de1d 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1185,10 +1185,10 @@ static void mana_post_pkt_rxq(struct mana_rxq *rxq) + WARN_ON_ONCE(recv_buf_oob->wqe_inf.wqe_size_in_bu != 1); + } + +-static struct sk_buff *mana_build_skb(void *buf_va, uint pkt_len, +- struct xdp_buff *xdp) ++static struct sk_buff *mana_build_skb(struct mana_rxq *rxq, void *buf_va, ++ uint pkt_len, struct xdp_buff *xdp) + { +- struct sk_buff *skb = napi_build_skb(buf_va, PAGE_SIZE); ++ struct sk_buff *skb = napi_build_skb(buf_va, rxq->alloc_size); + + if (!skb) + return NULL; +@@ -1196,11 +1196,12 @@ static struct sk_buff *mana_build_skb(void *buf_va, uint pkt_len, + if (xdp->data_hard_start) { + skb_reserve(skb, xdp->data - xdp->data_hard_start); + skb_put(skb, xdp->data_end - xdp->data); +- } else { +- skb_reserve(skb, XDP_PACKET_HEADROOM); +- skb_put(skb, pkt_len); ++ return skb; + } + ++ skb_reserve(skb, rxq->headroom); ++ skb_put(skb, pkt_len); ++ + return skb; + } + +@@ -1233,7 +1234,7 @@ static void mana_rx_skb(void *buf_va, struct mana_rxcomp_oob *cqe, + if (act != XDP_PASS && act != XDP_TX) + goto drop_xdp; + +- skb = mana_build_skb(buf_va, pkt_len, &xdp); ++ skb = mana_build_skb(rxq, buf_va, pkt_len, &xdp); + + if (!skb) + goto drop; +@@ -1301,6 +1302,14 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev, + if (rxq->xdp_save_va) { + va = rxq->xdp_save_va; + rxq->xdp_save_va = NULL; ++ } else if (rxq->alloc_size > PAGE_SIZE) { ++ if (is_napi) ++ va = napi_alloc_frag(rxq->alloc_size); ++ else ++ va = netdev_alloc_frag(rxq->alloc_size); ++ ++ if (!va) ++ return NULL; + } else { + page = dev_alloc_page(); + if (!page) +@@ -1309,7 +1318,7 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev, + va = page_to_virt(page); + } + +- *da = dma_map_single(dev, va + XDP_PACKET_HEADROOM, rxq->datasize, ++ *da = dma_map_single(dev, va + rxq->headroom, rxq->datasize, + DMA_FROM_DEVICE); + + if (dma_mapping_error(dev, *da)) { +@@ -1732,7 +1741,7 @@ static int mana_alloc_rx_wqe(struct mana_port_context *apc, + u32 buf_idx; + int ret; + +- WARN_ON(rxq->datasize == 0 || rxq->datasize > PAGE_SIZE); ++ WARN_ON(rxq->datasize == 0); + + *rxq_size = 0; + *cq_size = 0; +@@ -1788,6 +1797,7 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc, + struct gdma_dev *gd = apc->ac->gdma_dev; + struct mana_obj_spec wq_spec; + struct mana_obj_spec cq_spec; ++ unsigned int mtu = ndev->mtu; + struct gdma_queue_spec spec; + struct mana_cq *cq = NULL; + struct gdma_context *gc; +@@ -1807,7 +1817,15 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc, + rxq->rxq_idx = rxq_idx; + rxq->rxobj = INVALID_MANA_HANDLE; + +- rxq->datasize = ALIGN(ETH_FRAME_LEN, 64); ++ rxq->datasize = ALIGN(mtu + ETH_HLEN, 64); ++ ++ if (mtu > MANA_XDP_MTU_MAX) { ++ rxq->alloc_size = mtu + MANA_RXBUF_PAD; ++ rxq->headroom = 0; ++ } else { ++ rxq->alloc_size = mtu + MANA_RXBUF_PAD + XDP_PACKET_HEADROOM; ++ rxq->headroom = XDP_PACKET_HEADROOM; ++ } + + err = mana_alloc_rx_wqe(apc, rxq, &rq_size, &cq_size); + if (err) +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index da556246233e..42795849d68c 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -291,6 +291,11 @@ struct mana_recv_buf_oob { + struct gdma_posted_wqe_info wqe_inf; + }; + ++#define MANA_RXBUF_PAD (SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) \ ++ + ETH_HLEN) ++ ++#define MANA_XDP_MTU_MAX (PAGE_SIZE - MANA_RXBUF_PAD - XDP_PACKET_HEADROOM) ++ + struct mana_rxq { + struct gdma_queue *gdma_rq; + /* Cache the gdma receive queue id */ +@@ -300,6 +305,8 @@ struct mana_rxq { + u32 rxq_idx; + + u32 datasize; ++ u32 alloc_size; ++ u32 headroom; + + mana_handle_t rxobj; + +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0020-net-mana-Add-support-for-jumbo-frame.patch b/debian/patches/features/all/ethernet-microsoft/0020-net-mana-Add-support-for-jumbo-frame.patch new file mode 100644 index 000000000..5a5a44d88 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0020-net-mana-Add-support-for-jumbo-frame.patch @@ -0,0 +1,423 @@ +From 2552a80c48dd33368d0e7a2b94e1eb72e3053b99 Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Wed, 12 Apr 2023 14:16:03 -0700 +Subject: [PATCH 20/23] net: mana: Add support for jumbo frame + +During probe, get the hardware-allowed max MTU by querying the device +configuration. Users can select MTU up to the device limit. +When XDP is in use, limit MTU settings so the buffer size is within +one page. And, when MTU is set to a too large value, XDP is not allowed +to run. +Also, to prevent changing MTU fails, and leaves the NIC in a bad state, +pre-allocate all buffers before starting the change. So in low memory +condition, it will return error, without affecting the NIC. + +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 80f6215b450eb8e92d8b1f117abf5ecf867f963e) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + .../net/ethernet/microsoft/mana/mana_bpf.c | 22 +- + drivers/net/ethernet/microsoft/mana/mana_en.c | 217 ++++++++++++++++-- + include/net/mana/gdma.h | 4 + + include/net/mana/mana.h | 14 ++ + 4 files changed, 233 insertions(+), 24 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_bpf.c b/drivers/net/ethernet/microsoft/mana/mana_bpf.c +index 3caea631229c..23b1521c0df9 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_bpf.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_bpf.c +@@ -133,12 +133,6 @@ u32 mana_run_xdp(struct net_device *ndev, struct mana_rxq *rxq, + return act; + } + +-static unsigned int mana_xdp_fraglen(unsigned int len) +-{ +- return SKB_DATA_ALIGN(len) + +- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +-} +- + struct bpf_prog *mana_xdp_get(struct mana_port_context *apc) + { + ASSERT_RTNL(); +@@ -179,17 +173,18 @@ static int mana_xdp_set(struct net_device *ndev, struct bpf_prog *prog, + { + struct mana_port_context *apc = netdev_priv(ndev); + struct bpf_prog *old_prog; +- int buf_max; ++ struct gdma_context *gc; ++ ++ gc = apc->ac->gdma_dev->gdma_context; + + old_prog = mana_xdp_get(apc); + + if (!old_prog && !prog) + return 0; + +- buf_max = XDP_PACKET_HEADROOM + mana_xdp_fraglen(ndev->mtu + ETH_HLEN); +- if (prog && buf_max > PAGE_SIZE) { +- netdev_err(ndev, "XDP: mtu:%u too large, buf_max:%u\n", +- ndev->mtu, buf_max); ++ if (prog && ndev->mtu > MANA_XDP_MTU_MAX) { ++ netdev_err(ndev, "XDP: mtu:%u too large, mtu_max:%lu\n", ++ ndev->mtu, MANA_XDP_MTU_MAX); + NL_SET_ERR_MSG_MOD(extack, "XDP: mtu too large"); + + return -EOPNOTSUPP; +@@ -206,6 +201,11 @@ static int mana_xdp_set(struct net_device *ndev, struct bpf_prog *prog, + if (apc->port_is_up) + mana_chn_setxdp(apc, prog); + ++ if (prog) ++ ndev->max_mtu = MANA_XDP_MTU_MAX; ++ else ++ ndev->max_mtu = gc->adapter_mtu - ETH_HLEN; ++ + return 0; + } + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index afbbe447de1d..34fa5c758b28 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -427,6 +427,192 @@ static u16 mana_select_queue(struct net_device *ndev, struct sk_buff *skb, + return txq; + } + ++/* Release pre-allocated RX buffers */ ++static void mana_pre_dealloc_rxbufs(struct mana_port_context *mpc) ++{ ++ struct device *dev; ++ int i; ++ ++ dev = mpc->ac->gdma_dev->gdma_context->dev; ++ ++ if (!mpc->rxbufs_pre) ++ goto out1; ++ ++ if (!mpc->das_pre) ++ goto out2; ++ ++ while (mpc->rxbpre_total) { ++ i = --mpc->rxbpre_total; ++ dma_unmap_single(dev, mpc->das_pre[i], mpc->rxbpre_datasize, ++ DMA_FROM_DEVICE); ++ put_page(virt_to_head_page(mpc->rxbufs_pre[i])); ++ } ++ ++ kfree(mpc->das_pre); ++ mpc->das_pre = NULL; ++ ++out2: ++ kfree(mpc->rxbufs_pre); ++ mpc->rxbufs_pre = NULL; ++ ++out1: ++ mpc->rxbpre_datasize = 0; ++ mpc->rxbpre_alloc_size = 0; ++ mpc->rxbpre_headroom = 0; ++} ++ ++/* Get a buffer from the pre-allocated RX buffers */ ++static void *mana_get_rxbuf_pre(struct mana_rxq *rxq, dma_addr_t *da) ++{ ++ struct net_device *ndev = rxq->ndev; ++ struct mana_port_context *mpc; ++ void *va; ++ ++ mpc = netdev_priv(ndev); ++ ++ if (!mpc->rxbufs_pre || !mpc->das_pre || !mpc->rxbpre_total) { ++ netdev_err(ndev, "No RX pre-allocated bufs\n"); ++ return NULL; ++ } ++ ++ /* Check sizes to catch unexpected coding error */ ++ if (mpc->rxbpre_datasize != rxq->datasize) { ++ netdev_err(ndev, "rxbpre_datasize mismatch: %u: %u\n", ++ mpc->rxbpre_datasize, rxq->datasize); ++ return NULL; ++ } ++ ++ if (mpc->rxbpre_alloc_size != rxq->alloc_size) { ++ netdev_err(ndev, "rxbpre_alloc_size mismatch: %u: %u\n", ++ mpc->rxbpre_alloc_size, rxq->alloc_size); ++ return NULL; ++ } ++ ++ if (mpc->rxbpre_headroom != rxq->headroom) { ++ netdev_err(ndev, "rxbpre_headroom mismatch: %u: %u\n", ++ mpc->rxbpre_headroom, rxq->headroom); ++ return NULL; ++ } ++ ++ mpc->rxbpre_total--; ++ ++ *da = mpc->das_pre[mpc->rxbpre_total]; ++ va = mpc->rxbufs_pre[mpc->rxbpre_total]; ++ mpc->rxbufs_pre[mpc->rxbpre_total] = NULL; ++ ++ /* Deallocate the array after all buffers are gone */ ++ if (!mpc->rxbpre_total) ++ mana_pre_dealloc_rxbufs(mpc); ++ ++ return va; ++} ++ ++/* Get RX buffer's data size, alloc size, XDP headroom based on MTU */ ++static void mana_get_rxbuf_cfg(int mtu, u32 *datasize, u32 *alloc_size, ++ u32 *headroom) ++{ ++ if (mtu > MANA_XDP_MTU_MAX) ++ *headroom = 0; /* no support for XDP */ ++ else ++ *headroom = XDP_PACKET_HEADROOM; ++ ++ *alloc_size = mtu + MANA_RXBUF_PAD + *headroom; ++ ++ *datasize = ALIGN(mtu + ETH_HLEN, MANA_RX_DATA_ALIGN); ++} ++ ++static int mana_pre_alloc_rxbufs(struct mana_port_context *mpc, int new_mtu) ++{ ++ struct device *dev; ++ struct page *page; ++ dma_addr_t da; ++ int num_rxb; ++ void *va; ++ int i; ++ ++ mana_get_rxbuf_cfg(new_mtu, &mpc->rxbpre_datasize, ++ &mpc->rxbpre_alloc_size, &mpc->rxbpre_headroom); ++ ++ dev = mpc->ac->gdma_dev->gdma_context->dev; ++ ++ num_rxb = mpc->num_queues * RX_BUFFERS_PER_QUEUE; ++ ++ WARN(mpc->rxbufs_pre, "mana rxbufs_pre exists\n"); ++ mpc->rxbufs_pre = kmalloc_array(num_rxb, sizeof(void *), GFP_KERNEL); ++ if (!mpc->rxbufs_pre) ++ goto error; ++ ++ mpc->das_pre = kmalloc_array(num_rxb, sizeof(dma_addr_t), GFP_KERNEL); ++ if (!mpc->das_pre) ++ goto error; ++ ++ mpc->rxbpre_total = 0; ++ ++ for (i = 0; i < num_rxb; i++) { ++ if (mpc->rxbpre_alloc_size > PAGE_SIZE) { ++ va = netdev_alloc_frag(mpc->rxbpre_alloc_size); ++ if (!va) ++ goto error; ++ } else { ++ page = dev_alloc_page(); ++ if (!page) ++ goto error; ++ ++ va = page_to_virt(page); ++ } ++ ++ da = dma_map_single(dev, va + mpc->rxbpre_headroom, ++ mpc->rxbpre_datasize, DMA_FROM_DEVICE); ++ ++ if (dma_mapping_error(dev, da)) { ++ put_page(virt_to_head_page(va)); ++ goto error; ++ } ++ ++ mpc->rxbufs_pre[i] = va; ++ mpc->das_pre[i] = da; ++ mpc->rxbpre_total = i + 1; ++ } ++ ++ return 0; ++ ++error: ++ mana_pre_dealloc_rxbufs(mpc); ++ return -ENOMEM; ++} ++ ++static int mana_change_mtu(struct net_device *ndev, int new_mtu) ++{ ++ struct mana_port_context *mpc = netdev_priv(ndev); ++ unsigned int old_mtu = ndev->mtu; ++ int err; ++ ++ /* Pre-allocate buffers to prevent failure in mana_attach later */ ++ err = mana_pre_alloc_rxbufs(mpc, new_mtu); ++ if (err) { ++ netdev_err(ndev, "Insufficient memory for new MTU\n"); ++ return err; ++ } ++ ++ err = mana_detach(ndev, false); ++ if (err) { ++ netdev_err(ndev, "mana_detach failed: %d\n", err); ++ goto out; ++ } ++ ++ ndev->mtu = new_mtu; ++ ++ err = mana_attach(ndev); ++ if (err) { ++ netdev_err(ndev, "mana_attach failed: %d\n", err); ++ ndev->mtu = old_mtu; ++ } ++ ++out: ++ mana_pre_dealloc_rxbufs(mpc); ++ return err; ++} ++ + static const struct net_device_ops mana_devops = { + .ndo_open = mana_open, + .ndo_stop = mana_close, +@@ -436,6 +622,7 @@ static const struct net_device_ops mana_devops = { + .ndo_get_stats64 = mana_get_stats64, + .ndo_bpf = mana_bpf, + .ndo_xdp_xmit = mana_xdp_xmit, ++ .ndo_change_mtu = mana_change_mtu, + }; + + static void mana_cleanup_port_context(struct mana_port_context *apc) +@@ -625,6 +812,9 @@ static int mana_query_device_cfg(struct mana_context *ac, u32 proto_major_ver, + + mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_DEV_CONFIG, + sizeof(req), sizeof(resp)); ++ ++ req.hdr.resp.msg_version = GDMA_MESSAGE_V2; ++ + req.proto_major_ver = proto_major_ver; + req.proto_minor_ver = proto_minor_ver; + req.proto_micro_ver = proto_micro_ver; +@@ -647,6 +837,11 @@ static int mana_query_device_cfg(struct mana_context *ac, u32 proto_major_ver, + + *max_num_vports = resp.max_num_vports; + ++ if (resp.hdr.response.msg_version == GDMA_MESSAGE_V2) ++ gc->adapter_mtu = resp.adapter_mtu; ++ else ++ gc->adapter_mtu = ETH_FRAME_LEN; ++ + return 0; + } + +@@ -1712,10 +1907,14 @@ static void mana_destroy_rxq(struct mana_port_context *apc, + static int mana_fill_rx_oob(struct mana_recv_buf_oob *rx_oob, u32 mem_key, + struct mana_rxq *rxq, struct device *dev) + { ++ struct mana_port_context *mpc = netdev_priv(rxq->ndev); + dma_addr_t da; + void *va; + +- va = mana_get_rxfrag(rxq, dev, &da, false); ++ if (mpc->rxbufs_pre) ++ va = mana_get_rxbuf_pre(rxq, &da); ++ else ++ va = mana_get_rxfrag(rxq, dev, &da, false); + + if (!va) + return -ENOMEM; +@@ -1797,7 +1996,6 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc, + struct gdma_dev *gd = apc->ac->gdma_dev; + struct mana_obj_spec wq_spec; + struct mana_obj_spec cq_spec; +- unsigned int mtu = ndev->mtu; + struct gdma_queue_spec spec; + struct mana_cq *cq = NULL; + struct gdma_context *gc; +@@ -1817,15 +2015,8 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc, + rxq->rxq_idx = rxq_idx; + rxq->rxobj = INVALID_MANA_HANDLE; + +- rxq->datasize = ALIGN(mtu + ETH_HLEN, 64); +- +- if (mtu > MANA_XDP_MTU_MAX) { +- rxq->alloc_size = mtu + MANA_RXBUF_PAD; +- rxq->headroom = 0; +- } else { +- rxq->alloc_size = mtu + MANA_RXBUF_PAD + XDP_PACKET_HEADROOM; +- rxq->headroom = XDP_PACKET_HEADROOM; +- } ++ mana_get_rxbuf_cfg(ndev->mtu, &rxq->datasize, &rxq->alloc_size, ++ &rxq->headroom); + + err = mana_alloc_rx_wqe(apc, rxq, &rq_size, &cq_size); + if (err) +@@ -2238,8 +2429,8 @@ static int mana_probe_port(struct mana_context *ac, int port_idx, + ndev->netdev_ops = &mana_devops; + ndev->ethtool_ops = &mana_ethtool_ops; + ndev->mtu = ETH_DATA_LEN; +- ndev->max_mtu = ndev->mtu; +- ndev->min_mtu = ndev->mtu; ++ ndev->max_mtu = gc->adapter_mtu - ETH_HLEN; ++ ndev->min_mtu = ETH_MIN_MTU; + ndev->needed_headroom = MANA_HEADROOM; + ndev->dev_port = port_idx; + SET_NETDEV_DEV(ndev, gc->dev); +diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h +index aabc7cea8a49..b27bf852471b 100644 +--- a/include/net/mana/gdma.h ++++ b/include/net/mana/gdma.h +@@ -143,6 +143,7 @@ struct gdma_general_req { + }; /* HW DATA */ + + #define GDMA_MESSAGE_V1 1 ++#define GDMA_MESSAGE_V2 2 + + struct gdma_general_resp { + struct gdma_resp_hdr hdr; +@@ -352,6 +353,9 @@ struct gdma_context { + struct gdma_resource msix_resource; + struct gdma_irq_context *irq_contexts; + ++ /* L2 MTU */ ++ u16 adapter_mtu; ++ + /* This maps a CQ index to the queue structure. */ + unsigned int max_num_cqs; + struct gdma_queue **cq_table; +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index 42795849d68c..4f19d73b66ae 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -37,6 +37,7 @@ enum TRI_STATE { + #define COMP_ENTRY_SIZE 64 + + #define RX_BUFFERS_PER_QUEUE 512 ++#define MANA_RX_DATA_ALIGN 64 + + #define MAX_SEND_BUFFERS_PER_QUEUE 256 + +@@ -390,6 +391,14 @@ struct mana_port_context { + /* This points to an array of num_queues of RQ pointers. */ + struct mana_rxq **rxqs; + ++ /* pre-allocated rx buffer array */ ++ void **rxbufs_pre; ++ dma_addr_t *das_pre; ++ int rxbpre_total; ++ u32 rxbpre_datasize; ++ u32 rxbpre_alloc_size; ++ u32 rxbpre_headroom; ++ + struct bpf_prog *bpf_prog; + + /* Create num_queues EQs, SQs, SQ-CQs, RQs and RQ-CQs, respectively. */ +@@ -486,6 +495,11 @@ struct mana_query_device_cfg_resp { + u16 max_num_vports; + u16 reserved; + u32 max_num_eqs; ++ ++ /* response v2: */ ++ u16 adapter_mtu; ++ u16 reserved2; ++ u32 reserved3; + }; /* HW DATA */ + + /* Query vPort Configuration */ +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0021-net-mana-Check-if-netdev-napi_alloc_frag-returns-sin.patch b/debian/patches/features/all/ethernet-microsoft/0021-net-mana-Check-if-netdev-napi_alloc_frag-returns-sin.patch new file mode 100644 index 000000000..33ca4257b --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0021-net-mana-Check-if-netdev-napi_alloc_frag-returns-sin.patch @@ -0,0 +1,54 @@ +From e1541b0cdf147beef46101f2b9fa8aeb9793bd8d Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Fri, 21 Apr 2023 10:06:58 -0700 +Subject: [PATCH 21/23] net: mana: Check if netdev/napi_alloc_frag returns + single page + +netdev/napi_alloc_frag() may fall back to single page which is smaller +than the requested size. +Add error checking to avoid memory overwritten. + +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +(cherry picked from commit df18f2da302f169e1a29098c6ca3b474f1b0269e) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 34fa5c758b28..fc19e62c9c84 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -553,6 +553,14 @@ static int mana_pre_alloc_rxbufs(struct mana_port_context *mpc, int new_mtu) + va = netdev_alloc_frag(mpc->rxbpre_alloc_size); + if (!va) + goto error; ++ ++ page = virt_to_head_page(va); ++ /* Check if the frag falls back to single page */ ++ if (compound_order(page) < ++ get_order(mpc->rxbpre_alloc_size)) { ++ put_page(page); ++ goto error; ++ } + } else { + page = dev_alloc_page(); + if (!page) +@@ -1505,6 +1513,13 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev, + + if (!va) + return NULL; ++ ++ page = virt_to_head_page(va); ++ /* Check if the frag falls back to single page */ ++ if (compound_order(page) < get_order(rxq->alloc_size)) { ++ put_page(page); ++ return NULL; ++ } + } else { + page = dev_alloc_page(); + if (!page) +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0022-net-mana-Fix-perf-regression-remove-rx_cqes-tx_cqes-.patch b/debian/patches/features/all/ethernet-microsoft/0022-net-mana-Fix-perf-regression-remove-rx_cqes-tx_cqes-.patch new file mode 100644 index 000000000..21a354cc8 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0022-net-mana-Fix-perf-regression-remove-rx_cqes-tx_cqes-.patch @@ -0,0 +1,121 @@ +From a6967df15a72ffd53963492b8cf52438cf0c27f7 Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Fri, 26 May 2023 08:38:57 -0700 +Subject: [PATCH 22/23] net: mana: Fix perf regression: remove rx_cqes, tx_cqes + counters + +The apc->eth_stats.rx_cqes is one per NIC (vport), and it's on the +frequent and parallel code path of all queues. So, r/w into this +single shared variable by many threads on different CPUs creates a +lot caching and memory overhead, hence perf regression. And, it's +not accurate due to the high volume concurrent r/w. + +For example, a workload is iperf with 128 threads, and with RPS +enabled. We saw perf regression of 25% with the previous patch +adding the counters. And this patch eliminates the regression. + +Since the error path of mana_poll_rx_cq() already has warnings, so +keeping the counter and convert it to a per-queue variable is not +necessary. So, just remove this counter from this high frequency +code path. + +Also, remove the tx_cqes counter for the same reason. We have +warnings & other counters for errors on that path, and don't need +to count every normal cqe processing. + +Cc: stable@vger.kernel.org +Fixes: bd7fc6e1957c ("net: mana: Add new MANA VF performance counters for easier troubleshooting") +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com> +Reviewed-by: Jiri Pirko <jiri@nvidia.com> +Link: https://lore.kernel.org/r/1685115537-31675-1-git-send-email-haiyangz@microsoft.com +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +(cherry picked from commit 1919b39fc6eabb9a6f9a51706ff6d03865f5df29) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 10 ---------- + drivers/net/ethernet/microsoft/mana/mana_ethtool.c | 2 -- + include/net/mana/mana.h | 2 -- + 3 files changed, 14 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index fc19e62c9c84..25b17213e54d 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1280,8 +1280,6 @@ static void mana_poll_tx_cq(struct mana_cq *cq) + if (comp_read < 1) + return; + +- apc->eth_stats.tx_cqes = comp_read; +- + for (i = 0; i < comp_read; i++) { + struct mana_tx_comp_oob *cqe_oob; + +@@ -1364,8 +1362,6 @@ static void mana_poll_tx_cq(struct mana_cq *cq) + WARN_ON_ONCE(1); + + cq->work_done = pkt_transmitted; +- +- apc->eth_stats.tx_cqes -= pkt_transmitted; + } + + static void mana_post_pkt_rxq(struct mana_rxq *rxq) +@@ -1629,15 +1625,11 @@ static void mana_poll_rx_cq(struct mana_cq *cq) + { + struct gdma_comp *comp = cq->gdma_comp_buf; + struct mana_rxq *rxq = cq->rxq; +- struct mana_port_context *apc; + int comp_read, i; + +- apc = netdev_priv(rxq->ndev); +- + comp_read = mana_gd_poll_cq(cq->gdma_cq, comp, CQE_POLLING_BUFFER); + WARN_ON_ONCE(comp_read > CQE_POLLING_BUFFER); + +- apc->eth_stats.rx_cqes = comp_read; + rxq->xdp_flush = false; + + for (i = 0; i < comp_read; i++) { +@@ -1649,8 +1641,6 @@ static void mana_poll_rx_cq(struct mana_cq *cq) + return; + + mana_process_rx_cqe(rxq, cq, &comp[i]); +- +- apc->eth_stats.rx_cqes--; + } + + if (rxq->xdp_flush) +diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +index a64c81410dc1..0dc78679f620 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +@@ -13,11 +13,9 @@ static const struct { + } mana_eth_stats[] = { + {"stop_queue", offsetof(struct mana_ethtool_stats, stop_queue)}, + {"wake_queue", offsetof(struct mana_ethtool_stats, wake_queue)}, +- {"tx_cqes", offsetof(struct mana_ethtool_stats, tx_cqes)}, + {"tx_cq_err", offsetof(struct mana_ethtool_stats, tx_cqe_err)}, + {"tx_cqe_unknown_type", offsetof(struct mana_ethtool_stats, + tx_cqe_unknown_type)}, +- {"rx_cqes", offsetof(struct mana_ethtool_stats, rx_cqes)}, + {"rx_coalesced_err", offsetof(struct mana_ethtool_stats, + rx_coalesced_err)}, + {"rx_cqe_unknown_type", offsetof(struct mana_ethtool_stats, +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index 4f19d73b66ae..3abfce420594 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -347,10 +347,8 @@ struct mana_tx_qp { + struct mana_ethtool_stats { + u64 stop_queue; + u64 wake_queue; +- u64 tx_cqes; + u64 tx_cqe_err; + u64 tx_cqe_unknown_type; +- u64 rx_cqes; + u64 rx_coalesced_err; + u64 rx_cqe_unknown_type; + }; +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0023-net-mana-Add-support-for-vlan-tagging.patch b/debian/patches/features/all/ethernet-microsoft/0023-net-mana-Add-support-for-vlan-tagging.patch new file mode 100644 index 000000000..74866c088 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0023-net-mana-Add-support-for-vlan-tagging.patch @@ -0,0 +1,67 @@ +From dc801500fea4fd5ddecc4007acffb5716a761f51 Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Fri, 9 Jun 2023 05:47:17 -0700 +Subject: [PATCH 23/23] net: mana: Add support for vlan tagging + +To support vlan, use MANA_LONG_PKT_FMT if vlan tag is present in TX +skb. Then extract the vlan tag from the skb struct, and save it to +tx_oob for the NIC to transmit. For vlan tags on the payload, they +are accepted by the NIC too. + +For RX, extract the vlan tag from CQE and put it into skb. + +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit b803d1fded4085d268507a432dac8077ead68971) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 25b17213e54d..808dbf55beef 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -179,6 +179,14 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) + pkg.tx_oob.s_oob.short_vp_offset = txq->vp_offset; + } + ++ if (skb_vlan_tag_present(skb)) { ++ pkt_fmt = MANA_LONG_PKT_FMT; ++ pkg.tx_oob.l_oob.inject_vlan_pri_tag = 1; ++ pkg.tx_oob.l_oob.pcp = skb_vlan_tag_get_prio(skb); ++ pkg.tx_oob.l_oob.dei = skb_vlan_tag_get_cfi(skb); ++ pkg.tx_oob.l_oob.vlan_id = skb_vlan_tag_get_id(skb); ++ } ++ + pkg.tx_oob.s_oob.pkt_fmt = pkt_fmt; + + if (pkt_fmt == MANA_SHORT_PKT_FMT) { +@@ -1458,6 +1466,12 @@ static void mana_rx_skb(void *buf_va, struct mana_rxcomp_oob *cqe, + skb_set_hash(skb, hash_value, PKT_HASH_TYPE_L3); + } + ++ if (cqe->rx_vlantag_present) { ++ u16 vlan_tci = cqe->rx_vlan_id; ++ ++ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); ++ } ++ + u64_stats_update_begin(&rx_stats->syncp); + rx_stats->packets++; + rx_stats->bytes += pkt_len; +@@ -2454,8 +2468,9 @@ static int mana_probe_port(struct mana_context *ac, int port_idx, + ndev->hw_features |= NETIF_F_RXCSUM; + ndev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6; + ndev->hw_features |= NETIF_F_RXHASH; +- ndev->features = ndev->hw_features; +- ndev->vlan_features = 0; ++ ndev->features = ndev->hw_features | NETIF_F_HW_VLAN_CTAG_TX | ++ NETIF_F_HW_VLAN_CTAG_RX; ++ ndev->vlan_features = ndev->features; + + err = register_netdev(ndev); + if (err) { +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0024-RDMA-mana_ib-Use-v2-version-of-cfg_rx_steer_req-to-e.patch b/debian/patches/features/all/ethernet-microsoft/0024-RDMA-mana_ib-Use-v2-version-of-cfg_rx_steer_req-to-e.patch new file mode 100644 index 000000000..fb8020cdb --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0024-RDMA-mana_ib-Use-v2-version-of-cfg_rx_steer_req-to-e.patch @@ -0,0 +1,78 @@ +From 672aac0622254a8f1f5f9d2aa8cee2319654d083 Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Sat, 13 May 2023 23:18:15 -0700 +Subject: [PATCH 24/30] RDMA/mana_ib: Use v2 version of cfg_rx_steer_req to + enable RX coalescing + +With RX coalescing, one CQE entry can be used to indicate multiple packets +on the receive queue. This saves processing time and PCI bandwidth over +the CQ. + +The MANA Ethernet driver also uses the v2 version of the protocol. It +doesn't use RX coalescing and its behavior is not changed. + +Link: https://lore.kernel.org/r/1684045095-31228-1-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Long Li <longli@microsoft.com> +Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> +(cherry picked from commit 2145328515c8fa9b8a9f7889250bc6c032f2a0e6) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 5 ++++- + include/net/mana/mana.h | 4 +++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 808dbf55beef..7d82b8949a1e 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -981,7 +981,7 @@ static int mana_cfg_vport_steering(struct mana_port_context *apc, + bool update_tab) + { + u16 num_entries = MANA_INDIRECT_TABLE_SIZE; +- struct mana_cfg_rx_steer_req *req = NULL; ++ struct mana_cfg_rx_steer_req_v2 *req; + struct mana_cfg_rx_steer_resp resp = {}; + struct net_device *ndev = apc->ndev; + mana_handle_t *req_indir_tab; +@@ -996,6 +996,8 @@ static int mana_cfg_vport_steering(struct mana_port_context *apc, + mana_gd_init_req_hdr(&req->hdr, MANA_CONFIG_VPORT_RX, req_buf_size, + sizeof(resp)); + ++ req->hdr.req.msg_version = GDMA_MESSAGE_V2; ++ + req->vport = apc->port_handle; + req->num_indir_entries = num_entries; + req->indir_tab_offset = sizeof(*req); +@@ -1005,6 +1007,7 @@ static int mana_cfg_vport_steering(struct mana_port_context *apc, + req->update_hashkey = update_key; + req->update_indir_tab = update_tab; + req->default_rxobj = apc->default_rxobj; ++ req->cqe_coalescing_enable = 0; + + if (update_key) + memcpy(&req->hashkey, apc->hashkey, MANA_HASH_KEY_SIZE); +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index 3abfce420594..46b5769a5b6a 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -576,7 +576,7 @@ struct mana_fence_rq_resp { + }; /* HW DATA */ + + /* Configure vPort Rx Steering */ +-struct mana_cfg_rx_steer_req { ++struct mana_cfg_rx_steer_req_v2 { + struct gdma_req_hdr hdr; + mana_handle_t vport; + u16 num_indir_entries; +@@ -589,6 +589,8 @@ struct mana_cfg_rx_steer_req { + u8 reserved; + mana_handle_t default_rxobj; + u8 hashkey[MANA_HASH_KEY_SIZE]; ++ u8 cqe_coalescing_enable; ++ u8 reserved2[7]; + }; /* HW DATA */ + + struct mana_cfg_rx_steer_resp { +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0025-net-mana-use-vmalloc_array-and-vcalloc.patch b/debian/patches/features/all/ethernet-microsoft/0025-net-mana-use-vmalloc_array-and-vcalloc.patch new file mode 100644 index 000000000..348583771 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0025-net-mana-use-vmalloc_array-and-vcalloc.patch @@ -0,0 +1,75 @@ +From 4a202b0bfd1b2f3509361e5d3f6040f7af90c2ec Mon Sep 17 00:00:00 2001 +From: Julia Lawall <Julia.Lawall@inria.fr> +Date: Tue, 27 Jun 2023 16:43:37 +0200 +Subject: [PATCH 25/30] net: mana: use vmalloc_array and vcalloc + +Use vmalloc_array and vcalloc to protect against +multiplication overflows. + +The changes were done using the following Coccinelle +semantic patch: + +// <smpl> +@initialize:ocaml@ +@@ + +let rename alloc = + match alloc with + "vmalloc" -> "vmalloc_array" + | "vzalloc" -> "vcalloc" + | _ -> failwith "unknown" + +@@ + size_t e1,e2; + constant C1, C2; + expression E1, E2, COUNT, x1, x2, x3; + typedef u8; + typedef __u8; + type t = {u8,__u8,char,unsigned char}; + identifier alloc = {vmalloc,vzalloc}; + fresh identifier realloc = script:ocaml(alloc) { rename alloc }; +@@ + +( + alloc(x1*x2*x3) +| + alloc(C1 * C2) +| + alloc((sizeof(t)) * (COUNT), ...) +| +- alloc((e1) * (e2)) ++ realloc(e1, e2) +| +- alloc((e1) * (COUNT)) ++ realloc(COUNT, e1) +| +- alloc((E1) * (E2)) ++ realloc(E1, E2) +) +// </smpl> + +Signed-off-by: Julia Lawall <Julia.Lawall@inria.fr> +Link: https://lore.kernel.org/r/20230627144339.144478-23-Julia.Lawall@inria.fr +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +(cherry picked from commit e9c74f8b8a31f77f8e9d7bbed5fc9f2eacbf32a5) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/hw_channel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c +index 9d1507eba5b9..2bd1d74021f7 100644 +--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c ++++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c +@@ -627,7 +627,7 @@ static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth, + if (WARN_ON(cq->id >= gc->max_num_cqs)) + return -EPROTO; + +- gc->cq_table = vzalloc(gc->max_num_cqs * sizeof(struct gdma_queue *)); ++ gc->cq_table = vcalloc(gc->max_num_cqs, sizeof(struct gdma_queue *)); + if (!gc->cq_table) + return -ENOMEM; + +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0026-net-mana-Batch-ringing-RX-queue-doorbell-on-receivin.patch b/debian/patches/features/all/ethernet-microsoft/0026-net-mana-Batch-ringing-RX-queue-doorbell-on-receivin.patch new file mode 100644 index 000000000..6f03091cd --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0026-net-mana-Batch-ringing-RX-queue-doorbell-on-receivin.patch @@ -0,0 +1,62 @@ +From ad96bbb0b221f0cc22fba13a28234636bf7fb9f5 Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Mon, 17 Jul 2023 12:35:38 -0700 +Subject: [PATCH 26/30] net: mana: Batch ringing RX queue doorbell on receiving + packets + +It's inefficient to ring the doorbell page every time a WQE is posted to +the received queue. Excessive MMIO writes result in CPU spending more +time waiting on LOCK instructions (atomic operations), resulting in +poor scaling performance. + +Move the code for ringing doorbell page to where after we have posted all +WQEs to the receive queue during a callback from napi_poll(). + +With this change, tests showed an improvement from 120G/s to 160G/s on a +200G physical link, with 16 or 32 hardware queues. + +Tests showed no regression in network latency benchmarks on single +connection. + +Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1689622539-5334-2-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +(cherry picked from commit da4e8648079eb6f26f3a88d8c34270a057e2bfe6) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 7d82b8949a1e..75c1f81ce64f 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1387,8 +1387,8 @@ static void mana_post_pkt_rxq(struct mana_rxq *rxq) + + recv_buf_oob = &rxq->rx_oobs[curr_index]; + +- err = mana_gd_post_and_ring(rxq->gdma_rq, &recv_buf_oob->wqe_req, +- &recv_buf_oob->wqe_inf); ++ err = mana_gd_post_work_request(rxq->gdma_rq, &recv_buf_oob->wqe_req, ++ &recv_buf_oob->wqe_inf); + if (WARN_ON_ONCE(err)) + return; + +@@ -1660,6 +1660,12 @@ static void mana_poll_rx_cq(struct mana_cq *cq) + mana_process_rx_cqe(rxq, cq, &comp[i]); + } + ++ if (comp_read > 0) { ++ struct gdma_context *gc = rxq->gdma_rq->gdma_dev->gdma_context; ++ ++ mana_gd_wq_ring_doorbell(gc, rxq->gdma_rq); ++ } ++ + if (rxq->xdp_flush) + xdp_do_flush(); + } +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0027-net-mana-Use-the-correct-WQE-count-for-ringing-RQ-do.patch b/debian/patches/features/all/ethernet-microsoft/0027-net-mana-Use-the-correct-WQE-count-for-ringing-RQ-do.patch new file mode 100644 index 000000000..d0bb113fc --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0027-net-mana-Use-the-correct-WQE-count-for-ringing-RQ-do.patch @@ -0,0 +1,41 @@ +From ac7f97738c05e80f7de5e4ccbbf1ea82fdad956c Mon Sep 17 00:00:00 2001 +From: Long Li <longli@microsoft.com> +Date: Mon, 17 Jul 2023 12:35:39 -0700 +Subject: [PATCH 27/30] net: mana: Use the correct WQE count for ringing RQ + doorbell + +The hardware specification specifies that WQE_COUNT should set to 0 for +the Receive Queue. Although currently the hardware doesn't enforce the +check, in the future releases it may check on this value. + +Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Dexuan Cui <decui@microsoft.com> +Signed-off-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1689622539-5334-3-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +(cherry picked from commit f5e39b57124fd4715d7f0e2f841b8609b38f3e40) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/gdma_main.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index 97a1845c676a..6108a481edcb 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -300,8 +300,11 @@ static void mana_gd_ring_doorbell(struct gdma_context *gc, u32 db_index, + + void mana_gd_wq_ring_doorbell(struct gdma_context *gc, struct gdma_queue *queue) + { ++ /* Hardware Spec specifies that software client should set 0 for ++ * wqe_cnt for Receive Queues. This value is not used in Send Queues. ++ */ + mana_gd_ring_doorbell(gc, queue->gdma_dev->doorbell, queue->type, +- queue->id, queue->head * GDMA_WQE_BU_SIZE, 1); ++ queue->id, queue->head * GDMA_WQE_BU_SIZE, 0); + } + + void mana_gd_ring_cq(struct gdma_queue *cq, u8 arm_bit) +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0028-net-mana-Configure-hwc-timeout-from-hardware.patch b/debian/patches/features/all/ethernet-microsoft/0028-net-mana-Configure-hwc-timeout-from-hardware.patch new file mode 100644 index 000000000..b5c24df16 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0028-net-mana-Configure-hwc-timeout-from-hardware.patch @@ -0,0 +1,217 @@ +From 4c91517cbcdd16c2a9aee0e21066f2f1aa193ece Mon Sep 17 00:00:00 2001 +From: Souradeep Chakrabarti <schakrabarti@linux.microsoft.com> +Date: Wed, 2 Aug 2023 04:07:40 -0700 +Subject: [PATCH 28/30] net: mana: Configure hwc timeout from hardware + +At present hwc timeout value is a fixed value. This patch sets the hwc +timeout from the hardware. It now uses a new hardware capability +GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG to query and set the value +in hwc_timeout. + +Signed-off-by: Souradeep Chakrabarti <schakrabarti@linux.microsoft.com> +Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 62c1bff593b7e30041d0273b835af9fd6f5ee737) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + .../net/ethernet/microsoft/mana/gdma_main.c | 30 ++++++++++++++++++- + .../net/ethernet/microsoft/mana/hw_channel.c | 24 ++++++++++++++- + include/net/mana/gdma.h | 20 ++++++++++++- + include/net/mana/hw_channel.h | 5 ++++ + 4 files changed, 76 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index 6108a481edcb..4fa1901a2789 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -106,6 +106,25 @@ static int mana_gd_query_max_resources(struct pci_dev *pdev) + return 0; + } + ++static int mana_gd_query_hwc_timeout(struct pci_dev *pdev, u32 *timeout_val) ++{ ++ struct gdma_context *gc = pci_get_drvdata(pdev); ++ struct gdma_query_hwc_timeout_resp resp = {}; ++ struct gdma_query_hwc_timeout_req req = {}; ++ int err; ++ ++ mana_gd_init_req_hdr(&req.hdr, GDMA_QUERY_HWC_TIMEOUT, ++ sizeof(req), sizeof(resp)); ++ req.timeout_ms = *timeout_val; ++ err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); ++ if (err || resp.hdr.status) ++ return err ? err : -EPROTO; ++ ++ *timeout_val = resp.timeout_ms; ++ ++ return 0; ++} ++ + static int mana_gd_detect_devices(struct pci_dev *pdev) + { + struct gdma_context *gc = pci_get_drvdata(pdev); +@@ -883,8 +902,10 @@ int mana_gd_verify_vf_version(struct pci_dev *pdev) + struct gdma_context *gc = pci_get_drvdata(pdev); + struct gdma_verify_ver_resp resp = {}; + struct gdma_verify_ver_req req = {}; ++ struct hw_channel_context *hwc; + int err; + ++ hwc = gc->hwc.driver_data; + mana_gd_init_req_hdr(&req.hdr, GDMA_VERIFY_VF_DRIVER_VERSION, + sizeof(req), sizeof(resp)); + +@@ -911,7 +932,14 @@ int mana_gd_verify_vf_version(struct pci_dev *pdev) + err, resp.hdr.status); + return err ? err : -EPROTO; + } +- ++ if (resp.pf_cap_flags1 & GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG) { ++ err = mana_gd_query_hwc_timeout(pdev, &hwc->hwc_timeout); ++ if (err) { ++ dev_err(gc->dev, "Failed to set the hwc timeout %d\n", err); ++ return err; ++ } ++ dev_dbg(gc->dev, "set the hwc timeout to %u\n", hwc->hwc_timeout); ++ } + return 0; + } + +diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c +index 2bd1d74021f7..9d1cd3bfcf66 100644 +--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c ++++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c +@@ -174,7 +174,25 @@ static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self, + complete(&hwc->hwc_init_eqe_comp); + break; + ++ case GDMA_EQE_HWC_SOC_RECONFIG_DATA: ++ type_data.as_uint32 = event->details[0]; ++ type = type_data.type; ++ val = type_data.value; ++ ++ switch (type) { ++ case HWC_DATA_CFG_HWC_TIMEOUT: ++ hwc->hwc_timeout = val; ++ break; ++ ++ default: ++ dev_warn(hwc->dev, "Received unknown reconfig type %u\n", type); ++ break; ++ } ++ ++ break; ++ + default: ++ dev_warn(hwc->dev, "Received unknown gdma event %u\n", event->type); + /* Ignore unknown events, which should never happen. */ + break; + } +@@ -696,6 +714,7 @@ int mana_hwc_create_channel(struct gdma_context *gc) + gd->driver_data = hwc; + hwc->gdma_dev = gd; + hwc->dev = gc->dev; ++ hwc->hwc_timeout = HW_CHANNEL_WAIT_RESOURCE_TIMEOUT_MS; + + /* HWC's instance number is always 0. */ + gd->dev_id.as_uint32 = 0; +@@ -770,6 +789,8 @@ void mana_hwc_destroy_channel(struct gdma_context *gc) + hwc->gdma_dev->doorbell = INVALID_DOORBELL; + hwc->gdma_dev->pdid = INVALID_PDID; + ++ hwc->hwc_timeout = 0; ++ + kfree(hwc); + gc->hwc.driver_data = NULL; + gc->hwc.gdma_context = NULL; +@@ -825,7 +846,8 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len, + goto out; + } + +- if (!wait_for_completion_timeout(&ctx->comp_event, 30 * HZ)) { ++ if (!wait_for_completion_timeout(&ctx->comp_event, ++ (msecs_to_jiffies(hwc->hwc_timeout) * HZ))) { + dev_err(hwc->dev, "HWC: Request timed out!\n"); + err = -ETIMEDOUT; + goto out; +diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h +index b27bf852471b..102bb73c7a4f 100644 +--- a/include/net/mana/gdma.h ++++ b/include/net/mana/gdma.h +@@ -31,6 +31,7 @@ enum gdma_request_type { + GDMA_DESTROY_PD = 30, + GDMA_CREATE_MR = 31, + GDMA_DESTROY_MR = 32, ++ GDMA_QUERY_HWC_TIMEOUT = 84, /* 0x54 */ + }; + + enum gdma_queue_type { +@@ -53,6 +54,8 @@ enum gdma_eqe_type { + GDMA_EQE_HWC_INIT_EQ_ID_DB = 129, + GDMA_EQE_HWC_INIT_DATA = 130, + GDMA_EQE_HWC_INIT_DONE = 131, ++ GDMA_EQE_HWC_SOC_RECONFIG = 132, ++ GDMA_EQE_HWC_SOC_RECONFIG_DATA = 133, + }; + + enum { +@@ -529,10 +532,12 @@ enum { + * so the driver is able to reliably support features like busy_poll. + */ + #define GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX BIT(2) ++#define GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG BIT(3) + + #define GDMA_DRV_CAP_FLAGS1 \ + (GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \ +- GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX) ++ GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \ ++ GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG) + + #define GDMA_DRV_CAP_FLAGS2 0 + +@@ -642,6 +647,19 @@ struct gdma_disable_queue_req { + u32 alloc_res_id_on_creation; + }; /* HW DATA */ + ++/* GDMA_QUERY_HWC_TIMEOUT */ ++struct gdma_query_hwc_timeout_req { ++ struct gdma_req_hdr hdr; ++ u32 timeout_ms; ++ u32 reserved; ++}; ++ ++struct gdma_query_hwc_timeout_resp { ++ struct gdma_resp_hdr hdr; ++ u32 timeout_ms; ++ u32 reserved; ++}; ++ + enum atb_page_size { + ATB_PAGE_SIZE_4K, + ATB_PAGE_SIZE_8K, +diff --git a/include/net/mana/hw_channel.h b/include/net/mana/hw_channel.h +index 6a757a6e2732..3d3b5c881bc1 100644 +--- a/include/net/mana/hw_channel.h ++++ b/include/net/mana/hw_channel.h +@@ -23,6 +23,10 @@ + #define HWC_INIT_DATA_PF_DEST_RQ_ID 10 + #define HWC_INIT_DATA_PF_DEST_CQ_ID 11 + ++#define HWC_DATA_CFG_HWC_TIMEOUT 1 ++ ++#define HW_CHANNEL_WAIT_RESOURCE_TIMEOUT_MS 30000 ++ + /* Structures labeled with "HW DATA" are exchanged with the hardware. All of + * them are naturally aligned and hence don't need __packed. + */ +@@ -182,6 +186,7 @@ struct hw_channel_context { + + u32 pf_dest_vrq_id; + u32 pf_dest_vrcq_id; ++ u32 hwc_timeout; + + struct hwc_caller_ctx *caller_ctx; + }; +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0029-net-mana-Rename-mana_refill_rxoob-and-remove-some-em.patch b/debian/patches/features/all/ethernet-microsoft/0029-net-mana-Rename-mana_refill_rxoob-and-remove-some-em.patch new file mode 100644 index 000000000..a9f8249bd --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0029-net-mana-Rename-mana_refill_rxoob-and-remove-some-em.patch @@ -0,0 +1,67 @@ +From 609fba0ab4ebdde830c8c52ef0dcc2ea8f5e82fe Mon Sep 17 00:00:00 2001 +From: Haiyang Zhang <haiyangz@microsoft.com> +Date: Fri, 21 Apr 2023 10:06:57 -0700 +Subject: [PATCH 29/30] net: mana: Rename mana_refill_rxoob and remove some + empty lines + +Rename mana_refill_rxoob for naming consistency. +And remove some empty lines between function call and error +checking. + +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +(cherry picked from commit 5c74064f43c291d9add2b436a2d70205b71a7cc7) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 75c1f81ce64f..6aa273b68327 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -579,7 +579,6 @@ static int mana_pre_alloc_rxbufs(struct mana_port_context *mpc, int new_mtu) + + da = dma_map_single(dev, va + mpc->rxbpre_headroom, + mpc->rxbpre_datasize, DMA_FROM_DEVICE); +- + if (dma_mapping_error(dev, da)) { + put_page(virt_to_head_page(va)); + goto error; +@@ -1543,7 +1542,6 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev, + + *da = dma_map_single(dev, va + rxq->headroom, rxq->datasize, + DMA_FROM_DEVICE); +- + if (dma_mapping_error(dev, *da)) { + put_page(virt_to_head_page(va)); + return NULL; +@@ -1553,14 +1551,13 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev, + } + + /* Allocate frag for rx buffer, and save the old buf */ +-static void mana_refill_rxoob(struct device *dev, struct mana_rxq *rxq, +- struct mana_recv_buf_oob *rxoob, void **old_buf) ++static void mana_refill_rx_oob(struct device *dev, struct mana_rxq *rxq, ++ struct mana_recv_buf_oob *rxoob, void **old_buf) + { + dma_addr_t da; + void *va; + + va = mana_get_rxfrag(rxq, dev, &da, true); +- + if (!va) + return; + +@@ -1625,7 +1622,7 @@ static void mana_process_rx_cqe(struct mana_rxq *rxq, struct mana_cq *cq, + rxbuf_oob = &rxq->rx_oobs[curr]; + WARN_ON_ONCE(rxbuf_oob->wqe_inf.wqe_size_in_bu != 1); + +- mana_refill_rxoob(dev, rxq, rxbuf_oob, &old_buf); ++ mana_refill_rx_oob(dev, rxq, rxbuf_oob, &old_buf); + + /* Unsuccessful refill will have old_buf == NULL. + * In this case, mana_rx_skb() will drop the packet. +-- +2.40.1 + diff --git a/debian/patches/features/all/ethernet-microsoft/0030-net-mana-Add-gdma-stats-to-ethtool-output-for-mana.patch b/debian/patches/features/all/ethernet-microsoft/0030-net-mana-Add-gdma-stats-to-ethtool-output-for-mana.patch new file mode 100644 index 000000000..07caff6a9 --- /dev/null +++ b/debian/patches/features/all/ethernet-microsoft/0030-net-mana-Add-gdma-stats-to-ethtool-output-for-mana.patch @@ -0,0 +1,232 @@ +From b7a5d522d26c84055bcc410b51b8cefc64fcdbca Mon Sep 17 00:00:00 2001 +From: Shradha Gupta <shradhagupta@linux.microsoft.com> +Date: Wed, 9 Aug 2023 21:15:22 -0700 +Subject: [PATCH 30/30] net: mana: Add gdma stats to ethtool output for mana + +Extended performance counter stats in 'ethtool -S <interface>' +for MANA VF to include GDMA tx LSO packets and bytes count. + +Tested-on: Ubuntu22 +Testcases: +1. LISA testcase: +PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-Synthetic +2. LISA testcase: +PERF-NETWORK-TCP-THROUGHPUT-MULTICONNECTION-NTTTCP-SRIOV +3. Validated the GDMA stat packets and byte counters +Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com> +Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit ac3899c6229649737b9d5cb86e417c98243883dc) +Signed-off-by: Bastian Blank <waldi@debian.org> +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 40 +++++++++ + .../ethernet/microsoft/mana/mana_ethtool.c | 15 ++++ + include/net/mana/mana.h | 87 +++++++++++++++++++ + 3 files changed, 142 insertions(+) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 6aa273b68327..a006bd69b26e 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -2234,6 +2234,46 @@ int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx, + return 0; + } + ++void mana_query_gf_stats(struct mana_port_context *apc) ++{ ++ struct mana_query_gf_stat_resp resp = {}; ++ struct mana_query_gf_stat_req req = {}; ++ struct net_device *ndev = apc->ndev; ++ int err; ++ ++ mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_GF_STAT, ++ sizeof(req), sizeof(resp)); ++ req.req_stats = STATISTICS_FLAGS_HC_TX_BYTES | ++ STATISTICS_FLAGS_HC_TX_UCAST_PACKETS | ++ STATISTICS_FLAGS_HC_TX_UCAST_BYTES | ++ STATISTICS_FLAGS_HC_TX_MCAST_PACKETS | ++ STATISTICS_FLAGS_HC_TX_MCAST_BYTES | ++ STATISTICS_FLAGS_HC_TX_BCAST_PACKETS | ++ STATISTICS_FLAGS_HC_TX_BCAST_BYTES; ++ ++ err = mana_send_request(apc->ac, &req, sizeof(req), &resp, ++ sizeof(resp)); ++ if (err) { ++ netdev_err(ndev, "Failed to query GF stats: %d\n", err); ++ return; ++ } ++ err = mana_verify_resp_hdr(&resp.hdr, MANA_QUERY_GF_STAT, ++ sizeof(resp)); ++ if (err || resp.hdr.status) { ++ netdev_err(ndev, "Failed to query GF stats: %d, 0x%x\n", err, ++ resp.hdr.status); ++ return; ++ } ++ ++ apc->eth_stats.hc_tx_bytes = resp.hc_tx_bytes; ++ apc->eth_stats.hc_tx_ucast_pkts = resp.hc_tx_ucast_pkts; ++ apc->eth_stats.hc_tx_ucast_bytes = resp.hc_tx_ucast_bytes; ++ apc->eth_stats.hc_tx_bcast_pkts = resp.hc_tx_bcast_pkts; ++ apc->eth_stats.hc_tx_bcast_bytes = resp.hc_tx_bcast_bytes; ++ apc->eth_stats.hc_tx_mcast_pkts = resp.hc_tx_mcast_pkts; ++ apc->eth_stats.hc_tx_mcast_bytes = resp.hc_tx_mcast_bytes; ++} ++ + static int mana_init_port(struct net_device *ndev) + { + struct mana_port_context *apc = netdev_priv(ndev); +diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +index 0dc78679f620..607150165ab4 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +@@ -13,6 +13,19 @@ static const struct { + } mana_eth_stats[] = { + {"stop_queue", offsetof(struct mana_ethtool_stats, stop_queue)}, + {"wake_queue", offsetof(struct mana_ethtool_stats, wake_queue)}, ++ {"hc_tx_bytes", offsetof(struct mana_ethtool_stats, hc_tx_bytes)}, ++ {"hc_tx_ucast_pkts", offsetof(struct mana_ethtool_stats, ++ hc_tx_ucast_pkts)}, ++ {"hc_tx_ucast_bytes", offsetof(struct mana_ethtool_stats, ++ hc_tx_ucast_bytes)}, ++ {"hc_tx_bcast_pkts", offsetof(struct mana_ethtool_stats, ++ hc_tx_bcast_pkts)}, ++ {"hc_tx_bcast_bytes", offsetof(struct mana_ethtool_stats, ++ hc_tx_bcast_bytes)}, ++ {"hc_tx_mcast_pkts", offsetof(struct mana_ethtool_stats, ++ hc_tx_mcast_pkts)}, ++ {"hc_tx_mcast_bytes", offsetof(struct mana_ethtool_stats, ++ hc_tx_mcast_bytes)}, + {"tx_cq_err", offsetof(struct mana_ethtool_stats, tx_cqe_err)}, + {"tx_cqe_unknown_type", offsetof(struct mana_ethtool_stats, + tx_cqe_unknown_type)}, +@@ -114,6 +127,8 @@ static void mana_get_ethtool_stats(struct net_device *ndev, + + if (!apc->port_is_up) + return; ++ /* we call mana function to update stats from GDMA */ ++ mana_query_gf_stats(apc); + + for (q = 0; q < ARRAY_SIZE(mana_eth_stats); q++) + data[i++] = *(u64 *)(eth_stats + mana_eth_stats[q].offset); +diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h +index 46b5769a5b6a..cc4502db2ced 100644 +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -347,6 +347,13 @@ struct mana_tx_qp { + struct mana_ethtool_stats { + u64 stop_queue; + u64 wake_queue; ++ u64 hc_tx_bytes; ++ u64 hc_tx_ucast_pkts; ++ u64 hc_tx_ucast_bytes; ++ u64 hc_tx_bcast_pkts; ++ u64 hc_tx_bcast_bytes; ++ u64 hc_tx_mcast_pkts; ++ u64 hc_tx_mcast_bytes; + u64 tx_cqe_err; + u64 tx_cqe_unknown_type; + u64 rx_coalesced_err; +@@ -437,6 +444,7 @@ u32 mana_run_xdp(struct net_device *ndev, struct mana_rxq *rxq, + struct bpf_prog *mana_xdp_get(struct mana_port_context *apc); + void mana_chn_setxdp(struct mana_port_context *apc, struct bpf_prog *prog); + int mana_bpf(struct net_device *ndev, struct netdev_bpf *bpf); ++void mana_query_gf_stats(struct mana_port_context *apc); + + extern const struct ethtool_ops mana_ethtool_ops; + +@@ -575,6 +583,49 @@ struct mana_fence_rq_resp { + struct gdma_resp_hdr hdr; + }; /* HW DATA */ + ++/* Query stats RQ */ ++struct mana_query_gf_stat_req { ++ struct gdma_req_hdr hdr; ++ u64 req_stats; ++}; /* HW DATA */ ++ ++struct mana_query_gf_stat_resp { ++ struct gdma_resp_hdr hdr; ++ u64 reported_stats; ++ /* rx errors/discards */ ++ u64 discard_rx_nowqe; ++ u64 err_rx_vport_disabled; ++ /* rx bytes/packets */ ++ u64 hc_rx_bytes; ++ u64 hc_rx_ucast_pkts; ++ u64 hc_rx_ucast_bytes; ++ u64 hc_rx_bcast_pkts; ++ u64 hc_rx_bcast_bytes; ++ u64 hc_rx_mcast_pkts; ++ u64 hc_rx_mcast_bytes; ++ /* tx errors */ ++ u64 err_tx_gf_disabled; ++ u64 err_tx_vport_disabled; ++ u64 err_tx_inval_vport_offset_pkt; ++ u64 err_tx_vlan_enforcement; ++ u64 err_tx_ethtype_enforcement; ++ u64 err_tx_SA_enforecement; ++ u64 err_tx_SQPDID_enforcement; ++ u64 err_tx_CQPDID_enforcement; ++ u64 err_tx_mtu_violation; ++ u64 err_tx_inval_oob; ++ /* tx bytes/packets */ ++ u64 hc_tx_bytes; ++ u64 hc_tx_ucast_pkts; ++ u64 hc_tx_ucast_bytes; ++ u64 hc_tx_bcast_pkts; ++ u64 hc_tx_bcast_bytes; ++ u64 hc_tx_mcast_pkts; ++ u64 hc_tx_mcast_bytes; ++ /* tx error */ ++ u64 err_tx_gdma; ++}; /* HW DATA */ ++ + /* Configure vPort Rx Steering */ + struct mana_cfg_rx_steer_req_v2 { + struct gdma_req_hdr hdr; +@@ -654,6 +705,42 @@ struct mana_deregister_filter_resp { + struct gdma_resp_hdr hdr; + }; /* HW DATA */ + ++/* Requested GF stats Flags */ ++/* Rx discards/Errors */ ++#define STATISTICS_FLAGS_RX_DISCARDS_NO_WQE 0x0000000000000001 ++#define STATISTICS_FLAGS_RX_ERRORS_VPORT_DISABLED 0x0000000000000002 ++/* Rx bytes/pkts */ ++#define STATISTICS_FLAGS_HC_RX_BYTES 0x0000000000000004 ++#define STATISTICS_FLAGS_HC_RX_UCAST_PACKETS 0x0000000000000008 ++#define STATISTICS_FLAGS_HC_RX_UCAST_BYTES 0x0000000000000010 ++#define STATISTICS_FLAGS_HC_RX_MCAST_PACKETS 0x0000000000000020 ++#define STATISTICS_FLAGS_HC_RX_MCAST_BYTES 0x0000000000000040 ++#define STATISTICS_FLAGS_HC_RX_BCAST_PACKETS 0x0000000000000080 ++#define STATISTICS_FLAGS_HC_RX_BCAST_BYTES 0x0000000000000100 ++/* Tx errors */ ++#define STATISTICS_FLAGS_TX_ERRORS_GF_DISABLED 0x0000000000000200 ++#define STATISTICS_FLAGS_TX_ERRORS_VPORT_DISABLED 0x0000000000000400 ++#define STATISTICS_FLAGS_TX_ERRORS_INVAL_VPORT_OFFSET_PACKETS \ ++ 0x0000000000000800 ++#define STATISTICS_FLAGS_TX_ERRORS_VLAN_ENFORCEMENT 0x0000000000001000 ++#define STATISTICS_FLAGS_TX_ERRORS_ETH_TYPE_ENFORCEMENT \ ++ 0x0000000000002000 ++#define STATISTICS_FLAGS_TX_ERRORS_SA_ENFORCEMENT 0x0000000000004000 ++#define STATISTICS_FLAGS_TX_ERRORS_SQPDID_ENFORCEMENT 0x0000000000008000 ++#define STATISTICS_FLAGS_TX_ERRORS_CQPDID_ENFORCEMENT 0x0000000000010000 ++#define STATISTICS_FLAGS_TX_ERRORS_MTU_VIOLATION 0x0000000000020000 ++#define STATISTICS_FLAGS_TX_ERRORS_INVALID_OOB 0x0000000000040000 ++/* Tx bytes/pkts */ ++#define STATISTICS_FLAGS_HC_TX_BYTES 0x0000000000080000 ++#define STATISTICS_FLAGS_HC_TX_UCAST_PACKETS 0x0000000000100000 ++#define STATISTICS_FLAGS_HC_TX_UCAST_BYTES 0x0000000000200000 ++#define STATISTICS_FLAGS_HC_TX_MCAST_PACKETS 0x0000000000400000 ++#define STATISTICS_FLAGS_HC_TX_MCAST_BYTES 0x0000000000800000 ++#define STATISTICS_FLAGS_HC_TX_BCAST_PACKETS 0x0000000001000000 ++#define STATISTICS_FLAGS_HC_TX_BCAST_BYTES 0x0000000002000000 ++/* Tx error */ ++#define STATISTICS_FLAGS_TX_ERRORS_GDMA_ERROR 0x0000000004000000 ++ + #define MANA_MAX_NUM_QUEUES 64 + + #define MANA_SHORT_VPORT_OFFSET_MAX ((1U << 8) - 1) +-- +2.40.1 + diff --git a/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch b/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch new file mode 100644 index 000000000..6f1ba8e5a --- /dev/null +++ b/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch @@ -0,0 +1,153 @@ +From: Linn Crosetto <linn@hpe.com> +Date: Tue, 30 Aug 2016 11:54:38 -0600 +Subject: arm64: add kernel config option to lock down when in Secure Boot mode +Bug-Debian: https://bugs.debian.org/831827 +Forwarded: no + +Add a kernel configuration option to lock down the kernel, to restrict +userspace's ability to modify the running kernel when UEFI Secure Boot is +enabled. Based on the x86 patch by Matthew Garrett. + +Determine the state of Secure Boot in the EFI stub and pass this to the +kernel using the FDT. + +Signed-off-by: Linn Crosetto <linn@hpe.com> +[bwh: Forward-ported to 4.10: adjust context] +[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream] +[bwh: Forward-ported to 4.15 and lockdown patch set: + - Pass result of efi_get_secureboot() in stub through to + efi_set_secure_boot() in main kernel + - Use lockdown API and naming] +[bwh: Forward-ported to 4.19.3: adjust context in update_fdt()] +[dannf: Moved init_lockdown() call after uefi_init(), fixing SB detection] +[bwh: Drop call to init_lockdown(), as efi_set_secure_boot() now calls this] +[bwh: Forward-ported to 5.6: efi_get_secureboot() no longer takes a + sys_table parameter] +[bwh: Forward-ported to 5.7: EFI initialisation from FDT was rewritten, so: + - Add Secure Boot mode to the parameter enumeration in fdtparams.c + - Add a parameter to efi_get_fdt_params() to return the Secure Boot mode + - Since Xen does not have a property name defined for Secure Boot mode, + change efi_get_fdt_prop() to handle a missing property name by clearing + the output variable] +[Salvatore Bonaccorso: Forward-ported to 5.10: f30f242fb131 ("efi: Rename +arm-init to efi-init common for all arch") renamed arm-init.c to efi-init.c] +--- + drivers/firmware/efi/efi-init.c | 5 ++++- + drivers/firmware/efi/fdtparams.c | 12 +++++++++++- + drivers/firmware/efi/libstub/fdt.c | 6 ++++++ + include/linux/efi.h | 3 ++- + 4 files changed, 23 insertions(+), 3 deletions(-) + +--- a/drivers/firmware/efi/efi-init.c ++++ b/drivers/firmware/efi/efi-init.c +@@ -210,9 +210,10 @@ void __init efi_init(void) + { + struct efi_memory_map_data data; + u64 efi_system_table; ++ u32 secure_boot; + + /* Grab UEFI information placed in FDT by stub */ +- efi_system_table = efi_get_fdt_params(&data); ++ efi_system_table = efi_get_fdt_params(&data, &secure_boot); + if (!efi_system_table) + return; + +@@ -234,6 +235,8 @@ void __init efi_init(void) + return; + } + ++ efi_set_secure_boot(secure_boot); ++ + reserve_regions(); + /* + * For memblock manipulation, the cap should come after the memblock_add(). +--- a/drivers/firmware/efi/fdtparams.c ++++ b/drivers/firmware/efi/fdtparams.c +@@ -16,6 +16,7 @@ enum { + MMSIZE, + DCSIZE, + DCVERS, ++ SBMODE, + + PARAMCOUNT + }; +@@ -26,6 +27,7 @@ static __initconst const char name[][22] + [MMSIZE] = "MemMap Size ", + [DCSIZE] = "MemMap Desc. Size ", + [DCVERS] = "MemMap Desc. Version ", ++ [SBMODE] = "Secure Boot Enabled ", + }; + + static __initconst const struct { +@@ -41,6 +43,7 @@ static __initconst const struct { + [MMSIZE] = "xen,uefi-mmap-size", + [DCSIZE] = "xen,uefi-mmap-desc-size", + [DCVERS] = "xen,uefi-mmap-desc-ver", ++ [SBMODE] = "", + } + }, { + #endif +@@ -51,6 +54,7 @@ static __initconst const struct { + [MMSIZE] = "linux,uefi-mmap-size", + [DCSIZE] = "linux,uefi-mmap-desc-size", + [DCVERS] = "linux,uefi-mmap-desc-ver", ++ [SBMODE] = "linux,uefi-secure-boot", + } + } + }; +@@ -62,6 +66,11 @@ static int __init efi_get_fdt_prop(const + int len; + u64 val; + ++ if (!pname[0]) { ++ memset(var, 0, size); ++ return 0; ++ } ++ + prop = fdt_getprop(fdt, node, pname, &len); + if (!prop) + return 1; +@@ -79,7 +88,7 @@ static int __init efi_get_fdt_prop(const + return 0; + } + +-u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) ++u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm, u32 *secure_boot) + { + const void *fdt = initial_boot_params; + unsigned long systab; +@@ -93,6 +102,7 @@ u64 __init efi_get_fdt_params(struct efi + [MMSIZE] = { &mm->size, sizeof(mm->size) }, + [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, + [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, ++ [SBMODE] = { secure_boot, sizeof(*secure_boot) }, + }; + + BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); +--- a/drivers/firmware/efi/libstub/fdt.c ++++ b/drivers/firmware/efi/libstub/fdt.c +@@ -148,6 +148,12 @@ static efi_status_t update_fdt(void *ori + } + } + ++ fdt_val32 = cpu_to_fdt32(efi_get_secureboot()); ++ status = fdt_setprop(fdt, node, "linux,uefi-secure-boot", ++ &fdt_val32, sizeof(fdt_val32)); ++ if (status) ++ goto fdt_set_fail; ++ + /* Shrink the FDT back to its minimum size: */ + fdt_pack(fdt); + +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -662,7 +662,8 @@ extern void efi_mem_reserve(phys_addr_t + extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size); + extern void efi_initialize_iomem_resources(struct resource *code_resource, + struct resource *data_resource, struct resource *bss_resource); +-extern u64 efi_get_fdt_params(struct efi_memory_map_data *data); ++extern u64 efi_get_fdt_params(struct efi_memory_map_data *data, ++ u32 *secure_boot); + extern struct kobject *efi_kobj; + + extern int efi_reboot_quirk_mode; diff --git a/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch b/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch new file mode 100644 index 000000000..b46698757 --- /dev/null +++ b/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch @@ -0,0 +1,153 @@ +From: David Howells <dhowells@redhat.com> +Date: Mon, 18 Feb 2019 12:45:03 +0000 +Subject: [28/30] efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a5d70c55c603233c192b375f72116a395909da28 + +UEFI machines can be booted in Secure Boot mode. Add an EFI_SECURE_BOOT +flag that can be passed to efi_enabled() to find out whether secure boot is +enabled. + +Move the switch-statement in x86's setup_arch() that inteprets the +secure_boot boot parameter to generic code and set the bit there. + +Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +cc: linux-efi@vger.kernel.org +[rperier: Forward-ported to 5.5: + - Use pr_warn() + - Adjust context] +[bwh: Forward-ported to 5.6: adjust context] +[bwh: Forward-ported to 5.7: + - Use the next available bit in efi.flags + - Adjust context] +--- + arch/x86/kernel/setup.c | 14 +---------- + drivers/firmware/efi/Makefile | 1 + + drivers/firmware/efi/secureboot.c | 39 +++++++++++++++++++++++++++++++ + include/linux/efi.h | 16 ++++++++----- + 4 files changed, 51 insertions(+), 19 deletions(-) + create mode 100644 drivers/firmware/efi/secureboot.c + +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1205,19 +1205,7 @@ void __init setup_arch(char **cmdline_p) + /* Allocate bigger log buffer */ + setup_log_buf(1); + +- if (efi_enabled(EFI_BOOT)) { +- switch (boot_params.secure_boot) { +- case efi_secureboot_mode_disabled: +- pr_info("Secure boot disabled\n"); +- break; +- case efi_secureboot_mode_enabled: +- pr_info("Secure boot enabled\n"); +- break; +- default: +- pr_info("Secure boot could not be determined\n"); +- break; +- } +- } ++ efi_set_secure_boot(boot_params.secure_boot); + + reserve_initrd(); + +--- a/drivers/firmware/efi/Makefile ++++ b/drivers/firmware/efi/Makefile +@@ -27,6 +27,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_m + obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o + obj-$(CONFIG_EFI_TEST) += test/ + obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o ++obj-$(CONFIG_EFI) += secureboot.o + obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o + obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o + obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o +--- /dev/null ++++ b/drivers/firmware/efi/secureboot.c +@@ -0,0 +1,39 @@ ++ ++/* Core kernel secure boot support. ++ * ++ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include <linux/efi.h> ++#include <linux/kernel.h> ++#include <linux/printk.h> ++ ++/* ++ * Decide what to do when UEFI secure boot mode is enabled. ++ */ ++void __init efi_set_secure_boot(enum efi_secureboot_mode mode) ++{ ++ if (efi_enabled(EFI_BOOT)) { ++ switch (mode) { ++ case efi_secureboot_mode_disabled: ++ pr_info("Secure boot disabled\n"); ++ break; ++ case efi_secureboot_mode_enabled: ++ set_bit(EFI_SECURE_BOOT, &efi.flags); ++ pr_info("Secure boot enabled\n"); ++ break; ++ default: ++ pr_warn("Secure boot could not be determined (mode %u)\n", ++ mode); ++ break; ++ } ++ } ++} +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -849,6 +849,14 @@ extern int __init efi_setup_pcdp_console + #define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */ + #define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */ + #define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */ ++#define EFI_SECURE_BOOT 13 /* Are we in Secure Boot mode? */ ++ ++enum efi_secureboot_mode { ++ efi_secureboot_mode_unset, ++ efi_secureboot_mode_unknown, ++ efi_secureboot_mode_disabled, ++ efi_secureboot_mode_enabled, ++}; + + #ifdef CONFIG_EFI + /* +@@ -873,6 +881,7 @@ static inline bool efi_rt_services_suppo + return (efi.runtime_supported_mask & mask) == mask; + } + extern void efi_find_mirror(void); ++extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode); + #else + static inline bool efi_enabled(int feature) + { +@@ -892,6 +901,7 @@ static inline bool efi_rt_services_suppo + } + + static inline void efi_find_mirror(void) {} ++static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {} + #endif + + extern int efi_status_to_err(efi_status_t status); +@@ -1107,13 +1117,6 @@ static inline bool efi_runtime_disabled( + extern void efi_call_virt_check_flags(unsigned long flags, const char *call); + extern unsigned long efi_call_virt_save_flags(void); + +-enum efi_secureboot_mode { +- efi_secureboot_mode_unset, +- efi_secureboot_mode_unknown, +- efi_secureboot_mode_disabled, +- efi_secureboot_mode_enabled, +-}; +- + static inline + enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var) + { diff --git a/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch b/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch new file mode 100644 index 000000000..9ec425871 --- /dev/null +++ b/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch @@ -0,0 +1,131 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 10 Sep 2019 11:54:28 +0100 +Subject: efi: Lock down the kernel if booted in secure boot mode + +Based on an earlier patch by David Howells, who wrote the following +description: + +> UEFI Secure Boot provides a mechanism for ensuring that the firmware will +> only load signed bootloaders and kernels. Certain use cases may also +> require that all kernel modules also be signed. Add a configuration option +> that to lock down the kernel - which includes requiring validly signed +> modules - if the kernel is secure-booted. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +[Salvatore Bonaccorso: After fixing https://bugs.debian.org/956197 the +help text for LOCK_DOWN_IN_EFI_SECURE_BOOT needs to be adjusted to +mention that lockdown is triggered in integrity mode] +Signed-off-by: Salvatore Bonaccorso <carnil@debian.org> +--- + arch/x86/kernel/setup.c | 4 ++-- + drivers/firmware/efi/secureboot.c | 3 +++ + include/linux/security.h | 6 ++++++ + security/lockdown/Kconfig | 15 +++++++++++++++ + security/lockdown/lockdown.c | 2 +- + 5 files changed, 27 insertions(+), 3 deletions(-) + +Index: debian-kernel/arch/x86/kernel/setup.c +=================================================================== +--- debian-kernel.orig/arch/x86/kernel/setup.c ++++ debian-kernel/arch/x86/kernel/setup.c +@@ -979,6 +979,8 @@ void __init setup_arch(char **cmdline_p) + if (efi_enabled(EFI_BOOT)) + efi_init(); + ++ efi_set_secure_boot(boot_params.secure_boot); ++ + dmi_setup(); + + /* +@@ -1130,8 +1132,6 @@ void __init setup_arch(char **cmdline_p) + /* Allocate bigger log buffer */ + setup_log_buf(1); + +- efi_set_secure_boot(boot_params.secure_boot); +- + reserve_initrd(); + + acpi_table_upgrade(); +Index: debian-kernel/drivers/firmware/efi/secureboot.c +=================================================================== +--- debian-kernel.orig/drivers/firmware/efi/secureboot.c ++++ debian-kernel/drivers/firmware/efi/secureboot.c +@@ -15,6 +15,7 @@ + #include <linux/efi.h> + #include <linux/kernel.h> + #include <linux/printk.h> ++#include <linux/security.h> + + /* + * Decide what to do when UEFI secure boot mode is enabled. +@@ -28,6 +29,10 @@ void __init efi_set_secure_boot(enum efi + break; + case efi_secureboot_mode_enabled: + set_bit(EFI_SECURE_BOOT, &efi.flags); ++#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT ++ lock_kernel_down("EFI Secure Boot", ++ LOCKDOWN_INTEGRITY_MAX); ++#endif + pr_info("Secure boot enabled\n"); + break; + default: +Index: debian-kernel/include/linux/security.h +=================================================================== +--- debian-kernel.orig/include/linux/security.h ++++ debian-kernel/include/linux/security.h +@@ -451,6 +451,7 @@ int security_inode_notifysecctx(struct i + int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); + int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); + int security_locked_down(enum lockdown_reason what); ++int lock_kernel_down(const char *where, enum lockdown_reason level); + #else /* CONFIG_SECURITY */ + + static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data) +@@ -1291,6 +1292,11 @@ static inline int security_locked_down(e + { + return 0; + } ++static inline int ++lock_kernel_down(const char *where, enum lockdown_reason level) ++{ ++ return -EOPNOTSUPP; ++} + #endif /* CONFIG_SECURITY */ + + #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE) +Index: debian-kernel/security/lockdown/Kconfig +=================================================================== +--- debian-kernel.orig/security/lockdown/Kconfig ++++ debian-kernel/security/lockdown/Kconfig +@@ -45,3 +45,18 @@ config LOCK_DOWN_KERNEL_FORCE_CONFIDENTI + disabled. + + endchoice ++ ++config LOCK_DOWN_IN_EFI_SECURE_BOOT ++ bool "Lock down the kernel in EFI Secure Boot mode" ++ default n ++ depends on SECURITY_LOCKDOWN_LSM ++ depends on EFI ++ select SECURITY_LOCKDOWN_LSM_EARLY ++ help ++ UEFI Secure Boot provides a mechanism for ensuring that the firmware ++ will only load signed bootloaders and kernels. Secure boot mode may ++ be determined from EFI variables provided by the system firmware if ++ not indicated by the boot parameters. ++ ++ Enabling this option results in kernel lockdown being ++ triggered in integrity mode if EFI Secure Boot is set. +Index: debian-kernel/security/lockdown/lockdown.c +=================================================================== +--- debian-kernel.orig/security/lockdown/lockdown.c ++++ debian-kernel/security/lockdown/lockdown.c +@@ -23,7 +23,7 @@ static const enum lockdown_reason lockdo + /* + * Put the kernel into lock-down mode. + */ +-static int lock_kernel_down(const char *where, enum lockdown_reason level) ++int lock_kernel_down(const char *where, enum lockdown_reason level) + { + if (kernel_locked_down >= level) + return -EPERM; diff --git a/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch b/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch new file mode 100644 index 000000000..c718e7e2f --- /dev/null +++ b/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch @@ -0,0 +1,75 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 30 Aug 2019 15:54:24 +0100 +Subject: mtd: phram,slram: Disable when the kernel is locked down +Forwarded: https://lore.kernel.org/linux-security-module/20190830154720.eekfjt6c4jzvlbfz@decadent.org.uk/ + +These drivers allow mapping arbitrary memory ranges as MTD devices. +This should be disabled to preserve the kernel's integrity when it is +locked down. + +* Add the HWPARAM flag to the module parameters +* When slram is built-in, it uses __setup() to read kernel parameters, + so add an explicit check security_locked_down() check + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +Cc: Matthew Garrett <mjg59@google.com> +Cc: David Howells <dhowells@redhat.com> +Cc: Joern Engel <joern@lazybastard.org> +Cc: linux-mtd@lists.infradead.org +--- + drivers/mtd/devices/phram.c | 6 +++++- + drivers/mtd/devices/slram.c | 9 ++++++++- + 2 files changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/devices/phram.c ++++ b/drivers/mtd/devices/phram.c +@@ -364,7 +364,11 @@ static int phram_param_call(const char * + #endif + } + +-module_param_call(phram, phram_param_call, NULL, NULL, 0200); ++static const struct kernel_param_ops phram_param_ops = { ++ .set = phram_param_call ++}; ++__module_param_call(MODULE_PARAM_PREFIX, phram, &phram_param_ops, NULL, ++ 0200, -1, KERNEL_PARAM_FL_HWPARAM | hwparam_iomem); + MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>[,<erasesize>]\""); + + #ifdef CONFIG_OF +--- a/drivers/mtd/devices/slram.c ++++ b/drivers/mtd/devices/slram.c +@@ -43,6 +43,7 @@ + #include <linux/ioctl.h> + #include <linux/init.h> + #include <linux/io.h> ++#include <linux/security.h> + + #include <linux/mtd/mtd.h> + +@@ -65,7 +66,7 @@ typedef struct slram_mtd_list { + #ifdef MODULE + static char *map[SLRAM_MAX_DEVICES_PARAMS]; + +-module_param_array(map, charp, NULL, 0); ++module_param_hw_array(map, charp, iomem, NULL, 0); + MODULE_PARM_DESC(map, "List of memory regions to map. \"map=<name>, <start>, <length / end>\""); + #else + static char *map; +@@ -281,11 +282,17 @@ static int __init init_slram(void) + #ifndef MODULE + char *devstart; + char *devlength; ++ int ret; + + if (!map) { + E("slram: not enough parameters.\n"); + return(-EINVAL); + } ++ ++ ret = security_locked_down(LOCKDOWN_MODULE_PARAMETERS); ++ if (ret) ++ return ret; ++ + while (map) { + devname = devstart = devlength = NULL; + diff --git a/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch b/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch new file mode 100644 index 000000000..e58668ebe --- /dev/null +++ b/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch @@ -0,0 +1,80 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 11 Jan 2016 15:23:55 +0000 +Subject: security,perf: Allow further restriction of perf_event_open +Forwarded: https://lkml.org/lkml/2016/1/11/587 + +When kernel.perf_event_open is set to 3 (or greater), disallow all +access to performance events by users without CAP_SYS_ADMIN. +Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that +makes this value the default. + +This is based on a similar feature in grsecurity +(CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making +the variable read-only. It also allows enabling further restriction +at run-time regardless of whether the default is changed. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/perf_event.h | 5 +++++ + kernel/events/core.c | 8 ++++++++ + security/Kconfig | 9 +++++++++ + 3 files changed, 22 insertions(+) + +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1387,6 +1387,11 @@ int perf_cpu_time_max_percent_handler(st + int perf_event_max_stack_handler(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos); + ++static inline bool perf_paranoid_any(void) ++{ ++ return sysctl_perf_event_paranoid > 2; ++} ++ + /* Access to perf_event_open(2) syscall. */ + #define PERF_SECURITY_OPEN 0 + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -415,8 +415,13 @@ static struct kmem_cache *perf_event_cac + * 0 - disallow raw tracepoint access for unpriv + * 1 - disallow cpu events for unpriv + * 2 - disallow kernel profiling for unpriv ++ * 3 - disallow all unpriv perf event use + */ ++#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT ++int sysctl_perf_event_paranoid __read_mostly = 3; ++#else + int sysctl_perf_event_paranoid __read_mostly = 2; ++#endif + + /* Minimum for 512 kiB + 1 user control page */ + int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ +@@ -12235,6 +12240,9 @@ SYSCALL_DEFINE5(perf_event_open, + if (err) + return err; + ++ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) ++ return -EACCES; ++ + /* Do we allow access to perf_event_open(2) ? */ + err = security_perf_event_open(&attr, PERF_SECURITY_OPEN); + if (err) +--- a/security/Kconfig ++++ b/security/Kconfig +@@ -19,6 +19,15 @@ config SECURITY_DMESG_RESTRICT + + If you are unsure how to answer this question, answer N. + ++config SECURITY_PERF_EVENTS_RESTRICT ++ bool "Restrict unprivileged use of performance events" ++ depends on PERF_EVENTS ++ help ++ If you say Y here, the kernel.perf_event_paranoid sysctl ++ will be set to 3 by default, and no unprivileged use of the ++ perf_event_open syscall will be permitted unless it is ++ changed. ++ + config SECURITY + bool "Enable different security models" + depends on SYSFS diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-Hardkernel-ODROID-M1-board.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-Hardkernel-ODROID-M1-board.patch new file mode 100644 index 000000000..18b3218ee --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-Hardkernel-ODROID-M1-board.patch @@ -0,0 +1,454 @@ +From: Dongjin Kim <tobetter@gmail.com> +Date: Fri, 30 Sep 2022 07:12:35 +0200 +Subject: [02/13] arm64: dts: rockchip: Add Hardkernel ODROID-M1 board +Origin: https://git.kernel.org/linus/fd35832677032980df230f02509d6c016664cc89 + +This patch is to add a device tree for new board Hardkernel ODROID-M1 +based on Rockchip RK3568, includes basic peripherals - +uart/eMMC/uSD/i2c and on-board ethernet. + +Signed-off-by: Dongjin Kim <tobetter@gmail.com> +[aurelien@aurel32.net: addressed issues from initial review] +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-3-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../boot/dts/rockchip/rk3568-odroid-m1.dts | 414 ++++++++++++++++++ + 2 files changed, 415 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index a5a6262936f0..68cc720a623a 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -72,4 +72,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-odroid-m1.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +new file mode 100644 +index 000000000000..b3016437640b +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -0,0 +1,414 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2022 Hardkernel Co., Ltd. ++ * ++ */ ++ ++/dts-v1/; ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/leds/common.h> ++#include <dt-bindings/pinctrl/rockchip.h> ++#include "rk3568.dtsi" ++ ++/ { ++ model = "Hardkernel ODROID-M1"; ++ compatible = "rockchip,rk3568-odroid-m1", "rockchip,rk3568"; ++ ++ aliases { ++ ethernet0 = &gmac0; ++ i2c0 = &i2c3; ++ i2c3 = &i2c0; ++ mmc0 = &sdhci; ++ mmc1 = &sdmmc0; ++ serial0 = &uart1; ++ serial1 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ dc_12v: dc-12v-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "dc_12v"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_power: led-0 { ++ gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>; ++ function = LED_FUNCTION_POWER; ++ color = <LED_COLOR_ID_RED>; ++ default-state = "keep"; ++ linux,default-trigger = "default-on"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_power_pin>; ++ }; ++ led_work: led-1 { ++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; ++ function = LED_FUNCTION_HEARTBEAT; ++ color = <LED_COLOR_ID_BLUE>; ++ linux,default-trigger = "heartbeat"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_work_pin>; ++ }; ++ }; ++ ++ vcc3v3_sys: vcc3v3-sys-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&dc_12v>; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_cpu>; ++}; ++ ++&gmac0 { ++ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; ++ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>; ++ assigned-clock-rates = <0>, <125000000>; ++ clock_in_out = "output"; ++ phy-handle = <&rgmii_phy0>; ++ phy-mode = "rgmii"; ++ phy-supply = <&vcc3v3_sys>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac0_miim ++ &gmac0_tx_bus2 ++ &gmac0_rx_bus2 ++ &gmac0_rgmii_clk ++ &gmac0_rgmii_bus>; ++ status = "okay"; ++ ++ tx_delay = <0x4f>; ++ rx_delay = <0x2d>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ vdd_cpu: regulator@1c { ++ compatible = "tcs,tcs4525"; ++ reg = <0x1c>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-name = "vdd_cpu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-ramp-delay = <2300>; ++ vin-supply = <&vcc3v3_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk809: pmic@20 { ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ wakeup-source; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-init-microvolt = <900000>; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: DCDC_REG2 { ++ regulator-name = "vdd_gpu"; ++ regulator-always-on; ++ regulator-init-microvolt = <900000>; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-initial-mode = <0x2>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_npu: DCDC_REG4 { ++ regulator-name = "vdd_npu"; ++ regulator-init-microvolt = <900000>; ++ regulator-initial-mode = <0x2>; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG5 { ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_image: LDO_REG1 { ++ regulator-name = "vdda0v9_image"; ++ regulator-always-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda_0v9: LDO_REG2 { ++ regulator-name = "vdda_0v9"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdda0v9_pmu: LDO_REG3 { ++ regulator-name = "vdda0v9_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ }; ++ ++ vccio_acodec: LDO_REG4 { ++ regulator-name = "vccio_acodec"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_pmu: LDO_REG6 { ++ regulator-name = "vcc3v3_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG7 { ++ regulator-name = "vcca_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca1v8_pmu: LDO_REG8 { ++ regulator-name = "vcca1v8_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcca1v8_image: LDO_REG9 { ++ regulator-name = "vcca1v8_image"; ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: SWITCH_REG1 { ++ regulator-name = "vcc_3v3"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_sd: SWITCH_REG2 { ++ regulator-name = "vcc3v3_sd"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&mdio0 { ++ rgmii_phy0: ethernet-phy@0 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x0>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&pinctrl { ++ leds { ++ led_power_pin: led-power-pin { ++ rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ led_work_pin: led-work-pin { ++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc3v3_pmu>; ++ pmuio2-supply = <&vcc3v3_pmu>; ++ vccio1-supply = <&vccio_acodec>; ++ vccio2-supply = <&vcc_1v8>; ++ vccio3-supply = <&vccio_sd>; ++ vccio4-supply = <&vcc_1v8>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_3v3>; ++ vccio7-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcca_1v8>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ max-frequency = <200000000>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe &emmc_rstnout>; ++ vmmc-supply = <&vcc_3v3>; ++ vqmmc-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&sdmmc0 { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>; ++ sd-uhs-sdr50; ++ vmmc-supply = <&vcc3v3_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-IR-receiver-node-to-ODROID-M1.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-IR-receiver-node-to-ODROID-M1.patch new file mode 100644 index 000000000..c94e717a5 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-IR-receiver-node-to-ODROID-M1.patch @@ -0,0 +1,51 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:46 +0200 +Subject: [13/13] arm64: dts: rockchip: Add IR receiver node to ODROID-M1 +Origin: https://git.kernel.org/linus/d6882992fe8182e3122be34af3f491948a8b9069 + +Add the infrared receiver and its associated pinctrl entry. Note that +there is an external pullup to VCC3V3_SYS. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-14-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index 2f685c606bb9..59ecf868dbd0 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -49,6 +49,13 @@ hdmi_con_in: endpoint { + }; + }; + ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ir_receiver_pin>; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -519,6 +526,13 @@ fspi_dual_io_pins: fspi-dual-io-pins { + }; + }; + ++ ir-receiver { ++ ir_receiver_pin: ir-receiver-pin { ++ /* external pullup to VCC3V3_SYS */ ++ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + leds { + led_power_pin: led-power-pin { + rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-NOR-flash-to-ODROID-M1.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-NOR-flash-to-ODROID-M1.patch new file mode 100644 index 000000000..ebc21afec --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-NOR-flash-to-ODROID-M1.patch @@ -0,0 +1,100 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:37 +0200 +Subject: [04/13] arm64: dts: rockchip: Add NOR flash to ODROID-M1 +Origin: https://git.kernel.org/linus/9f96204b7dcf94d03cad41194447c665d10675b7 + +Enable the Rockchip Serial Flash Controller for the ODROID-M1 and add +the corresponding SPI NOR flash entry. The SFC is used in dual I/O mode +and not quad I/O mode, as the FSPI_D2 pin is shared with the EMMC_RSTn +pin. + +The partitions addresses and sizes are taken from the ODROID-M1 +Partition Table page on the ODROID wiki. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-5-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + .../boot/dts/rockchip/rk3568-odroid-m1.dts | 58 +++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index 112c65af3f55..94e839c9afab 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -351,6 +351,20 @@ rgmii_phy0: ethernet-phy@0 { + }; + + &pinctrl { ++ fspi { ++ fspi_dual_io_pins: fspi-dual-io-pins { ++ rockchip,pins = ++ /* fspi_clk */ ++ <1 RK_PD0 1 &pcfg_pull_none>, ++ /* fspi_cs0n */ ++ <1 RK_PD3 1 &pcfg_pull_none>, ++ /* fspi_d0 */ ++ <1 RK_PD1 1 &pcfg_pull_none>, ++ /* fspi_d1 */ ++ <1 RK_PD2 1 &pcfg_pull_none>; ++ }; ++ }; ++ + leds { + led_power_pin: led-power-pin { + rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; +@@ -409,6 +423,50 @@ &sdmmc0 { + status = "okay"; + }; + ++&sfc { ++ /* Dual I/O mode as the D2 pin conflicts with the eMMC */ ++ pinctrl-0 = <&fspi_dual_io_pins>; ++ pinctrl-names = "default"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <100000000>; ++ spi-rx-bus-width = <2>; ++ spi-tx-bus-width = <1>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "SPL"; ++ reg = <0x0 0xe0000>; ++ }; ++ partition@e0000 { ++ label = "U-Boot Env"; ++ reg = <0xe0000 0x20000>; ++ }; ++ partition@100000 { ++ label = "U-Boot"; ++ reg = <0x100000 0x200000>; ++ }; ++ partition@300000 { ++ label = "splash"; ++ reg = <0x300000 0x100000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x400000 0xc00000>; ++ }; ++ }; ++ }; ++}; ++ + &tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-PCIEe-v3-nodes-to-ODROID-M1.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-PCIEe-v3-nodes-to-ODROID-M1.patch new file mode 100644 index 000000000..94c7d7952 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-PCIEe-v3-nodes-to-ODROID-M1.patch @@ -0,0 +1,77 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:45 +0200 +Subject: [12/13] arm64: dts: rockchip: Add PCIEe v3 nodes to ODROID-M1 +Origin: https://git.kernel.org/linus/35b28582aa3dfd7b6861b7ebc72798b0ff50ed41 + +Add nodes to ODROID-M1 to support PCIe v3 on the M2 slot. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-13-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + .../boot/dts/rockchip/rk3568-odroid-m1.dts | 34 +++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index bd24ccf94e76..2f685c606bb9 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -96,6 +96,19 @@ simple-audio-card,codec { + }; + }; + ++ vcc3v3_pcie: vcc3v3-pcie-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_pcie"; ++ enable-active-high; ++ gpio = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc3v3_pcie_en_pin>; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <5000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ + vcc3v3_sys: vcc3v3-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; +@@ -479,6 +492,18 @@ rgmii_phy0: ethernet-phy@0 { + }; + }; + ++&pcie30phy { ++ status = "okay"; ++}; ++ ++&pcie3x2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_reset_pin>; ++ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>; ++ vpcie3v3-supply = <&vcc3v3_pcie>; ++ status = "okay"; ++}; ++ + &pinctrl { + fspi { + fspi_dual_io_pins: fspi-dual-io-pins { +@@ -503,6 +528,15 @@ led_work_pin: led-work-pin { + }; + }; + ++ pcie { ++ pcie_reset_pin: pcie-reset-pin { ++ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ vcc3v3_pcie_en_pin: vcc3v3-pcie-en-pin { ++ rockchip,pins = <4 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-SATA-support-to-ODROID-M1.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-SATA-support-to-ODROID-M1.patch new file mode 100644 index 000000000..2025079e1 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-SATA-support-to-ODROID-M1.patch @@ -0,0 +1,45 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:44 +0200 +Subject: [11/13] arm64: dts: rockchip: Add SATA support to ODROID-M1 +Origin: https://git.kernel.org/linus/6a5a04d52ccc42e0e59ff69fca9c1db7e08ba44b + +Enable the Combo PHY and SATA nodes in ODROID-M1. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-12-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index 9a84a7e76d7a..bd24ccf94e76 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -153,6 +153,11 @@ &combphy1 { + status = "okay"; + }; + ++&combphy2 { ++ /* used for SATA */ ++ status = "okay"; ++}; ++ + &cpu0 { + cpu-supply = <&vdd_cpu>; + }; +@@ -538,6 +543,10 @@ &saradc { + status = "okay"; + }; + ++&sata2 { ++ status = "okay"; ++}; ++ + &sdhci { + bus-width = <8>; + max-frequency = <200000000>; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-analog-audio-on-ODROID-M1.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-analog-audio-on-ODROID-M1.patch new file mode 100644 index 000000000..03cb99ff1 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-analog-audio-on-ODROID-M1.patch @@ -0,0 +1,99 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:38 +0200 +Subject: [05/13] arm64: dts: rockchip: Add analog audio on ODROID-M1 +Origin: https://git.kernel.org/linus/78f858447cb78cac7259093d095fb783328b835c + +On the ODROID-M1, the I2S1 TDM controller is connected to the rk809 +codec in I2S mode. It is used to provide a stereo headphones output and +a mono speaker output. A GPIO with an external pullup is used as an +headphone detection input. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-6-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + .../boot/dts/rockchip/rk3568-odroid-m1.dts | 43 ++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index 94e839c9afab..634c1bd80b4e 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -59,6 +59,31 @@ led_work: led-1 { + }; + }; + ++ rk809-sound { ++ compatible = "simple-audio-card"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hp_det_pin>; ++ simple-audio-card,name = "Analog RK817"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,hp-det-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,widgets = ++ "Headphone", "Headphones", ++ "Speaker", "Speaker"; ++ simple-audio-card,routing = ++ "Headphones", "HPOL", ++ "Headphones", "HPOR", ++ "Speaker", "SPKO"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1_8ch>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&rk809>; ++ }; ++ }; ++ + vcc3v3_sys: vcc3v3-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; +@@ -131,10 +156,15 @@ rk809: pmic@20 { + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>; ++ assigned-clocks = <&cru I2S1_MCLKOUT_TX>; ++ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; + #clock-cells = <1>; ++ clock-names = "mclk"; ++ clocks = <&cru I2S1_MCLKOUT_TX>; + pinctrl-names = "default"; +- pinctrl-0 = <&pmic_int_l>; ++ pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>; + rockchip,system-power-controller; ++ #sound-dai-cells = <0>; + vcc1-supply = <&vcc3v3_sys>; + vcc2-supply = <&vcc3v3_sys>; + vcc3-supply = <&vcc3v3_sys>; +@@ -340,6 +370,11 @@ regulator-state-mem { + }; + }; + ++&i2s1_8ch { ++ rockchip,trcm-sync-tx-only; ++ status = "okay"; ++}; ++ + &mdio0 { + rgmii_phy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; +@@ -379,6 +414,12 @@ pmic_int_l: pmic-int-l { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; ++ ++ rk809 { ++ hp_det_pin: hp-det-pin { ++ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; + }; + + &pmu_io_domains { +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Enable-HDMI-audio-on-ODROID-M1.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-HDMI-audio-on-ODROID-M1.patch new file mode 100644 index 000000000..0dff4d2b7 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-HDMI-audio-on-ODROID-M1.patch @@ -0,0 +1,45 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:40 +0200 +Subject: [07/13] arm64: dts: rockchip: Enable HDMI audio on ODROID-M1. +Origin: https://git.kernel.org/linus/1ca7ddddf36494f0f6afd4f35d37827323271f39 + +This enables the i2s0 controller and the hdmi-sound node on the +ODROID-M1. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-8-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index 126b893048fe..ac4e94d18feb 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -161,6 +161,10 @@ hdmi_out_con: endpoint { + }; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &i2c0 { + status = "okay"; + +@@ -400,6 +404,10 @@ regulator-state-mem { + }; + }; + ++&i2s0_8ch { ++ status = "okay"; ++}; ++ + &i2s1_8ch { + rockchip,trcm-sync-tx-only; + status = "okay"; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-GPU-on-ODROID-M1.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-GPU-on-ODROID-M1.patch new file mode 100644 index 000000000..faed83fca --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-GPU-on-ODROID-M1.patch @@ -0,0 +1,34 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:41 +0200 +Subject: [08/13] arm64: dts: rockchip: Enable the GPU on ODROID-M1 +Origin: https://git.kernel.org/linus/cb80b3455c7cadc4c1157879930e919f607d557c + +Enable the GPU core on the Rockchip RK3568 ODROID-M1. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-9-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index ac4e94d18feb..e4b7699d3eea 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -143,6 +143,11 @@ &gmac0_rgmii_clk + rx_delay = <0x2d>; + }; + ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ + &hdmi { + avdd-0v9-supply = <&vdda0v9_image>; + avdd-1v8-supply = <&vcca1v8_image>; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-USB-2.0-ports-on-ODROI.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-USB-2.0-ports-on-ODROI.patch new file mode 100644 index 000000000..c27944417 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-USB-2.0-ports-on-ODROI.patch @@ -0,0 +1,108 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:42 +0200 +Subject: [09/13] arm64: dts: rockchip: Enable the USB 2.0 ports on ODROID-M1 +Origin: https://git.kernel.org/linus/4685d7b68aaac199ab0d950d2047405bf551f964 + +The Rockchip RK3568 has two USB OHCI/EHCI controllers connected to a PHY +providing one host-only port and one OTG port. On the ODROID-M1, they +are both used in host mode. The USB ports are powered by a DC/DC +converter providing 5V and named VCC5V0_SYS on the schematics, followed +by a power switch. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-10-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + .../boot/dts/rockchip/rk3568-odroid-m1.dts | 61 +++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index e4b7699d3eea..2e4cc20bd676 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -105,6 +105,28 @@ vcc3v3_sys: vcc3v3-sys-regulator { + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; ++ ++ vcc5v0_sys: vcc5v0-sys-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&dc_12v>; ++ }; ++ ++ vcc5v0_usb_host: vcc5v0-usb-host-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_usb_host"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_usb_host_en_pin>; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; + }; + + &cpu0 { +@@ -463,6 +485,15 @@ hp_det_pin: hp-det-pin { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; ++ ++ usb { ++ vcc5v0_usb_host_en_pin: vcc5v0-usb-host-en-pin { ++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ vcc5v0_usb_otg_en_pin: vcc5v0-usb-otg-en-pin { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; + }; + + &pmu_io_domains { +@@ -561,6 +592,36 @@ &uart2 { + status = "okay"; + }; + ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usb2phy1 { ++ status = "okay"; ++}; ++ ++&usb2phy1_host { ++ phy-supply = <&vcc5v0_usb_host>; ++ status = "okay"; ++}; ++ ++&usb2phy1_otg { ++ phy-supply = <&vcc5v0_usb_host>; ++ status = "okay"; ++}; ++ + &vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-USB-3.0-ports-on-ODROI.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-USB-3.0-ports-on-ODROI.patch new file mode 100644 index 000000000..bfcf9c523 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-the-USB-3.0-ports-on-ODROI.patch @@ -0,0 +1,111 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:43 +0200 +Subject: [10/13] arm64: dts: rockchip: Enable the USB 3.0 ports on ODROID-M1 +Origin: https://git.kernel.org/linus/9984ef562653c8d0beb51021fc286706b6ec4802 + +The Rockchip RK3568 has two USB XHCI controllers. The USB 2.0 signals +are connected to a PHY providing one host-only port and one OTG port. +The USB 3.0 signals are connected to two USB3.0/PCIE/SATA combo PHY. + +The ODROID M1 has 2 type A USB 3.0 connectors, with the USB 3.0 signals +connected to the two combo PHYs. For the USB 2.0 signals, one connector +is connected to the host-only PHY and uses the same power switch as the +USB 2.0 ports. The other connector has its own power switch and is +connected to the OTG PHY, which is also connected to a device only +micro-USB connector. The purpose of this micro-USB connector is for +firmware update using the Rockusb vendor specific USB class. Therefore +it does not make sense to enable this port on Linux, and the PHY is +forced to host mode. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-11-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + .../boot/dts/rockchip/rk3568-odroid-m1.dts | 49 ++++++++++++++++++- + 1 file changed, 48 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index 2e4cc20bd676..9a84a7e76d7a 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -127,6 +127,30 @@ vcc5v0_usb_host: vcc5v0-usb-host-regulator { + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; ++ ++ vcc5v0_usb_otg: vcc5v0-usb-otg-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_usb_otg"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_usb_otg_en_pin>; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++}; ++ ++&combphy0 { ++ /* Used for USB3 */ ++ phy-supply = <&vcc5v0_usb_host>; ++ status = "okay"; ++}; ++ ++&combphy1 { ++ /* Used for USB3 */ ++ phy-supply = <&vcc5v0_usb_otg>; ++ status = "okay"; + }; + + &cpu0 { +@@ -490,7 +514,7 @@ usb { + vcc5v0_usb_host_en_pin: vcc5v0-usb-host-en-pin { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; +- vcc5v0_usb_otg_en_pin: vcc5v0-usb-otg-en-pin { ++ vcc5v0_usb_otg_en_pin: vcc5v0-usb-dr-en-pin { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +@@ -600,6 +624,11 @@ &usb_host0_ohci { + status = "okay"; + }; + ++&usb_host0_xhci { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ + &usb_host1_ehci { + status = "okay"; + }; +@@ -608,6 +637,24 @@ &usb_host1_ohci { + status = "okay"; + }; + ++&usb_host1_xhci { ++ status = "okay"; ++}; ++ ++&usb2phy0 { ++ status = "okay"; ++}; ++ ++&usb2phy0_host { ++ phy-supply = <&vcc5v0_usb_host>; ++ status = "okay"; ++}; ++ ++&usb2phy0_otg { ++ phy-supply = <&vcc5v0_usb_otg>; ++ status = "okay"; ++}; ++ + &usb2phy1 { + status = "okay"; + }; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Enable-vop2-and-hdmi-tx-on-ODROID.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-vop2-and-hdmi-tx-on-ODROID.patch new file mode 100644 index 000000000..48d1b3642 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-Enable-vop2-and-hdmi-tx-on-ODROID.patch @@ -0,0 +1,94 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:39 +0200 +Subject: [06/13] arm64: dts: rockchip: Enable vop2 and hdmi tx on ODROID-M1 +Origin: https://git.kernel.org/linus/913404aa2e60610f9cae375069dae97e11d726ed + +Enable the RK356x Video Output Processor (VOP) 2 on ODROID M1. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-7-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + .../boot/dts/rockchip/rk3568-odroid-m1.dts | 47 +++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index 634c1bd80b4e..126b893048fe 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -8,6 +8,7 @@ + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/leds/common.h> + #include <dt-bindings/pinctrl/rockchip.h> ++#include <dt-bindings/soc/rockchip,vop2.h> + #include "rk3568.dtsi" + + / { +@@ -37,6 +38,17 @@ dc_12v: dc-12v-regulator { + regulator-max-microvolt = <12000000>; + }; + ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -131,6 +143,24 @@ &gmac0_rgmii_clk + rx_delay = <0x2d>; + }; + ++&hdmi { ++ avdd-0v9-supply = <&vdda0v9_image>; ++ avdd-1v8-supply = <&vcca1v8_image>; ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint { ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ + &i2c0 { + status = "okay"; + +@@ -517,3 +547,20 @@ &tsadc { + &uart2 { + status = "okay"; + }; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = <ROCKCHIP_VOP2_EP_HDMI0>; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-add-thermal-support-to-ODROID-M1.patch b/debian/patches/features/arm64/arm64-dts-rockchip-add-thermal-support-to-ODROID-M1.patch new file mode 100644 index 000000000..5e0970dba --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-rockchip-add-thermal-support-to-ODROID-M1.patch @@ -0,0 +1,35 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Fri, 30 Sep 2022 07:12:36 +0200 +Subject: [03/13] arm64: dts: rockchip: add thermal support to ODROID-M1 +Origin: https://git.kernel.org/linus/f5511bd8498da222b6455038a0cf3e7d2b2dfc7e + +Add the thermal nodes for the ODROID-M1. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-4-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +index b3016437640b..112c65af3f55 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +@@ -409,6 +409,12 @@ &sdmmc0 { + status = "okay"; + }; + ++&tsadc { ++ rockchip,hw-tshut-mode = <1>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ + &uart2 { + status = "okay"; + }; +-- +2.35.1 + diff --git a/debian/patches/features/arm64/dt-bindings-rockchip-Add-Hardkernel-ODROID-M1-board.patch b/debian/patches/features/arm64/dt-bindings-rockchip-Add-Hardkernel-ODROID-M1-board.patch new file mode 100644 index 000000000..54d0c6c20 --- /dev/null +++ b/debian/patches/features/arm64/dt-bindings-rockchip-Add-Hardkernel-ODROID-M1-board.patch @@ -0,0 +1,37 @@ +From: Dongjin Kim <tobetter@gmail.com> +Date: Fri, 30 Sep 2022 07:12:34 +0200 +Subject: [01/13] dt-bindings: rockchip: Add Hardkernel ODROID-M1 board +Origin: https://git.kernel.org/linus/19cc53eb2ce63c0e5adc2fd89494fb16f383ac10 + +Add device tree binding for Hardkernel ODROID-M1 board based on RK3568 +SoC. + +Signed-off-by: Dongjin Kim <tobetter@gmail.com> +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Tested-by: Dan Johansen <strit@manjaro.org> +Link: https://lore.kernel.org/r/20220930051246.391614-2-aurelien@aurel32.net +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml +index eee1e6b3f9cb..72bf2fbfe99d 100644 +--- a/Documentation/devicetree/bindings/arm/rockchip.yaml ++++ b/Documentation/devicetree/bindings/arm/rockchip.yaml +@@ -468,6 +468,11 @@ properties: + - const: hardkernel,rk3326-odroid-go2 + - const: rockchip,rk3326 + ++ - description: Hardkernel Odroid M1 ++ items: ++ - const: rockchip,rk3568-odroid-m1 ++ - const: rockchip,rk3568 ++ + - description: Hugsun X99 TV Box + items: + - const: hugsun,x99 +-- +2.35.1 + diff --git a/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Add-SOQuartz-Model-A-baseboard.patch b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Add-SOQuartz-Model-A-baseboard.patch new file mode 100644 index 000000000..ae644e05f --- /dev/null +++ b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Add-SOQuartz-Model-A-baseboard.patch @@ -0,0 +1,279 @@ +From: Andrew Powers-Holmes <aholmes@omnom.net> +Date: Wed, 16 Nov 2022 12:53:37 +0100 +Subject: [4/4] arm64: dts: rockchip: Add SOQuartz Model A baseboard +Origin: https://git.kernel.org/linus/afbaed737fb45bcae91e4606025fb31da71b9dfe + +This patch adds the device tree for the "Model A" baseboard for +the SOQuartz CM4 SoM, which is not to be confused with the +Quartz64 Model A, which is the same form factor and SoC, but is +not a CM4 carrier board. + +The board features a PCIe 2 x1 slot, USB 2 host ports, CSI/DSI +connectors, an eDP FFC connector, gigabit ethernet, HDMI, and a +12V DC barrel jack. Also present is a microSD card slot, 40-pin +GPIO, and a power and reset button. + +Signed-off-by: Andrew Powers-Holmes <aholmes@omnom.net> +[rebase, misc fixes, reword] +Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Link: https://lore.kernel.org/r/20221116115337.541601-5-frattaroli.nicolas@gmail.com +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../dts/rockchip/rk3566-soquartz-model-a.dts | 232 ++++++++++++++++++ + 2 files changed, 233 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 071284a46bf7..0a76a2ebb5f6 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -70,6 +70,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-blade.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-model-a.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-odroid-m1.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts +new file mode 100644 +index 000000000000..2208dbfb7f0a +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts +@@ -0,0 +1,232 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include "rk3566-soquartz.dtsi" ++ ++/ { ++ model = "PINE64 RK3566 SOQuartz on Model A carrier board"; ++ compatible = "pine64,soquartz-model-a", "pine64,soquartz", "rockchip,rk3566"; ++ ++ /* labeled DCIN_12V in schematic */ ++ vcc12v_dcin: vcc12v-dcin-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc5v0_usb: vcc5v0-usb-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_usb"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ /* ++ * Labelled VCC3V0_SD in schematic to not conflict with PMIC ++ * regulator, it's 3.3v in actuality ++ */ ++ vcc3v0_sd: vcc3v0-sd-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v0_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vcc3v3_pcie: vcc3v3-pcie-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_pcie"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc12v_pcie: vcc12v-pcie-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_pcie"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++}; ++ ++/* phy for pcie */ ++&combphy2 { ++ phy-supply = <&vcc3v3_sys>; ++ status = "okay"; ++}; ++ ++&gmac1 { ++ status = "okay"; ++}; ++ ++/* ++ * i2c1 is exposed on CM1 / Module1A ++ * pin 80 - SCL0 - i2c1_scl_m0, pullup to vcc3v3_pmu ++ * pin 82 - SDA0 - i2c1_sda_m0, pullup to vcc3v3_pmu ++ */ ++&i2c1 { ++ status = "okay"; ++ ++ /* ++ * the rtc interrupt is tied to PMIC_PWRON, ++ * it will force reset the board if triggered. ++ */ ++ pcf85063: rtc@51 { ++ compatible = "nxp,pcf85063"; ++ reg = <0x51>; ++ }; ++}; ++ ++/* ++ * i2c2 is exposed on CM1 / Module1A - to PI40 ++ * pin 56 - GPIO3 - i2c2_scl_m1, pullup to vcc_3v3, shared with i2s1_8ch ++ * pin 58 - GPIO2 - i2c2_sda_m1, pullup to vcc_3v3 ++ */ ++&i2c2 { ++ status = "disabled"; ++}; ++ ++/* ++ * i2c3 is exposed on CM1 / Module1A - to PI40 ++ * pin 35 - ID_SC(GPIO28) - i2c3_scl_m0, pullup to vcc_3v3 ++ * pin 36 - ID_SD(GPIO27) - i2c3_sda_m0, pullup to vcc_3v3 ++ */ ++&i2c3 { ++ status = "disabled"; ++}; ++ ++/* ++ * i2c4 is exposed on CM2 / Module1B - to PI40 ++ * pin 45 - GPIO24 - i2c4_scl_m1 ++ * pin 47 - GPIO23 - i2c4_sda_m1 ++ */ ++&i2c4 { ++ status = "disabled"; ++}; ++ ++/* ++ * i2s1_8ch is exposed on CM1 / Module1A - to PI40 ++ * pin 24 - GPIO26 - i2s1_sdi1_m1 ++ * pin 25 - GPIO21 - i2s1_sdo0_m1 ++ * pin 26 - GPIO19 - i2s1_lrck_tx_m1 ++ * pin 27 - GPIO20 - i2s1_sdi0_m1 ++ * pin 29 - GPIO16 - i2s1_sdi3_m1 ++ * pin 30 - GPIO6 - i2s1_sdi2_m1 ++ * pin 40 - GPIO9 - i2s1_sdo1_m1, shared with spi3 ++ * pin 41 - GPIO25 - i2s1_sdo2_m1 ++ * pin 49 - GPIO18 - i2s1_sclk_tx_m1 ++ * pin 50 - GPIO17 - i2s1_mclk_m1 ++ * pin 56 - GPIO3 - i2s1_sdo3_m1, shared with i2c2 ++ */ ++&i2s1_8ch { ++ status = "disabled"; ++}; ++ ++&led_diy { ++ status = "okay"; ++}; ++ ++&led_work { ++ status = "okay"; ++}; ++ ++&pcie2x1 { ++ vpcie3v3-supply = <&vcc3v3_pcie>; ++ status = "okay"; ++}; ++ ++&rgmii_phy1 { ++ status = "okay"; ++}; ++ ++&rgmii_phy1 { ++ status = "okay"; ++}; ++ ++/* ++ * saradc is exposed on CM1 / Module1A - to J2 ++ * pin 94 - AIN1 - saradc_vin3 ++ * pin 96 - AIN0 - saradc_vin2 ++ */ ++&saradc { ++ status = "disabled"; ++}; ++ ++/* ++ * vmmc-supply is vcc3v3_sd on v1.0 and vcc3v0_sd on v1.1+ ++ * the soquartz SoM has SDMMC_PWR (CM1 pin 75) hardwired to vcc3v3_sys, ++ * so we use vcc3v3_sd here to ensure the regulator is enabled on older boards. ++ */ ++&sdmmc0 { ++ vmmc-supply = <&vcc3v3_sd>; ++ status = "okay"; ++}; ++ ++/* ++ * spi3 is exposed on CM1 / Module1A - to PI40 ++ * pin 37 - GPIO7 - spi3_cs1_m0 ++ * pin 38 - GPIO11 - spi3_clk_m0 ++ * pin 39 - GPIO8 - spi3_cs0_m0 ++ * pin 40 - GPIO9 - spi3_miso_m0, shared with i2s1_8ch ++ * pin 44 - GPIO10 - spi3_mosi_m0 ++ */ ++&spi3 { ++ status = "disabled"; ++}; ++ ++/* ++ * uart2 is exposed on CM1 / Module1A - to PI40 ++ * pin 51 - GPIO15 - uart2_rx_m0 ++ * pin 55 - GPIO14 - uart2_tx_m0 ++ */ ++&uart2 { ++ status = "okay"; ++}; ++ ++/* ++ * uart7 is exposed on CM1 / Module1A - to PI40 ++ * pin 46 - GPIO22 - uart7_tx_m2 ++ * pin 47 - GPIO23 - uart7_rx_m2 ++ */ ++&uart7 { ++ status = "okay"; ++}; ++ ++&usb2phy0 { ++ status = "okay"; ++}; ++ ++&usb2phy0_otg { ++ phy-supply = <&vcc5v0_usb>; ++ status = "okay"; ++}; ++ ++&usb_host0_xhci { ++ status = "okay"; ++}; ++ ++&vbus { ++ vin-supply = <&vcc5v0_usb>; ++}; ++ ++&vcc3v3_sd { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ status = "okay"; ++}; +-- +2.39.0 + diff --git a/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Add-SOQuartz-blade-board.patch b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Add-SOQuartz-blade-board.patch new file mode 100644 index 000000000..246d62c12 --- /dev/null +++ b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Add-SOQuartz-blade-board.patch @@ -0,0 +1,242 @@ +From: Andrew Powers-Holmes <aholmes@omnom.net> +Date: Wed, 16 Nov 2022 12:53:35 +0100 +Subject: [2/4] arm64: dts: rockchip: Add SOQuartz blade board +Origin: https://git.kernel.org/linus/a5c826ecde5222f755e7d8a0c8d795189c5c1228 + +This adds a device tree for the PINE64 SOQuartz blade baseboard, +a 1U rack mountable baseboard for the CM4 form factor with PoE +support designed for the SOQuartz CM4 System-on-Module. + +The board takes power from either PoE or a 5V DC input, and allows +for mounting an M.2 SSD. + +The board also features one USB 2.0 host port, one HDMI output, +a 3.5mm jack for UART, and the aforementioned gigabit networking +port. + +Signed-off-by: Andrew Powers-Holmes <aholmes@omnom.net> +[rebase, squash, reword, misc fixes] +Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Link: https://lore.kernel.org/r/20221116115337.541601-3-frattaroli.nicolas@gmail.com +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../dts/rockchip/rk3566-soquartz-blade.dts | 194 ++++++++++++++++++ + 2 files changed, 195 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index e14390277739..071284a46bf7 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -68,6 +68,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-blade.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts +new file mode 100644 +index 000000000000..4e49bebf548b +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts +@@ -0,0 +1,194 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++ ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/input/input.h> ++#include <dt-bindings/leds/common.h> ++#include <dt-bindings/pinctrl/rockchip.h> ++ ++#include "rk3566-soquartz.dtsi" ++ ++/ { ++ model = "PINE64 RK3566 SOQuartz on Blade carrier board"; ++ compatible = "pine64,soquartz-blade", "pine64,soquartz", "rockchip,rk3566"; ++ ++ /* labeled VCC3V0_SD in schematic to not conflict with PMIC regulator */ ++ vcc3v0_sd: vcc3v0-sd-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v0_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ /* labeled VCC_SSD in schematic */ ++ vcc3v3_pcie_p: vcc3v3-pcie-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_pcie_p"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vbus>; ++ }; ++ ++ vcc5v_dcin: vcc5v-dcin-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++}; ++ ++&combphy2 { ++ phy-supply = <&vcc3v3_sys>; ++ status = "okay"; ++}; ++ ++&gmac1 { ++ status = "okay"; ++}; ++ ++/* ++ * i2c1 is exposed on CM1 / Module1A ++ * pin 80 - SCL0 - i2c1_scl_m0, pullup to vcc3v3_pmu ++ * pin 82 - SDA0 - i2c1_sda_m0, pullup to vcc3v3_pmu ++ */ ++&i2c1 { ++ status = "okay"; ++ ++}; ++ ++/* ++ * i2c2 is exposed on CM1 / Module1A - to PI40 ++ * pin 56 - GPIO3 - i2c2_scl_m1, pullup to vcc_3v3, shared with i2s1_8ch ++ * pin 58 - GPIO2 - i2c2_sda_m1, pullup to vcc_3v3 ++ */ ++&i2c2 { ++ status = "disabled"; ++}; ++ ++/* ++ * i2c3 is exposed on CM1 / Module1A - to PI40 ++ * pin 35 - ID_SC(GPIO28) - i2c3_scl_m0, pullup to vcc_3v3 ++ * pin 36 - ID_SD(GPIO27) - i2c3_sda_m0, pullup to vcc_3v3 ++ */ ++&i2c3 { ++ status = "disabled"; ++}; ++ ++/* ++ * i2c4 is exposed on CM2 / Module1B - to PI40 ++ * pin 45 - GPIO24 - i2c4_scl_m1 ++ * pin 47 - GPIO23 - i2c4_sda_m1 ++ */ ++&i2c4 { ++ status = "disabled"; ++}; ++ ++/* ++ * i2s1_8ch is exposed on CM1 / Module1A - to PI40 ++ * pin 24 - GPIO26 - i2s1_sdi1_m1 ++ * pin 25 - GPIO21 - i2s1_sdo0_m1 ++ * pin 26 - GPIO19 - i2s1_lrck_tx_m1 ++ * pin 27 - GPIO20 - i2s1_sdi0_m1 ++ * pin 29 - GPIO16 - i2s1_sdi3_m1 ++ * pin 30 - GPIO6 - i2s1_sdi2_m1 ++ * pin 40 - GPIO9 - i2s1_sdo1_m1, shared with spi3 ++ * pin 41 - GPIO25 - i2s1_sdo2_m1 ++ * pin 49 - GPIO18 - i2s1_sclk_tx_m1 ++ * pin 50 - GPIO17 - i2s1_mclk_m1 ++ * pin 56 - GPIO3 - i2s1_sdo3_m1, shared with i2c2 ++ */ ++&i2s1_8ch { ++ status = "disabled"; ++}; ++ ++&led_diy { ++ color = <LED_COLOR_ID_RED>; ++ function = LED_FUNCTION_DISK_ACTIVITY; ++ linux,default-trigger = "disk-activity"; ++ status = "okay"; ++}; ++ ++&led_work { ++ color = <LED_COLOR_ID_GREEN>; ++ function = LED_FUNCTION_STATUS; ++ linux,default-trigger = "heartbeat"; ++ status = "okay"; ++}; ++ ++&pcie2x1 { ++ vpcie3v3-supply = <&vcc3v3_pcie_p>; ++ status = "okay"; ++}; ++ ++&rgmii_phy1 { ++ status = "okay"; ++}; ++ ++/* ++ * saradc is exposed on CM1 / Module1A - to J2 ++ * pin 94 - AIN1 - saradc_vin3 ++ * pin 96 - AIN0 - saradc_vin2 ++ */ ++&saradc { ++ status = "disabled"; ++}; ++ ++&sdmmc0 { ++ vmmc-supply = <&vcc3v0_sd>; ++ status = "okay"; ++}; ++ ++/* ++ * spi3 is exposed on CM1 / Module1A - to PI40 ++ * pin 37 - GPIO7 - spi3_cs1_m0 ++ * pin 38 - GPIO11 - spi3_clk_m0 ++ * pin 39 - GPIO8 - spi3_cs0_m0 ++ * pin 40 - GPIO9 - spi3_miso_m0, shared with i2s1_8ch ++ * pin 44 - GPIO10 - spi3_mosi_m0 ++ */ ++&spi3 { ++ status = "disabled"; ++}; ++ ++/* ++ * uart2 is exposed on CM1 / Module1A - to PI40 ++ * pin 51 - GPIO15 - uart2_rx_m0 ++ * pin 55 - GPIO14 - uart2_tx_m0 ++ */ ++&uart2 { ++ status = "okay"; ++}; ++ ++/* ++ * uart7 is exposed on CM1 / Module1A - to PI40 ++ * pin 46 - GPIO22 - uart7_tx_m2 ++ * pin 47 - GPIO23 - uart7_rx_m2 ++ */ ++&uart7 { ++ status = "okay"; ++}; ++ ++&usb2phy0 { ++ status = "okay"; ++}; ++ ++&usb2phy0_otg { ++ phy-supply = <&vbus>; ++ status = "okay"; ++}; ++ ++&usb_host0_xhci { ++ status = "okay"; ++}; ++ ++&vbus { ++ vin-supply = <&vcc5v_dcin>; ++}; +-- +2.39.0 + diff --git a/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-HDMI-sound-on-SOQuartz.patch b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-HDMI-sound-on-SOQuartz.patch new file mode 100644 index 000000000..d4df69e16 --- /dev/null +++ b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-HDMI-sound-on-SOQuartz.patch @@ -0,0 +1,44 @@ +From: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Date: Sat, 12 Nov 2022 17:04:00 +0100 +Subject: arm64: dts: rockchip: Enable HDMI sound on SOQuartz +Origin: https://git.kernel.org/linus/70b620c4ba919a87c607b8d98b08478b213877bd + +This patch enables the i2s0 node on SOQuartz, which is responsible +for hdmi audio, and adds an hdmi-sound node to enable said audio. + +Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Link: https://lore.kernel.org/r/20221112160404.70868-4-frattaroli.nicolas@gmail.com +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi +index 0bfb0cea7d6b..1b975822effa 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi +@@ -178,6 +178,10 @@ + }; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &i2c0 { + status = "okay"; + +@@ -446,6 +450,10 @@ + status = "disabled"; + }; + ++&i2s0_8ch { ++ status = "okay"; ++}; ++ + /* + * i2s1_8ch is exposed on CM1 / Module1A + * pin 24 - i2s1_sdi1_m1 +-- +2.39.0 + diff --git a/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-PCIe-2-on-SOQuartz-CM4IO.patch b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-PCIe-2-on-SOQuartz-CM4IO.patch new file mode 100644 index 000000000..1a8063e0f --- /dev/null +++ b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-PCIe-2-on-SOQuartz-CM4IO.patch @@ -0,0 +1,82 @@ +From: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Date: Sat, 12 Nov 2022 17:04:01 +0100 +Subject: arm64: dts: rockchip: Enable PCIe 2 on SOQuartz CM4IO +Origin: https://git.kernel.org/linus/3736aa7ecc4cd9b4abce30052bad00aba4f0362f + +This patch enables the PCIe2 on the CM4IO board when paired with +a SOQuartz CM4 System-on-Module board. combphy2 also needs to be +enabled in this case to make the PHY work for this. + +Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Link: https://lore.kernel.org/r/20221112160404.70868-5-frattaroli.nicolas@gmail.com +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + .../boot/dts/rockchip/rk3566-soquartz-cm4.dts | 11 +++++++++++ + arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi | 15 +++++++++++++++ + 2 files changed, 26 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts +index e00568a6be5c..263ce40770dd 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts +@@ -30,6 +30,12 @@ + }; + }; + ++/* phy for pcie */ ++&combphy2 { ++ phy-supply = <&vcc3v3_sys>; ++ status = "okay"; ++}; ++ + &gmac1 { + status = "okay"; + }; +@@ -105,6 +111,11 @@ + status = "okay"; + }; + ++&pcie2x1 { ++ vpcie3v3-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ + &rgmii_phy1 { + status = "okay"; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi +index 1b975822effa..ce7165d7f1a1 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi +@@ -487,6 +487,12 @@ + }; + }; + ++&pcie2x1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_reset_h>; ++ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; ++}; ++ + &pinctrl { + bt { + bt_enable_h: bt-enable-h { +@@ -512,6 +518,15 @@ + }; + }; + ++ pcie { ++ pcie_clkreq_h: pcie-clkreq-h { ++ rockchip,pins = <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ pcie_reset_h: pcie-reset-h { ++ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; +-- +2.39.0 + diff --git a/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-video-output-and-HDMI-on-S.patch b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-video-output-and-HDMI-on-S.patch new file mode 100644 index 000000000..37cfbdb23 --- /dev/null +++ b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-Enable-video-output-and-HDMI-on-S.patch @@ -0,0 +1,94 @@ +From: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Date: Sat, 12 Nov 2022 17:03:59 +0100 +Subject: arm64: dts: rockchip: Enable video output and HDMI on SOQuartz +Origin: https://git.kernel.org/linus/36d7a605706d9648526a0574b8e7b0e02fa70c2a + +This patch adds and enables the necessary device tree nodes to +enable video output and HDMI functionality on the SOQuartz module. + +Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Link: https://lore.kernel.org/r/20221112160404.70868-3-frattaroli.nicolas@gmail.com +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + .../boot/dts/rockchip/rk3566-soquartz.dtsi | 47 +++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi +index 6e99f049501c..0bfb0cea7d6b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi +@@ -4,6 +4,7 @@ + + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/pinctrl/rockchip.h> ++#include <dt-bindings/soc/rockchip,vop2.h> + #include "rk3566.dtsi" + + / { +@@ -28,6 +29,17 @@ + #clock-cells = <0>; + }; + ++ hdmi-con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -148,6 +160,24 @@ + status = "okay"; + }; + ++&hdmi { ++ avdd-0v9-supply = <&vdda0v9_image>; ++ avdd-1v8-supply = <&vcca1v8_image>; ++ status = "okay"; ++}; ++ ++&hdmi_in { ++ hdmi_in_vp0: endpoint { ++ remote-endpoint = <&vp0_out_hdmi>; ++ }; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ + &i2c0 { + status = "okay"; + +@@ -619,3 +649,20 @@ + &usb_host0_xhci { + status = "disabled"; + }; ++ ++&vop { ++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; ++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vp0 { ++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { ++ reg = <ROCKCHIP_VOP2_EP_HDMI0>; ++ remote-endpoint = <&hdmi_in_vp0>; ++ }; ++}; +-- +2.39.0 + diff --git a/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-RK356x-Add-I2S2-device-node.patch b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-RK356x-Add-I2S2-device-node.patch new file mode 100644 index 000000000..55c6af80b --- /dev/null +++ b/debian/patches/features/arm64/quartz64/arm64-dts-rockchip-RK356x-Add-I2S2-device-node.patch @@ -0,0 +1,50 @@ +From: Shengyu Qu <wiagn233@outlook.com> +Date: Sun, 30 Oct 2022 01:09:04 +0800 +Subject: arm64: dts: rockchip: RK356x: Add I2S2 device node +Origin: https://git.kernel.org/linus/755f37010f3eac0bdfa41bdf2308e8380a93f10c + +This patch adds I2S2 device tree node for RK3566/RK3568. + +Signed-off-by: Shengyu Qu <wiagn233@outlook.com> +Link: https://lore.kernel.org/r/OS3P286MB259771C12F2B15A4DDF435FE98359@OS3P286MB2597.JPNP286.PROD.OUTLOOK.COM +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +index 10e3a0862602..5706c3e24f0a 100644 +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -1091,6 +1091,28 @@ + status = "disabled"; + }; + ++ i2s2_2ch: i2s@fe420000 { ++ compatible = "rockchip,rk3568-i2s-tdm"; ++ reg = <0x0 0xfe420000 0x0 0x1000>; ++ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; ++ assigned-clocks = <&cru CLK_I2S2_2CH_SRC>; ++ assigned-clock-rates = <1188000000>; ++ clocks = <&cru MCLK_I2S2_2CH>, <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>; ++ clock-names = "mclk_tx", "mclk_rx", "hclk"; ++ dmas = <&dmac1 4>, <&dmac1 5>; ++ dma-names = "tx", "rx"; ++ resets = <&cru SRST_M_I2S2_2CH>; ++ reset-names = "m"; ++ rockchip,grf = <&grf>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s2m0_sclktx ++ &i2s2m0_lrcktx ++ &i2s2m0_sdi ++ &i2s2m0_sdo>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2s3_2ch: i2s@fe430000 { + compatible = "rockchip,rk3568-i2s-tdm"; + reg = <0x0 0xfe430000 0x0 0x1000>; +-- +2.39.0 + diff --git a/debian/patches/features/arm64/quartz64/dt-bindings-arm-rockchip-Add-SOQuartz-Blade.patch b/debian/patches/features/arm64/quartz64/dt-bindings-arm-rockchip-Add-SOQuartz-Blade.patch new file mode 100644 index 000000000..52fdca25d --- /dev/null +++ b/debian/patches/features/arm64/quartz64/dt-bindings-arm-rockchip-Add-SOQuartz-Blade.patch @@ -0,0 +1,39 @@ +From: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Date: Wed, 16 Nov 2022 12:53:34 +0100 +Subject: [1/4] dt-bindings: arm: rockchip: Add SOQuartz Blade +Origin: https://git.kernel.org/linus/8c84c2e51f3ee39b40e8078ebe3ad9c01fb17aff + +Add a compatible for the SOQuartz Blade base board to the rockchip +platforms binding. + +The SOQuartz Blade is a PoE-capable carrier board for the CM4 SoM +form factor, designed around the SOQuartz CM4 System-on-Module. + +The board features the usual connectivity (GPIO, USB, HDMI, +Ethernet) and an M.2 slot for SSDs. It may also be powered from +a 5V barrel jack input, and has a 3.5mm jack for UART debug +output. + +Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Link: https://lore.kernel.org/r/20221116115337.541601-2-frattaroli.nicolas@gmail.com +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + Documentation/devicetree/bindings/arm/rockchip.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml +index 3f31115ee99a..42f33240ade8 100644 +--- a/Documentation/devicetree/bindings/arm/rockchip.yaml ++++ b/Documentation/devicetree/bindings/arm/rockchip.yaml +@@ -593,6 +593,7 @@ properties: + - description: Pine64 SoQuartz SoM + items: + - enum: ++ - pine64,soquartz-blade + - pine64,soquartz-cm4io + - const: pine64,soquartz + - const: rockchip,rk3566 +-- +2.39.0 + diff --git a/debian/patches/features/arm64/quartz64/dt-bindings-arm-rockchip-Add-SOQuartz-Model-A.patch b/debian/patches/features/arm64/quartz64/dt-bindings-arm-rockchip-Add-SOQuartz-Model-A.patch new file mode 100644 index 000000000..2983e8a88 --- /dev/null +++ b/debian/patches/features/arm64/quartz64/dt-bindings-arm-rockchip-Add-SOQuartz-Model-A.patch @@ -0,0 +1,39 @@ +From: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Date: Wed, 16 Nov 2022 12:53:36 +0100 +Subject: [3/4] dt-bindings: arm: rockchip: Add SOQuartz Model A +Origin: https://git.kernel.org/linus/7441d8c437883581dddfb616a087b399338244f0 + +The SOQuartz Model A base board is a carrier board for the CM4 +form factor, designed around the PINE64 SOQuartz CM4 SoM. + +The board sports "Model A" dimensions like the Quartz64 Model A, +but is not to be confused with that. + +As for I/O, it features USB 2 ports, Gigabit Ethernet, a PCIe 2 +x1 slot, HDMI, a 40-pin GPIO header, CSI/DSI connectors, an eDP +flat-flex cable connector, a 12V DC barrel jack for power input +and power/reset buttons as well as a microSD card slot. + +Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> +Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Link: https://lore.kernel.org/r/20221116115337.541601-4-frattaroli.nicolas@gmail.com +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + Documentation/devicetree/bindings/arm/rockchip.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml +index 42f33240ade8..88ff4422a8c1 100644 +--- a/Documentation/devicetree/bindings/arm/rockchip.yaml ++++ b/Documentation/devicetree/bindings/arm/rockchip.yaml +@@ -595,6 +595,7 @@ properties: + - enum: + - pine64,soquartz-blade + - pine64,soquartz-cm4io ++ - pine64,soquartz-model-a + - const: pine64,soquartz + - const: rockchip,rk3566 + +-- +2.39.0 + diff --git a/debian/patches/features/x86/intel-iommu-add-kconfig-option-to-exclude-igpu-by-default.patch b/debian/patches/features/x86/intel-iommu-add-kconfig-option-to-exclude-igpu-by-default.patch new file mode 100644 index 000000000..ff2fdadc4 --- /dev/null +++ b/debian/patches/features/x86/intel-iommu-add-kconfig-option-to-exclude-igpu-by-default.patch @@ -0,0 +1,76 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 21 Aug 2019 00:32:16 +0100 +Subject: intel-iommu: Add Kconfig option to exclude iGPU by default +Bug-Debian: https://bugs.debian.org/935270 +Bug-Kali: https://bugs.kali.org/view.php?id=5644 + +There is still laptop firmware that touches the integrated GPU behind +the operating system's back, and doesn't say so in the RMRR table. +Enabling the IOMMU for all devices causes breakage. + +Replace CONFIG_INTEL_IOMMU_DEFAULT_ON with a 3-way choice +corresponding to "on", "off", and "on,intgpu_off". + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/iommu/intel/Kconfig ++++ b/drivers/iommu/intel/Kconfig +@@ -56,14 +56,25 @@ config INTEL_IOMMU_SVM + to access DMA resources through process address space by + means of a Process Address Space ID (PASID). + +-config INTEL_IOMMU_DEFAULT_ON +- bool "Enable Intel DMA Remapping Devices by default" +- default y ++choice ++ prompt "Default state of Intel DMA Remapping Devices" ++ default INTEL_IOMMU_DEFAULT_ON + help +- Selecting this option will enable a DMAR device at boot time if +- one is found. If this option is not selected, DMAR support can +- be enabled by passing intel_iommu=on to the kernel. ++ Choose whether Intel DMA Remapping Devices should be enabled ++ by default. This can be overridden at boot time using the ++ intel_iommu= kernel parameter. ++ ++config INTEL_IOMMU_DEFAULT_ON ++ bool "Enable" ++ ++config INTEL_IOMMU_DEFAULT_ON_INTGPU_OFF ++ bool "Enable, excluding integrated GPU" ++ ++config INTEL_IOMMU_DEFAULT_OFF ++ bool "Disable" + ++endchoice ++ + config INTEL_IOMMU_BROKEN_GFX_WA + bool "Workaround broken graphics drivers (going away soon)" + depends on BROKEN && X86 +--- a/drivers/iommu/intel/iommu.c ++++ b/drivers/iommu/intel/iommu.c +@@ -282,14 +282,14 @@ static LIST_HEAD(dmar_satc_units); + + static void device_block_translation(struct device *dev); + +-int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON); ++int dmar_disabled = IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_OFF); + int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON); + + int intel_iommu_enabled = 0; + EXPORT_SYMBOL_GPL(intel_iommu_enabled); + + static int dmar_map_gfx = 1; +-static int dmar_map_intgpu = 1; ++static int dmar_map_intgpu = IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON); + static int intel_iommu_superpage = 1; + static int iommu_identity_mapping; + static int iommu_skip_te_disable; +@@ -327,6 +327,7 @@ static int __init intel_iommu_setup(char + while (*str) { + if (!strncmp(str, "on", 2)) { + dmar_disabled = 0; ++ dmar_map_intgpu = 1; + pr_info("IOMMU enabled\n"); + } else if (!strncmp(str, "off", 3)) { + dmar_disabled = 1; diff --git a/debian/patches/features/x86/intel-iommu-add-option-to-exclude-integrated-gpu-only.patch b/debian/patches/features/x86/intel-iommu-add-option-to-exclude-integrated-gpu-only.patch new file mode 100644 index 000000000..a3543d90e --- /dev/null +++ b/debian/patches/features/x86/intel-iommu-add-option-to-exclude-integrated-gpu-only.patch @@ -0,0 +1,90 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 21 Aug 2019 00:05:30 +0100 +Subject: intel-iommu: Add option to exclude integrated GPU only +Bug-Debian: https://bugs.debian.org/935270 +Bug-Kali: https://bugs.kali.org/view.php?id=5644 + +There is still laptop firmware that touches the integrated GPU behind +the operating system's back, and doesn't say so in the RMRR table. +Enabling the IOMMU for all devices causes breakage, but turning it off +for all graphics devices seems like a major weakness. + +Add an option, intel_iommu=intgpu_off, to exclude only integrated GPUs +from remapping. This is a narrower exclusion than igfx_off: it only +affects Intel devices on the root bus. Devices attached through an +external port (Thunderbolt or ExpressCard) won't be on the root bus. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + Documentation/admin-guide/kernel-parameters.txt | 2 ++ + drivers/iommu/intel/iommu.c | 14 ++++++++++++++ + 2 files changed, 16 insertions(+) + +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -2053,6 +2053,8 @@ + bypassed by not enabling DMAR with this option. In + this case, gfx device will use physical address for + DMA. ++ intgpu_off [Default Off] ++ Bypass the DMAR unit for an integrated GPU only. + strict [Default Off] + Deprecated, equivalent to iommu.strict=1. + sp_off [Default Off] +--- a/drivers/iommu/intel/iommu.c ++++ b/drivers/iommu/intel/iommu.c +@@ -35,6 +35,9 @@ + #define CONTEXT_SIZE VTD_PAGE_SIZE + + #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) ++#define IS_INTGPU_DEVICE(pdev) (IS_GFX_DEVICE(pdev) && \ ++ (pdev)->vendor == 0x8086 && \ ++ pci_is_root_bus((pdev)->bus)) + #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB) + #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) + #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) +@@ -293,12 +296,14 @@ int intel_iommu_enabled = 0; + EXPORT_SYMBOL_GPL(intel_iommu_enabled); + + static int dmar_map_gfx = 1; ++static int dmar_map_intgpu = 1; + static int intel_iommu_superpage = 1; + static int iommu_identity_mapping; + static int iommu_skip_te_disable; + + #define IDENTMAP_GFX 2 + #define IDENTMAP_AZALIA 4 ++#define IDENTMAP_INTGPU 8 + + const struct iommu_ops intel_iommu_ops; + +@@ -337,6 +342,9 @@ static int __init intel_iommu_setup(char + } else if (!strncmp(str, "igfx_off", 8)) { + dmar_map_gfx = 0; + pr_info("Disable GFX device mapping\n"); ++ } else if (!strncmp(str, "intgpu_off", 10)) { ++ dmar_map_intgpu = 0; ++ pr_info("Disable integrated GPU device mapping\n"); + } else if (!strncmp(str, "forcedac", 8)) { + pr_warn("intel_iommu=forcedac deprecated; use iommu.forcedac instead\n"); + iommu_dma_forcedac = true; +@@ -2582,6 +2590,9 @@ static int device_def_domain_type(struct + + if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev)) + return IOMMU_DOMAIN_IDENTITY; ++ ++ if ((iommu_identity_mapping & IDENTMAP_INTGPU) && IS_INTGPU_DEVICE(pdev)) ++ return IOMMU_DOMAIN_IDENTITY; + } + + return 0; +@@ -2985,6 +2996,9 @@ static int __init init_dmars(void) + if (!dmar_map_gfx) + iommu_identity_mapping |= IDENTMAP_GFX; + ++ if (!dmar_map_intgpu) ++ iommu_identity_mapping |= IDENTMAP_INTGPU; ++ + check_tylersburg_isoch(); + + ret = si_domain_init(hw_pass_through); diff --git a/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch b/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch new file mode 100644 index 000000000..44dd25261 --- /dev/null +++ b/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch @@ -0,0 +1,180 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 12 Feb 2018 23:59:26 +0000 +Subject: x86: Make x32 syscall support conditional on a kernel parameter +Bug-Debian: https://bugs.debian.org/708070 +Forwarded: https://lore.kernel.org/lkml/1415245982.3398.53.camel@decadent.org.uk/T/#u + +Enabling x32 in the standard amd64 kernel would increase its attack +surface while provide no benefit to the vast majority of its users. +No-one seems interested in regularly checking for vulnerabilities +specific to x32 (at least no-one with a white hat). + +Still, adding another flavour just to turn on x32 seems wasteful. And +the only differences on syscall entry are a few instructions that mask +out the x32 flag and compare the syscall number. + +Use a static key to control whether x32 syscalls are really enabled, a +Kconfig parameter to set its default value and a kernel parameter +"syscall.x32" to change it at boot time. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + .../admin-guide/kernel-parameters.txt | 4 ++ + arch/x86/Kconfig | 8 ++++ + arch/x86/entry/common.c | 3 +- + arch/x86/entry/syscall_64.c | 46 +++++++++++++++++++ + arch/x86/include/asm/elf.h | 6 ++- + arch/x86/include/asm/syscall.h | 13 ++++++ + 6 files changed, 78 insertions(+), 2 deletions(-) + +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -5768,6 +5768,10 @@ + later by a loaded module cannot be set this way. + Example: sysctl.vm.swappiness=40 + ++ syscall.x32= [KNL,x86_64] Enable/disable use of x32 syscalls on ++ an x86_64 kernel where CONFIG_X86_X32 is enabled. ++ Default depends on CONFIG_X86_X32_DISABLED. ++ + sysfs.deprecated=0|1 [KNL] + Enable/disable old style sysfs layout for old udev + on older distributions. When this option is enabled +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -2865,6 +2865,14 @@ config COMPAT_32 + select HAVE_UID16 + select OLD_SIGSUSPEND3 + ++config X86_X32_DISABLED ++ bool "x32 ABI disabled by default" ++ depends on X86_X32_ABI ++ default n ++ help ++ Disable the x32 ABI unless explicitly enabled using the ++ kernel paramter "syscall.x32=y". ++ + config COMPAT + def_bool y + depends on IA32_EMULATION || X86_X32_ABI +--- a/arch/x86/entry/common.c ++++ b/arch/x86/entry/common.c +@@ -62,7 +62,7 @@ static __always_inline bool do_syscall_x + */ + unsigned int xnr = nr - __X32_SYSCALL_BIT; + +- if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) { ++ if (IS_ENABLED(CONFIG_X86_X32_ABI) && unlikely(x32_enabled) && likely(xnr < X32_NR_syscalls)) { + xnr = array_index_nospec(xnr, X32_NR_syscalls); + regs->ax = x32_sys_call_table[xnr](regs); + return true; +--- a/arch/x86/entry/syscall_x32.c ++++ b/arch/x86/entry/syscall_x32.c +@@ -4,6 +4,9 @@ + #include <linux/linkage.h> + #include <linux/sys.h> + #include <linux/cache.h> ++#include <linux/moduleparam.h> ++#undef MODULE_PARAM_PREFIX ++#define MODULE_PARAM_PREFIX "syscall." + #include <linux/syscalls.h> + #include <asm/syscall.h> + +@@ -16,3 +19,46 @@ + asmlinkage const sys_call_ptr_t x32_sys_call_table[] = { + #include <asm/syscalls_x32.h> + }; ++ ++/* Maybe enable x32 syscalls */ ++ ++#if defined(CONFIG_X86_X32_DISABLED) ++DEFINE_STATIC_KEY_FALSE(x32_enabled_skey); ++#else ++DEFINE_STATIC_KEY_TRUE(x32_enabled_skey); ++#endif ++ ++static int __init x32_param_set(const char *val, const struct kernel_param *p) ++{ ++ bool enabled; ++ int ret; ++ ++ ret = kstrtobool(val, &enabled); ++ if (ret) ++ return ret; ++ if (IS_ENABLED(CONFIG_X86_X32_DISABLED)) { ++ if (enabled) { ++ static_key_enable(&x32_enabled_skey.key); ++ pr_info("Enabled x32 syscalls\n"); ++ } ++ } else { ++ if (!enabled) { ++ static_key_disable(&x32_enabled_skey.key); ++ pr_info("Disabled x32 syscalls\n"); ++ } ++ } ++ return 0; ++} ++ ++static int x32_param_get(char *buffer, const struct kernel_param *p) ++{ ++ return sprintf(buffer, "%c\n", ++ static_key_enabled(&x32_enabled_skey) ? 'Y' : 'N'); ++} ++ ++static const struct kernel_param_ops x32_param_ops = { ++ .set = x32_param_set, ++ .get = x32_param_get, ++}; ++ ++arch_param_cb(x32, &x32_param_ops, NULL, 0444); +--- a/arch/x86/include/asm/elf.h ++++ b/arch/x86/include/asm/elf.h +@@ -11,6 +11,9 @@ + #include <asm/user.h> + #include <asm/auxvec.h> + #include <asm/fsgsbase.h> ++#ifndef COMPILE_OFFSETS /* avoid a circular dependency on asm-offsets.h */ ++#include <asm/syscall.h> ++#endif + + typedef unsigned long elf_greg_t; + +@@ -161,7 +164,8 @@ do { \ + + #define compat_elf_check_arch(x) \ + (elf_check_arch_ia32(x) || \ +- (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64)) ++ (IS_ENABLED(CONFIG_X86_X32_ABI) && x32_enabled && \ ++ (x)->e_machine == EM_X86_64)) + + #if __USER32_DS != __USER_DS + # error "The following code assumes __USER32_DS == __USER_DS" +--- a/arch/x86/include/asm/syscall.h ++++ b/arch/x86/include/asm/syscall.h +@@ -13,6 +13,7 @@ + #include <uapi/linux/audit.h> + #include <linux/sched.h> + #include <linux/err.h> ++#include <linux/jump_label.h> + #include <asm/thread_info.h> /* for TS_COMPAT */ + #include <asm/unistd.h> + +@@ -30,6 +31,18 @@ extern const sys_call_ptr_t ia32_sys_cal + extern const sys_call_ptr_t x32_sys_call_table[]; + #endif + ++#if defined(CONFIG_X86_X32_ABI) ++#if defined(CONFIG_X86_X32_DISABLED) ++DECLARE_STATIC_KEY_FALSE(x32_enabled_skey); ++#define x32_enabled static_branch_unlikely(&x32_enabled_skey) ++#else ++DECLARE_STATIC_KEY_TRUE(x32_enabled_skey); ++#define x32_enabled static_branch_likely(&x32_enabled_skey) ++#endif ++#else ++#define x32_enabled 0 ++#endif ++ + /* + * Only the low 32 bits of orig_ax are meaningful, so we return int. + * This importantly ignores the high bits on 64-bit, so comparisons diff --git a/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch b/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch new file mode 100644 index 000000000..7a7952003 --- /dev/null +++ b/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch @@ -0,0 +1,28 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 5 Dec 2011 04:00:58 +0000 +Subject: x86: memtest: WARN if bad RAM found +Bug-Debian: https://bugs.debian.org/613321 +Forwarded: http://thread.gmane.org/gmane.linux.kernel/1286471 + +Since this is not a particularly thorough test, if we find any bad +bits of RAM then there is a fair chance that there are other bad bits +we fail to detect. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/memtest.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +--- a/mm/memtest.c ++++ b/mm/memtest.c +@@ -26,6 +26,10 @@ static u64 patterns[] __initdata = { + + static void __init reserve_bad_mem(u64 pattern, phys_addr_t start_bad, phys_addr_t end_bad) + { ++#ifdef CONFIG_X86 ++ WARN_ONCE(1, "Bad RAM detected. Use memtest86+ to perform a thorough test\n" ++ "and the memmap= parameter to reserve the bad areas."); ++#endif + pr_info(" %016llx bad mem addr %pa - %pa reserved\n", + cpu_to_be64(pattern), &start_bad, &end_bad); + memblock_reserve(start_bad, end_bad - start_bad); |