[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/4] xen/arm: acpi: The fixmap area should always be cleared during failure/unmap


  • To: Julien Grall <julien@xxxxxxx>
  • From: Rahul Singh <Rahul.Singh@xxxxxxx>
  • Date: Tue, 29 Sep 2020 11:13:54 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KY64bThEoQ45wXpxRhVEap8LYQRwMReVDmAlFxeimoc=; b=dBBrLyxITIpSikGj7kl49ona0rKluRq9y2jfttRwicLS2FvTeGdIaYFfj1y+7IVmc7SXgtTVm5nnAyWRfg7TYOLzgOTLIt5bJhvZjNqsX7MyVNvBN9hvJ762BWwj+5NtaRXAqc/QXC7cKQriI9hW4seK5WnjBH7c3LJvu2fSbols/Ay7PZwhto8FEesgYNzkLIjZixAOH8Wn8c5A/2GnUyev2yOTJF2gI1niUttEYpMIQb15KEsg7osUSczu7epQHqetj7O16hOwGURuoJIthCu1UURAHehVZ+UJ4BpX3gSQNz1TrfgBFKyw3fNu87B9NPd3XSSHA8/+ZYbNr6GrcA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CDNyAH8nsJUz/IqhdUJOJ19QzLOy2PSre6BouB5AqywnEgTByhMNjb4P/Z4khqNTeGqegZrfeWGhdnz2el3YBudDDPclvUV1mmpGyrqJPvVhvncglBOEg9TGQGJnD7dPA0CNbEUHLHaD2QX2OxM60Rutv0pH/HVs4hKnUBhnzhrV+RYDxDttwIaTjDi4YqIhzrl6nwZcs+PDzBiNfsW62urmYPUmaQrgE19XsWFCMZR8S5uGSOhyazru6n7odafa15nGL1fHYdjpHaFs5e/IIXAjwcbG/px3xX8xaAM1fijDhRsMfKgFmsLIWl9fzvgKTNQ3knEDHeth7Zp3+IJOGA==
  • Authentication-results-original: xen.org; dkim=none (message not signed) header.d=none;xen.org; dmarc=none action=none header.from=arm.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, "alex.bennee@xxxxxxxxxx" <alex.bennee@xxxxxxxxxx>, "masami.hiramatsu@xxxxxxxxxx" <masami.hiramatsu@xxxxxxxxxx>, "ehem+xen@xxxxxxx" <ehem+xen@xxxxxxx>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, Andre Przywara <Andre.Przywara@xxxxxxx>, Julien Grall <jgrall@xxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Wei Xu <xuwei5@xxxxxxxxxxxxx>
  • Delivery-date: Tue, 29 Sep 2020 11:14:19 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: xen.org; dkim=none (message not signed) header.d=none;xen.org; dmarc=none action=none header.from=arm.com;
  • Thread-index: AQHWlEfKCl2/BWPbZ0mt0x0/DJ/LAql/equA
  • Thread-topic: [PATCH 2/4] xen/arm: acpi: The fixmap area should always be cleared during failure/unmap

Hello,

> On 26 Sep 2020, at 9:55 pm, Julien Grall <julien@xxxxxxx> wrote:
> 
> From: Julien Grall <jgrall@xxxxxxxxxx>
> 
> Commit 022387ee1ad3 "xen/arm: mm: Don't open-code Xen PT update in
> {set, clear}_fixmap()" enforced that each set_fixmap() should be
> paired with a clear_fixmap(). Any failure to follow the model would
> result to a platform crash.
> 
> Unfortunately, the use of fixmap in the ACPI code was overlooked as it
> is calling set_fixmap() but not clear_fixmap().
> 
> The function __acpi_os_map_table() is reworked so:
>    - We know before the mapping whether the fixmap region is big
>    enough for the mapping.
>    - It will fail if the fixmap is always inuse.
> 
> The function __acpi_os_unmap_table() will now call clear_fixmap().
> 
> Reported-by: Wei Xu <xuwei5@xxxxxxxxxxxxx>
> Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx>

Reviewed-by: Rahul Singh <rahul.singh@xxxxxxx>
Tested-by: Rahul Singh <rahul.singh@xxxxxxx>

> 
> ---
> 
> The discussion on the original thread [1] suggested to also zap it on
> x86. This is technically not necessary today, so it is left alone for
> now.
> 
> I looked at making the fixmap code common but the index are inverted
> between Arm and x86.
> 
> [1] https://lore.kernel.org/xen-devel/5E26C935.9080107@xxxxxxxxxxxxx/
> ---
> xen/arch/arm/acpi/lib.c | 75 +++++++++++++++++++++++++++++++----------
> 1 file changed, 58 insertions(+), 17 deletions(-)
> 
> diff --git a/xen/arch/arm/acpi/lib.c b/xen/arch/arm/acpi/lib.c
> index 2192a5519171..eebaca695562 100644
> --- a/xen/arch/arm/acpi/lib.c
> +++ b/xen/arch/arm/acpi/lib.c
> @@ -25,38 +25,79 @@
> #include <xen/init.h>
> #include <xen/mm.h>
> 
> +static bool fixmap_inuse;
> +
> char *__acpi_map_table(paddr_t phys, unsigned long size)
> {
> -    unsigned long base, offset, mapped_size;
> -    int idx;
> +    unsigned long base, offset;
> +    mfn_t mfn;
> +    unsigned int idx;
> 
>     /* No arch specific implementation after early boot */
>     if ( system_state >= SYS_STATE_boot )
>         return NULL;
> 
>     offset = phys & (PAGE_SIZE - 1);
> -    mapped_size = PAGE_SIZE - offset;
> -    set_fixmap(FIXMAP_ACPI_BEGIN, maddr_to_mfn(phys), PAGE_HYPERVISOR);
> -    base = FIXMAP_ADDR(FIXMAP_ACPI_BEGIN);
> +    base = FIXMAP_ADDR(FIXMAP_ACPI_BEGIN) + offset;
> +
> +    /* Check the fixmap is big enough to map the region */
> +    if ( (FIXMAP_ADDR(FIXMAP_ACPI_END) + PAGE_SIZE - base) < size )
> +        return NULL;
> +
> +    /* With the fixmap, we can only map one region at the time */
> +    if ( fixmap_inuse )
> +        return NULL;
> 
> -    /* Most cases can be covered by the below. */
> +    fixmap_inuse = true;
> +
> +    size += offset;
> +    mfn = maddr_to_mfn(phys);
>     idx = FIXMAP_ACPI_BEGIN;
> -    while ( mapped_size < size )
> -    {
> -        if ( ++idx > FIXMAP_ACPI_END )
> -            return NULL;    /* cannot handle this */
> -        phys += PAGE_SIZE;
> -        set_fixmap(idx, maddr_to_mfn(phys), PAGE_HYPERVISOR);
> -        mapped_size += PAGE_SIZE;
> -    }
> 
> -    return ((char *) base + offset);
> +    do {
> +        set_fixmap(idx, mfn, PAGE_HYPERVISOR);
> +        size -= min(size, (unsigned long)PAGE_SIZE);
> +        mfn = mfn_add(mfn, 1);
> +        idx++;
> +    } while ( size > 0 );
> +
> +    return (char *)base;
> }
> 
> bool __acpi_unmap_table(void *ptr, unsigned long size)
> {
> -    return ( vaddr >= FIXMAP_ADDR(FIXMAP_ACPI_BEGIN) &&
> -             vaddr < (FIXMAP_ADDR(FIXMAP_ACPI_END) + PAGE_SIZE) );
> +    vaddr_t vaddr = (vaddr_t)ptr;
> +    unsigned int idx;
> +
> +    /* We are only handling fixmap address in the arch code */
> +    if ( vaddr < FIXMAP_ADDR(FIXMAP_ACPI_BEGIN) ||
> +         vaddr >= FIXMAP_ADDR(FIXMAP_ACPI_END) )
> +        return false;
> +
> +    /*
> +     * __acpi_map_table() will always return a pointer in the first page
> +     * for the ACPI fixmap region. The caller is expected to free with
> +     * the same address.
> +     */
> +    ASSERT((vaddr & PAGE_MASK) == FIXMAP_ADDR(FIXMAP_ACPI_BEGIN));
> +
> +    /* The region allocated fit in the ACPI fixmap region. */
> +    ASSERT(size < (FIXMAP_ADDR(FIXMAP_ACPI_END) + PAGE_SIZE - vaddr));
> +    ASSERT(fixmap_inuse);
> +
> +    fixmap_inuse = false;
> +
> +    size += FIXMAP_ADDR(FIXMAP_ACPI_BEGIN) - vaddr;
> +    idx = FIXMAP_ACPI_BEGIN;
> +
> +    do
> +    {
> +        clear_fixmap(idx);
> +        size -= min(size, (unsigned long)PAGE_SIZE);
> +        idx++;
> +    } while ( size > 0 );
> +
> +    return true;
> }
> 
> /* True to indicate PSCI 0.2+ is implemented */
> -- 
> 2.17.1
> 
> 

Regards,
Rahul




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.