lib: logic_pio: Avoid possible overlap for unregistering regions [Linux 4.19.70]

This Linux kernel change "lib: logic_pio: Avoid possible overlap for unregistering regions" is included in the Linux 4.19.70 release. This change is authored by John Garry <john.garry [at] huawei.com> on Tue Jul 30 21:29:53 2019 +0800. The commit for this change in Linux stable tree is 7faef13 (patch) which is from upstream commit 0a27142. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 0a27142.

lib: logic_pio: Avoid possible overlap for unregistering regions

commit 0a27142bd1ee259e24a0be2b0133e5ca5df8da91 upstream.

The code was originally written to not support unregistering logical PIO
regions.

To accommodate supporting unregistering logical PIO regions, subtly modify
LOGIC_PIO_CPU_MMIO region registration code, such that the "end" of the
registered regions is the "end" of the last region, and not the sum of
the sizes of all the registered regions.

Cc: stable@vger.kernel.org
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Wei Xu <xuwei5@hisilicon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 10 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 lib/logic_pio.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/logic_pio.c b/lib/logic_pio.c
index 7612963..d0165c8 100644
--- a/lib/logic_pio.c
+++ b/lib/logic_pio.c
@@ -35,7 +35,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
    struct logic_pio_hwaddr *range;
    resource_size_t start;
    resource_size_t end;
-   resource_size_t mmio_sz = 0;
+   resource_size_t mmio_end = 0;
    resource_size_t iio_sz = MMIO_UPPER_LIMIT;
    int ret = 0;

@@ -56,7 +56,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
            /* for MMIO ranges we need to check for overlap */
            if (start >= range->hw_start + range->size ||
                end < range->hw_start) {
-               mmio_sz += range->size;
+               mmio_end = range->io_start + range->size;
            } else {
                ret = -EFAULT;
                goto end_register;
@@ -69,16 +69,16 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)

    /* range not registered yet, check for available space */
    if (new_range->flags == LOGIC_PIO_CPU_MMIO) {
-       if (mmio_sz + new_range->size - 1 > MMIO_UPPER_LIMIT) {
+       if (mmio_end + new_range->size - 1 > MMIO_UPPER_LIMIT) {
            /* if it's too big check if 64K space can be reserved */
-           if (mmio_sz + SZ_64K - 1 > MMIO_UPPER_LIMIT) {
+           if (mmio_end + SZ_64K - 1 > MMIO_UPPER_LIMIT) {
                ret = -E2BIG;
                goto end_register;
            }
            new_range->size = SZ_64K;
            pr_warn("Requested IO range too big, new size set to 64K\n");
        }
-       new_range->io_start = mmio_sz;
+       new_range->io_start = mmio_end;
    } else if (new_range->flags == LOGIC_PIO_INDIRECT) {
        if (iio_sz + new_range->size - 1 > IO_SPACE_LIMIT) {
            ret = -E2BIG;

Leave a Reply

Your email address will not be published. Required fields are marked *