An of_node can be duplicated from an existing device using
device_set_of_node_from_dev() or initialized using device_set_node()
In both cases, these functions have to be called before the device_add()
call in order to have the of_node link created in the device sysfs
directory. Further more, these function cannot prevent any of_node
and/or fwnode overwrites.
When adding an of_node on an already present device, the following
operations need to be done:
- Attach the of_node if no of_node were already attached
- Attach the of_node as a fwnode if no fwnode were already attached
- Create the of_node sysfs link if needed
This is the purpose of device_add_of_node().
device_remove_of_node() reverts the operations done by
device_add_of_node().
Cc: stable(a)vger.kernel.org
Signed-off-by: Herve Codina <herve.codina(a)bootlin.com>
---
drivers/base/core.c | 74 ++++++++++++++++++++++++++++++++++++++++++
include/linux/device.h | 2 ++
2 files changed, 76 insertions(+)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 2926f3b1f868..ac026187ac6a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -5046,6 +5046,80 @@ void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
}
EXPORT_SYMBOL_GPL(set_secondary_fwnode);
+/**
+ * device_remove_of_node - Remove an of_node from a device
+ * @dev: device whose device-tree node is being removed
+ */
+void device_remove_of_node(struct device *dev)
+{
+ dev = get_device(dev);
+ if (!dev)
+ return;
+
+ if (!dev->of_node)
+ goto end;
+
+ sysfs_remove_link(&dev->kobj, "of_node");
+
+ if (dev->fwnode == of_fwnode_handle(dev->of_node))
+ dev->fwnode = NULL;
+
+ of_node_put(dev->of_node);
+ dev->of_node = NULL;
+
+end:
+ put_device(dev);
+}
+EXPORT_SYMBOL_GPL(device_remove_of_node);
+
+/**
+ * device_add_of_node - Add an of_node to an existing device
+ * @dev: device whose device-tree node is being added
+ * @of_node: of_node to add
+ */
+void device_add_of_node(struct device *dev, struct device_node *of_node)
+{
+ int ret;
+
+ if (!of_node)
+ return;
+
+ dev = get_device(dev);
+ if (!dev)
+ return;
+
+ if (dev->of_node) {
+ dev_warn(dev, "Replace node %pOF with %pOF\n", dev->of_node, of_node);
+ device_remove_of_node(dev);
+ }
+
+ dev->of_node = of_node_get(of_node);
+
+ if (!dev->fwnode)
+ dev->fwnode = of_fwnode_handle(of_node);
+
+ if (!dev->p) {
+ /*
+ * device_add() was not previously called.
+ * The of_node link will be created when device_add() is called.
+ */
+ goto end;
+ }
+
+ /*
+ * device_add() was previously called and so the of_node link was not
+ * created by device_add_class_symlinks().
+ * Create this link now.
+ */
+ ret = sysfs_create_link(&dev->kobj, of_node_kobj(of_node), "of_node");
+ if (ret)
+ dev_warn(dev, "Error %d creating of_node link\n", ret);
+
+end:
+ put_device(dev);
+}
+EXPORT_SYMBOL_GPL(device_add_of_node);
+
/**
* device_set_of_node_from_dev - reuse device-tree node of another device
* @dev: device whose device-tree node is being set
diff --git a/include/linux/device.h b/include/linux/device.h
index d7a72a8749ea..2b093e62907a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1128,6 +1128,8 @@ int device_offline(struct device *dev);
int device_online(struct device *dev);
void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode);
+void device_add_of_node(struct device *dev, struct device_node *of_node);
+void device_remove_of_node(struct device *dev);
void device_set_of_node_from_dev(struct device *dev, const struct device *dev2);
void device_set_node(struct device *dev, struct fwnode_handle *fwnode);
--
2.42.0
The commit 407d1a51921e ("PCI: Create device tree node for bridge")
creates of_node for PCI devices.
During the insertion handling of these new DT nodes done by of_platform,
new devices (struct device) are created.
For each PCI devices a struct device is already present (created and
handled by the PCI core).
Having a second struct device to represent the exact same PCI device is
not correct.
On the of_node creation, tell the of_platform that there is no need to
create a device for this node (OF_POPULATED flag), link this newly
created of_node to the already present device and tell fwnode that the
device attached to this of_node is ready (fwnode_dev_initialized()).
With this fix, the of_node are available in the sysfs device tree:
/sys/devices/platform/soc/d0070000.pcie/
+ of_node -> .../devicetree/base/soc/pcie@d0070000
+ pci0000:00
+ 0000:00:00.0
+ of_node -> .../devicetree/base/soc/pcie@d0070000/pci@0,0
+ 0000:01:00.0
+ of_node -> .../devicetree/base/soc/pcie@d0070000/pci@0,0/dev@0,0
On the of_node removal, revert the operations.
Fixes: 407d1a51921e ("PCI: Create device tree node for bridge")
Cc: stable(a)vger.kernel.org
Signed-off-by: Herve Codina <herve.codina(a)bootlin.com>
---
drivers/pci/of.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 51e3dd0ea5ab..5afd2731e876 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -615,7 +615,8 @@ void of_pci_remove_node(struct pci_dev *pdev)
np = pci_device_to_OF_node(pdev);
if (!np || !of_node_check_flag(np, OF_DYNAMIC))
return;
- pdev->dev.of_node = NULL;
+
+ device_remove_of_node(&pdev->dev);
of_changeset_revert(np->data);
of_changeset_destroy(np->data);
@@ -668,12 +669,22 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
if (ret)
goto out_free_node;
+ /*
+ * This of_node will be added to an existing device.
+ * Avoid any device creation and use the existing device
+ */
+ of_node_set_flag(np, OF_POPULATED);
+ np->fwnode.dev = &pdev->dev;
+ fwnode_dev_initialized(&np->fwnode, true);
+
ret = of_changeset_apply(cset);
if (ret)
goto out_free_node;
np->data = cset;
- pdev->dev.of_node = np;
+
+ /* Add the of_node to the existing device */
+ device_add_of_node(&pdev->dev, np);
kfree(name);
return;
--
2.42.0
The patch titled
Subject: highmem: fix a memory copy problem in memcpy_from_folio
has been added to the -mm mm-hotfixes-unstable branch. Its filename is
highmem-fix-a-memory-copy-problem-in-memcpy_from_folio.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patche…
This patch will later appear in the mm-hotfixes-unstable branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days
------------------------------------------------------
From: Su Hui <suhui(a)nfschina.com>
Subject: highmem: fix a memory copy problem in memcpy_from_folio
Date: Thu, 30 Nov 2023 11:40:18 +0800
Clang static checker complains that value stored to 'from' is never read.
And memcpy_from_folio() only copy the last chunk memory from folio to
destination. Use 'to += chunk' to replace 'from += chunk' to fix this
typo problem.
Link: https://lkml.kernel.org/r/20231130034017.1210429-1-suhui@nfschina.com
Fixes: b23d03ef7af5 ("highmem: add memcpy_to_folio() and memcpy_from_folio()")
Signed-off-by: Su Hui <suhui(a)nfschina.com>
Reviewed-by: Matthew Wilcox (Oracle) <willy(a)infradead.org>
Cc: Ira Weiny <ira.weiny(a)intel.com>
Cc: Jiaqi Yan <jiaqiyan(a)google.com>
Cc: Nathan Chancellor <nathan(a)kernel.org>
Cc: Nick Desaulniers <ndesaulniers(a)google.com>
Cc: Peter Collingbourne <pcc(a)google.com>
Cc: Tom Rix <trix(a)redhat.com>
Cc: Tony Luck <tony.luck(a)intel.com>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
include/linux/highmem.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/linux/highmem.h~highmem-fix-a-memory-copy-problem-in-memcpy_from_folio
+++ a/include/linux/highmem.h
@@ -454,7 +454,7 @@ static inline void memcpy_from_folio(cha
memcpy(to, from, chunk);
kunmap_local(from);
- from += chunk;
+ to += chunk;
offset += chunk;
len -= chunk;
} while (len > 0);
_
Patches currently in -mm which might be from suhui(a)nfschina.com are
highmem-fix-a-memory-copy-problem-in-memcpy_from_folio.patch
From: Ashwin Dayanand Kamat <ashwin.kamat(a)broadcom.com>
kernel crash was observed because of page fault, while running
cpuhotplug ltp testcases on SEV-ES enabled systems. The crash was
observed during hotplug after the CPU was offlined and the process
was migrated to different cpu. setup_ghcb() is called again which
tries to update ghcb_version in sev_es_negotiate_protocol(). Ideally this
is a read_only variable which is initialised during booting.
This results in pagefault.
From logs,
[ 256.447466] BUG: unable to handle page fault for address: ffffffffba556e70
[ 256.447476] #PF: supervisor write access in kernel mode
[ 256.447478] #PF: error_code(0x0003) - permissions violation
[ 256.447479] PGD 8000667c0f067 P4D 8000667c0f067 PUD 8000667c10063 PMD 80080006674001e1
[ 256.447483] Oops: 0003 [#1] PREEMPT SMP NOPTI
[ 256.447487] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.1.45-8.ph5 #1-photon
.
.
.
.
.
[ 256.447511] CR2: ffffffffba556e70 CR3: 0008000667c0a004 CR4: 0000000000770ee0
[ 256.447514] PKRU: 55555554
[ 256.447515] Call Trace:
[ 256.447516] <TASK>
[ 256.447519] ? __die_body.cold+0x1a/0x1f
[ 256.447526] ? __die+0x2a/0x35
[ 256.447528] ? page_fault_oops+0x10c/0x270
[ 256.447531] ? setup_ghcb+0x71/0x100
[ 256.447533] ? __x86_return_thunk+0x5/0x6
[ 256.447537] ? search_exception_tables+0x60/0x70
[ 256.447541] ? __x86_return_thunk+0x5/0x6
[ 256.447543] ? fixup_exception+0x27/0x320
[ 256.447546] ? kernelmode_fixup_or_oops+0xa2/0x120
[ 256.447549] ? __bad_area_nosemaphore+0x16a/0x1b0
[ 256.447551] ? kernel_exc_vmm_communication+0x60/0xb0
[ 256.447556] ? bad_area_nosemaphore+0x16/0x20
[ 256.447558] ? do_kern_addr_fault+0x7a/0x90
[ 256.447560] ? exc_page_fault+0xbd/0x160
[ 256.447563] ? asm_exc_page_fault+0x27/0x30
[ 256.447570] ? setup_ghcb+0x71/0x100
[ 256.447572] ? setup_ghcb+0xe/0x100
[ 256.447574] cpu_init_exception_handling+0x1b9/0x1f0
Fix is to call sev_es_negotiate_protocol() only in the BSP boot phase (and
it only needs to be done once)
Fixes: 95d33bfaa3e1 ("x86/sev: Register GHCB memory when SEV-SNP is active")
Co-developed-by: Bo Gan <bo.gan(a)broadcom.com>
Signed-off-by: Bo Gan <bo.gan(a)broadcom.com>
Signed-off-by: Ashwin Dayanand Kamat <ashwin.kamat(a)broadcom.com>
---
v2:
As per the review comments given by Tom Lendacky, did below changes in v2,
- Moved sev_es_negotiate_protocol() after initial_vc_handler if-check in setup_ghcb()
- Added Signed-off of Co-developer
---
arch/x86/kernel/sev.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index 70472eebe719..c67285824e82 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -1234,10 +1234,6 @@ void setup_ghcb(void)
if (!cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
return;
- /* First make sure the hypervisor talks a supported protocol. */
- if (!sev_es_negotiate_protocol())
- sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);
-
/*
* Check whether the runtime #VC exception handler is active. It uses
* the per-CPU GHCB page which is set up by sev_es_init_vc_handling().
@@ -1254,6 +1250,13 @@ void setup_ghcb(void)
return;
}
+ /*
+ * Make sure the hypervisor talks a supported protocol.
+ * This gets called only in the BSP boot phase.
+ */
+ if (!sev_es_negotiate_protocol())
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);
+
/*
* Clear the boot_ghcb. The first exception comes in before the bss
* section is cleared.
--
2.39.0
Hi,
the following patch:
b4a778303ea0 serial: sc16is7xx: add missing support for rs485
devicetree properties
Was introduced in kernel 6.5.
Without it, the rs485 devicetree properties are not applied and the
RS-485 ports do not work.
I would like it to be applied to the stable kernel 6.1.
It applies cleanly and was tested on this kernel using a
custom board with a Variscite IMX8MN NANO SOM, a NewHaven LCD, and two
SC16IS752 on a SPI bus. The four UARTs are using RS-485 mode.
Thank you,
Hugo Villeneuve
Hi,
the following patch:
77a82cebf0eb serial: sc16is7xx: Put IOControl register into
regmap_volatile
Was introduced in kernel 6.5.
Without it, the debugfs register display can be incorrect for this
register.
I would like it to be applied to the stable kernel 6.1.
It applies cleanly and was tested on this kernel using a
custom board with a Variscite IMX8MN NANO SOM, a NewHaven LCD, and two
SC16IS752 on a SPI bus.
Thank you,
Hugo Villeneuve
Hi,
the following patch:
35b464e32c8b auxdisplay: hd44780: move cursor home after clear display
command
Was introduced in kernel 6.6.
Without it, the LCD messages are not displayed in the correct
position.
I would like it to be applied to the stable kernel 6.1.
The patch applies cleanly and was tested on this kernel using a
custom board with a Variscite IMX8MN NANO SOM and a NewHaven LCD.
Thank you,
Hugo Villeneuve
The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.4.y
git checkout FETCH_HEAD
git cherry-pick -x d6fef34ee4d102be448146f24caf96d7b4a05401
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable(a)vger.kernel.org>' --in-reply-to '2023113025-eastbound-uninstall-c2e0@gregkh' --subject-prefix 'PATCH 5.4.y' HEAD^..
Possible dependencies:
d6fef34ee4d1 ("io_uring: fix off-by one bvec index")
57bebf807e2a ("io_uring/rsrc: optimise registered huge pages")
b000ae0ec2d7 ("io_uring/rsrc: optimise single entry advance")
c059f7858408 ("io_uring: move io_import_fixed()")
f337a84d3952 ("io_uring: opcode independent fixed buf import")
f3b44f92e59a ("io_uring: move read/write related opcodes to its own file")
c98817e6cd44 ("io_uring: move remaining file table manipulation to filetable.c")
735729844819 ("io_uring: move rsrc related data, core, and commands")
3b77495a9723 ("io_uring: split provided buffers handling into its own file")
7aaff708a768 ("io_uring: move cancelation into its own file")
329061d3e2f9 ("io_uring: move poll handling into its own file")
cfd22e6b3319 ("io_uring: add opcode name to io_op_defs")
92ac8beaea1f ("io_uring: include and forward-declaration sanitation")
c9f06aa7de15 ("io_uring: move io_uring_task (tctx) helpers into its own file")
a4ad4f748ea9 ("io_uring: move fdinfo helpers to its own file")
e5550a1447bf ("io_uring: use io_is_uring_fops() consistently")
17437f311490 ("io_uring: move SQPOLL related handling into its own file")
59915143e89f ("io_uring: move timeout opcodes and handling into its own file")
e418bbc97bff ("io_uring: move our reference counting into a header")
36404b09aa60 ("io_uring: move msg_ring into its own file")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d6fef34ee4d102be448146f24caf96d7b4a05401 Mon Sep 17 00:00:00 2001
From: Keith Busch <kbusch(a)kernel.org>
Date: Mon, 20 Nov 2023 14:18:31 -0800
Subject: [PATCH] io_uring: fix off-by one bvec index
If the offset equals the bv_len of the first registered bvec, then the
request does not include any of that first bvec. Skip it so that drivers
don't have to deal with a zero length bvec, which was observed to break
NVMe's PRP list creation.
Cc: stable(a)vger.kernel.org
Fixes: bd11b3a391e3 ("io_uring: don't use iov_iter_advance() for fixed buffers")
Signed-off-by: Keith Busch <kbusch(a)kernel.org>
Link: https://lore.kernel.org/r/20231120221831.2646460-1-kbusch@meta.com
Signed-off-by: Jens Axboe <axboe(a)kernel.dk>
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index 7034be555334..f521c5965a93 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -1258,7 +1258,7 @@ int io_import_fixed(int ddir, struct iov_iter *iter,
*/
const struct bio_vec *bvec = imu->bvec;
- if (offset <= bvec->bv_len) {
+ if (offset < bvec->bv_len) {
/*
* Note, huge pages buffers consists of one large
* bvec entry and should always go this way. The other