x86/xen: Remove use of VLAs
authorLaura Abbott <labbott@redhat.com>
Wed, 18 Apr 2018 17:08:32 +0000 (10:08 -0700)
committerBoris Ostrovsky <boris.ostrovsky@oracle.com>
Thu, 19 Apr 2018 20:35:51 +0000 (16:35 -0400)
There's an ongoing effort to remove VLAs[1] from the kernel to eventually
turn on -Wvla. It turns out, the few VLAs in use in Xen produce only a
single entry array that is always bounded by GDT_SIZE. Clean up the code to
get rid of the VLA and the loop.

[1] https://lkml.org/lkml/2018/3/7/621

Signed-off-by: Laura Abbott <labbott@redhat.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
[boris: Use BUG_ON(size>PAGE_SIZE) instead of GDT_SIZE]
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
arch/x86/xen/enlighten_pv.c

index c36d23aa6c3502a004d1357027dca057fca7e3a6..357969a3697cc7af6e08c12144ec06f43a8841ad 100644 (file)
@@ -421,45 +421,33 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
 {
        unsigned long va = dtr->address;
        unsigned int size = dtr->size + 1;
-       unsigned pages = DIV_ROUND_UP(size, PAGE_SIZE);
-       unsigned long frames[pages];
-       int f;
-
-       /*
-        * A GDT can be up to 64k in size, which corresponds to 8192
-        * 8-byte entries, or 16 4k pages..
-        */
+       unsigned long pfn, mfn;
+       int level;
+       pte_t *ptep;
+       void *virt;
 
-       BUG_ON(size > 65536);
+       /* @size should be at most GDT_SIZE which is smaller than PAGE_SIZE. */
+       BUG_ON(size > PAGE_SIZE);
        BUG_ON(va & ~PAGE_MASK);
 
-       for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
-               int level;
-               pte_t *ptep;
-               unsigned long pfn, mfn;
-               void *virt;
-
-               /*
-                * The GDT is per-cpu and is in the percpu data area.
-                * That can be virtually mapped, so we need to do a
-                * page-walk to get the underlying MFN for the
-                * hypercall.  The page can also be in the kernel's
-                * linear range, so we need to RO that mapping too.
-                */
-               ptep = lookup_address(va, &level);
-               BUG_ON(ptep == NULL);
-
-               pfn = pte_pfn(*ptep);
-               mfn = pfn_to_mfn(pfn);
-               virt = __va(PFN_PHYS(pfn));
+       /*
+        * The GDT is per-cpu and is in the percpu data area.
+        * That can be virtually mapped, so we need to do a
+        * page-walk to get the underlying MFN for the
+        * hypercall.  The page can also be in the kernel's
+        * linear range, so we need to RO that mapping too.
+        */
+       ptep = lookup_address(va, &level);
+       BUG_ON(ptep == NULL);
 
-               frames[f] = mfn;
+       pfn = pte_pfn(*ptep);
+       mfn = pfn_to_mfn(pfn);
+       virt = __va(PFN_PHYS(pfn));
 
-               make_lowmem_page_readonly((void *)va);
-               make_lowmem_page_readonly(virt);
-       }
+       make_lowmem_page_readonly((void *)va);
+       make_lowmem_page_readonly(virt);
 
-       if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct)))
+       if (HYPERVISOR_set_gdt(&mfn, size / sizeof(struct desc_struct)))
                BUG();
 }
 
@@ -470,34 +458,22 @@ static void __init xen_load_gdt_boot(const struct desc_ptr *dtr)
 {
        unsigned long va = dtr->address;
        unsigned int size = dtr->size + 1;
-       unsigned pages = DIV_ROUND_UP(size, PAGE_SIZE);
-       unsigned long frames[pages];
-       int f;
-
-       /*
-        * A GDT can be up to 64k in size, which corresponds to 8192
-        * 8-byte entries, or 16 4k pages..
-        */
+       unsigned long pfn, mfn;
+       pte_t pte;
 
-       BUG_ON(size > 65536);
+       /* @size should be at most GDT_SIZE which is smaller than PAGE_SIZE. */
+       BUG_ON(size > PAGE_SIZE);
        BUG_ON(va & ~PAGE_MASK);
 
-       for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
-               pte_t pte;
-               unsigned long pfn, mfn;
+       pfn = virt_to_pfn(va);
+       mfn = pfn_to_mfn(pfn);
 
-               pfn = virt_to_pfn(va);
-               mfn = pfn_to_mfn(pfn);
+       pte = pfn_pte(pfn, PAGE_KERNEL_RO);
 
-               pte = pfn_pte(pfn, PAGE_KERNEL_RO);
-
-               if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0))
-                       BUG();
-
-               frames[f] = mfn;
-       }
+       if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0))
+               BUG();
 
-       if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct)))
+       if (HYPERVISOR_set_gdt(&mfn, size / sizeof(struct desc_struct)))
                BUG();
 }