Commit cb7400a1 authored by Dimitris Lampridis's avatar Dimitris Lampridis

[sw][kernel] respect stack frame limit

spec_fpga_app_init() declares too many local buffers that are allocated on the stack.

On some versions of GCC this is detected and reported, causing a warning that is promoted to an
error. Example:

spec-core-fpga.c:792:1: error: the frame size of 1888 bytes is larger than 1024 bytes
[-Werror=frame-larger-than=]

Since apparently it is not a very good idea to increase the stack frame size limit [1], the solution
implemented here is to switch to dynimically allocating the biggest buffer (struct resource res[]).

[1]: https://gcc.gnu.org/onlinedocs/gccint/Stack-Checking.html#Stack-Checking
"The maximum size of a stack frame, in bytes. GCC will generate probe instructions in non-leaf
functions to ensure at least this many bytes of stack are available. If a stack frame is larger than
this size, stack checking will not be reliable and GCC will issue a warning. The default is chosen
so that GCC only generates one instruction on most systems. You should normally not change the
default value of this macro."
Signed-off-by: Dimitris Lampridis's avatarDimitris Lampridis <dimitris.lampridis@cern.ch>
parent b32ff992
...@@ -733,22 +733,32 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga) ...@@ -733,22 +733,32 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga)
#define SPEC_FPGA_APP_RES_N (32 - SPEC_FPGA_APP_IRQ_BASE + 1) #define SPEC_FPGA_APP_RES_N (32 - SPEC_FPGA_APP_IRQ_BASE + 1)
struct pci_dev *pcidev = to_pci_dev(spec_fpga->dev.parent); struct pci_dev *pcidev = to_pci_dev(spec_fpga->dev.parent);
unsigned int res_n = SPEC_FPGA_APP_RES_N; unsigned int res_n = SPEC_FPGA_APP_RES_N;
struct resource res[SPEC_FPGA_APP_RES_N] = { struct resource *res;
[0] = { /* struct resource res[SPEC_FPGA_APP_RES_N] = { */
.name = "app-mem", /* [0] = { */
.flags = IORESOURCE_MEM, /* .name = "app-mem", */
}, /* .flags = IORESOURCE_MEM, */
}; /* }, */
/* }; */
struct platform_device *pdev; struct platform_device *pdev;
struct irq_domain *vic_domain; struct irq_domain *vic_domain;
char app_name[SPEC_FPGA_APP_NAME_MAX]; char app_name[SPEC_FPGA_APP_NAME_MAX];
unsigned long app_offset; unsigned long app_offset;
int err; int err = 0;
res = kzalloc(SPEC_FPGA_APP_RES_N * sizeof(struct resource), GFP_KERNEL);
if (!res) {
return -ENOMEM;
}
res[0].name = "app-mem";
res[0].flags = IORESOURCE_MEM;
app_offset = spec_fpga_csr_app_offset(spec_fpga); app_offset = spec_fpga_csr_app_offset(spec_fpga);
if (!app_offset) { if (!app_offset) {
dev_warn(&spec_fpga->dev, "Application not found\n"); dev_warn(&spec_fpga->dev, "Application not found\n");
return 0; err = 0;
goto err_free;
} }
res[0].start = pci_resource_start(pcidev, 0) + app_offset; res[0].start = pci_resource_start(pcidev, 0) + app_offset;
...@@ -777,18 +787,21 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga) ...@@ -777,18 +787,21 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga)
err = spec_fpga_app_id_build(spec_fpga, app_offset, err = spec_fpga_app_id_build(spec_fpga, app_offset,
app_name, SPEC_FPGA_APP_NAME_MAX); app_name, SPEC_FPGA_APP_NAME_MAX);
if (err) if (err)
return err; goto err_free;
spec_fpga_app_restart(spec_fpga); spec_fpga_app_restart(spec_fpga);
pdev = platform_device_register_resndata(&spec_fpga->dev, pdev = platform_device_register_resndata(&spec_fpga->dev,
app_name, PLATFORM_DEVID_AUTO, app_name, PLATFORM_DEVID_AUTO,
res, res_n, res, res_n,
NULL, 0); NULL, 0);
if (IS_ERR(pdev)) err = IS_ERR(pdev);
return PTR_ERR(pdev); if (err)
goto err_free;
spec_fpga->app_pdev = pdev; spec_fpga->app_pdev = pdev;
return 0; err_free:
kfree(res);
return err;
} }
static void spec_fpga_app_exit(struct spec_fpga *spec_fpga) static void spec_fpga_app_exit(struct spec_fpga *spec_fpga)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment