On Tue, 21 Aug 2018, Bin Yang wrote:
>  
> +static inline bool
> +overlap(unsigned long start1, unsigned long end1,
> +             unsigned long start2, unsigned long end2)
> +{
> +     /* Is 'start2' within area 1? */
> +     if (start1 <= start2 && end1 > start2)
> +             return true;
> +
> +     /* Is 'start1' within area 2? */
> +     if (start2 <= start1 && end2 > start1)
> +             return true;
> +
> +     return false;

>  static inline unsigned long highmap_start_pfn(void)
> @@ -293,7 +308,7 @@ static void cpa_flush_array(unsigned long *start, int 
> numpages, int cache,
>   * checks and fixes these known static required protection bits.
>   */
>  static inline pgprot_t static_protections(pgprot_t prot, unsigned long 
> address,
> -                                unsigned long pfn)
> +                                unsigned long len, unsigned long pfn)
>  {
>       pgprot_t forbidden = __pgprot(0);
>  
> @@ -302,7 +317,9 @@ static inline pgprot_t static_protections(pgprot_t prot, 
> unsigned long address,
>        * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support.
>        */
>  #ifdef CONFIG_PCI_BIOS
> -     if (pcibios_enabled && within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END 
> >> PAGE_SHIFT))
> +     if (pcibios_enabled &&
> +         overlap(pfn, pfn + PFN_DOWN(len),
> +                 PFN_DOWN(BIOS_BEGIN), PFN_DOWN(BIOS_END)))

This is completely unreadable and aside of that it is wrong. You cannot do
an overlap check with the following constraints:

           range1_end = range1_start + size;
           range2_end = range2_start + size;

See the definition of BIOS_END. It's 0x100000, i.e. 1MB, so the following
overlap check will give you the false result:

        overlap(256, 258, 0x000a0000 >> 12, 0x0010000 >> 12)

because

        0x0010000 >> 12 = 256

ergo will overlap return true. All of your overlap checks are broken.

Oh well.

Thanks,

        tglx


Reply via email to