From: Simon Glass <sjg@chromium.org>
The extlinux and PXE drivers allocate a pxe_context in priv but never
free it on device removal, leaking the bootdir string and any parsed
menu.
Add extlinux_bootmeth_remove() which frees the context, shared by both
drivers. Move the VBE driver to use a pxe_context embedded in its own
abrec_priv, since extlinux_plat no longer contains it.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
boot/bootmeth_extlinux.c | 12 ++++++++++++
boot/bootmeth_pxe.c | 1 +
boot/vbe_abrec.h | 4 ++++
boot/vbe_abrec_os.c | 8 ++++----
include/extlinux.h | 10 ++++++++++
5 files changed, 31 insertions(+), 4 deletions(-)
@@ -233,6 +233,17 @@ static int extlinux_local_read_all(struct udevice *dev, struct bootflow *bflow)
}
#endif
+int extlinux_bootmeth_remove(struct udevice *dev)
+{
+ struct extlinux_priv *priv = dev_get_priv(dev);
+
+ if (priv->ctx.cfg)
+ pxe_menu_uninit(priv->ctx.cfg);
+ pxe_destroy_ctx(&priv->ctx);
+
+ return 0;
+}
+
static int extlinux_bootmeth_bind(struct udevice *dev)
{
struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
@@ -267,6 +278,7 @@ U_BOOT_DRIVER(bootmeth_1extlinux) = {
.of_match = extlinux_bootmeth_ids,
.ops = &extlinux_bootmeth_ops,
.bind = extlinux_bootmeth_bind,
+ .remove = extlinux_bootmeth_remove,
.plat_auto = sizeof(struct extlinux_plat),
.priv_auto = sizeof(struct extlinux_priv),
};
@@ -193,6 +193,7 @@ U_BOOT_DRIVER(bootmeth_zpxe) = {
.of_match = extlinux_bootmeth_pxe_ids,
.ops = &extlinux_bootmeth_pxe_ops,
.bind = extlinux_bootmeth_pxe_bind,
+ .remove = extlinux_bootmeth_remove,
.plat_auto = sizeof(struct extlinux_plat),
.priv_auto = sizeof(struct extlinux_priv),
};
@@ -9,6 +9,8 @@
#ifndef __VBE_ABREC_H
#define __VBE_ABREC_H
+#include <pxe_utils.h>
+
#include <vbe.h>
#include <dm/ofnode_decl.h>
@@ -34,6 +36,7 @@ struct udevice;
* @version_size: Size of the version info
* @storage: Storage device to use, in the form <uclass><devnum>, e.g. "mmc1"
* @oem_devicetree: true if we should read an OEM devicetree
+ * @ctx: PXE context for extlinux boot/read_all
*/
struct abrec_priv {
u32 area_start;
@@ -45,6 +48,7 @@ struct abrec_priv {
u32 version_size;
const char *storage;
bool oem_devicetree;
+ struct pxe_context ctx;
};
/** struct abrec_state - state information read from media
@@ -204,7 +204,7 @@ err_buf:
static int vbe_abrec_boot(struct udevice *dev, struct bootflow *bflow)
{
- struct extlinux_plat *plat = dev_get_plat(dev);
+ struct abrec_priv *priv = dev_get_priv(dev);
const struct bootflow_img *img;
int ret;
@@ -231,16 +231,16 @@ static int vbe_abrec_boot(struct udevice *dev, struct bootflow *bflow)
printf("Loading OS FIT%s\n", img ? " keeping existing FDT" : "");
- return extlinux_boot(dev, bflow, &plat->ctx, vbe_abrec_getfile, true,
+ return extlinux_boot(dev, bflow, &priv->ctx, vbe_abrec_getfile, true,
bflow->fname, img);
}
#if CONFIG_IS_ENABLED(BOOTSTD_FULL)
static int vbe_abrec_read_all(struct udevice *dev, struct bootflow *bflow)
{
- struct extlinux_plat *plat = dev_get_plat(dev);
+ struct abrec_priv *priv = dev_get_priv(dev);
- return extlinux_read_all(dev, bflow, &plat->ctx, vbe_abrec_getfile,
+ return extlinux_read_all(dev, bflow, &priv->ctx, vbe_abrec_getfile,
true, bflow->fname);
}
#endif
@@ -42,6 +42,16 @@ struct extlinux_priv {
struct pxe_context ctx;
};
+/**
+ * extlinux_bootmeth_remove() - Remove function for extlinux-based bootmeths
+ *
+ * Frees the PXE context. Shared by extlinux and PXE drivers.
+ *
+ * @dev: Bootmethod device
+ * Return: 0 if OK
+ */
+int extlinux_bootmeth_remove(struct udevice *dev);
+
/**
* extlinux_set_property() - set an extlinux property
*