static int __init smp_scan_config(unsigned long base, unsigned long length,
                                  unsigned reserve)
 {
-       unsigned long *bp = phys_to_virt(base);
+       extern void __bad_mpf_size(void);
+       unsigned int *bp = phys_to_virt(base);
        struct intel_mp_floating *mpf;
 
-       printk(KERN_INFO "Scan SMP from %p for %ld bytes.\n", bp, length);
+       Dprintk("Scan SMP from %p for %ld bytes.\n", bp, length);
        if (sizeof(*mpf) != 16)
-               printk("Error: MPF size\n");
+               __bad_mpf_size();
 
        while (length > 0) {
                mpf = (struct intel_mp_floating *)bp;
                     || (mpf->mpf_specification == 4))) {
 
                        smp_found_config = 1;
+                       mpf_found = mpf;
+#ifdef CONFIG_X86_32
                        printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
                               mpf, virt_to_phys(mpf));
                        reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE,
                                                BOOTMEM_DEFAULT);
                        }
 
-                       mpf_found = mpf;
-                       return 1;
+#else
+                       if (!reserve)
+                               return 1;
+
+                       reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE);
+                       if (mpf->mpf_physptr)
+                               reserve_bootmem_generic(mpf->mpf_physptr,
+                                                       PAGE_SIZE);
+#endif
+               return 1;
                }
                bp += 4;
                length -= 16;
 
 
                        smp_found_config = 1;
                        mpf_found = mpf;
+#ifdef CONFIG_X86_32
+                       printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
+                              mpf, virt_to_phys(mpf));
+                       reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE,
+                                       BOOTMEM_DEFAULT);
+                       if (mpf->mpf_physptr) {
+                               /*
+                                * We cannot access to MPC table to compute
+                                * table size yet, as only few megabytes from
+                                * the bottom is mapped now.
+                                * PC-9800's MPC table places on the very last
+                                * of physical memory; so that simply reserving
+                                * PAGE_SIZE from mpg->mpf_physptr yields BUG()
+                                * in reserve_bootmem.
+                                */
+                               unsigned long size = PAGE_SIZE;
+                               unsigned long end = max_low_pfn * PAGE_SIZE;
+                               if (mpf->mpf_physptr + size > end)
+                                       size = end - mpf->mpf_physptr;
+                               reserve_bootmem(mpf->mpf_physptr, size,
+                                               BOOTMEM_DEFAULT);
+                       }
 
+#else
                        if (!reserve)
                                return 1;
 
                        if (mpf->mpf_physptr)
                                reserve_bootmem_generic(mpf->mpf_physptr,
                                                        PAGE_SIZE);
-                       return 1;
+#endif
+               return 1;
                }
                bp += 4;
                length -= 16;