x85: mptable: Move the mptable to the end of base RAM

Recent Linux kernel's fail to start if the mptable is at the start of
RAM (address 0x00). Avoid putting the mptable there so that crosvm can
boot 4.14+ kernels. The kernel scans the last kilobyte of RAM after the
first, move the mptable there.

Change-Id: Ia00f49e7a4cbd0fb3719c21b757e8fdca65584e8
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/780045
diff --git a/x86_64/src/mptable.rs b/x86_64/src/mptable.rs
index e5ab03e..b74992c 100644
--- a/x86_64/src/mptable.rs
+++ b/x86_64/src/mptable.rs
@@ -57,6 +57,7 @@
 const CPU_STEPPING: u32 = 0x600;
 const CPU_FEATURE_APIC: u32 = 0x200;
 const CPU_FEATURE_FPU: u32 = 0x001;
+const MPTABLE_START: usize = 0x400 * 639; // Last 1k of Linux's 640k base RAM.
 
 fn compute_checksum<T: Copy>(v: &T) -> u8 {
     // Safe because we are only reading the bytes within the size of the `T` reference `v`.
@@ -85,7 +86,7 @@
 pub fn setup_mptable(mem: &GuestMemory, num_cpus: u8) -> Result<()> {
 
     // Used to keep track of the next base pointer into the MP table.
-    let mut base_mp = GuestAddress(0x0);
+    let mut base_mp = GuestAddress(MPTABLE_START);
 
     let mp_size = compute_mp_size(num_cpus);
 
@@ -267,7 +268,8 @@
     #[test]
     fn bounds_check() {
         let num_cpus = 4;
-        let mem = GuestMemory::new(&[(GuestAddress(0), compute_mp_size(num_cpus))]).unwrap();
+        let mem = GuestMemory::new(&[(GuestAddress(MPTABLE_START),
+                                      compute_mp_size(num_cpus))]).unwrap();
 
         setup_mptable(&mem, num_cpus).unwrap();
     }
@@ -275,7 +277,8 @@
     #[test]
     fn bounds_check_fails() {
         let num_cpus = 4;
-        let mem = GuestMemory::new(&[(GuestAddress(0), compute_mp_size(num_cpus) - 1)]).unwrap();
+        let mem = GuestMemory::new(&[(GuestAddress(MPTABLE_START),
+                                      compute_mp_size(num_cpus) - 1)]).unwrap();
 
         assert!(setup_mptable(&mem, num_cpus).is_err());
     }
@@ -283,11 +286,12 @@
     #[test]
     fn mpf_intel_checksum() {
         let num_cpus = 1;
-        let mem = GuestMemory::new(&[(GuestAddress(0), compute_mp_size(num_cpus))]).unwrap();
+        let mem = GuestMemory::new(&[(GuestAddress(MPTABLE_START),
+                                      compute_mp_size(num_cpus))]).unwrap();
 
         setup_mptable(&mem, num_cpus).unwrap();
 
-        let mpf_intel = mem.read_obj_from_addr(GuestAddress(0)).unwrap();
+        let mpf_intel = mem.read_obj_from_addr(GuestAddress(MPTABLE_START)).unwrap();
 
         assert_eq!(mpf_intel_compute_checksum(&mpf_intel), mpf_intel.checksum);
     }
@@ -295,11 +299,12 @@
     #[test]
     fn mpc_table_checksum() {
         let num_cpus = 4;
-        let mem = GuestMemory::new(&[(GuestAddress(0), compute_mp_size(num_cpus))]).unwrap();
+        let mem = GuestMemory::new(&[(GuestAddress(MPTABLE_START),
+                                      compute_mp_size(num_cpus))]).unwrap();
 
         setup_mptable(&mem, num_cpus).unwrap();
 
-        let mpf_intel: mpf_intel = mem.read_obj_from_addr(GuestAddress(0)).unwrap();
+        let mpf_intel: mpf_intel = mem.read_obj_from_addr(GuestAddress(MPTABLE_START)).unwrap();
         let mpc_offset = GuestAddress(mpf_intel.physptr as usize);
         let mpc_table: mpc_table = mem.read_obj_from_addr(mpc_offset).unwrap();
 
@@ -325,12 +330,13 @@
     #[test]
     fn cpu_entry_count() {
         const MAX_CPUS: u8 = 0xff;
-        let mem = GuestMemory::new(&[(GuestAddress(0), compute_mp_size(MAX_CPUS))]).unwrap();
+        let mem = GuestMemory::new(&[(GuestAddress(MPTABLE_START),
+                                      compute_mp_size(MAX_CPUS))]).unwrap();
 
         for i in 0..MAX_CPUS {
             setup_mptable(&mem, i).unwrap();
 
-            let mpf_intel: mpf_intel = mem.read_obj_from_addr(GuestAddress(0)).unwrap();
+            let mpf_intel: mpf_intel = mem.read_obj_from_addr(GuestAddress(MPTABLE_START)).unwrap();
             let mpc_offset = GuestAddress(mpf_intel.physptr as usize);
             let mpc_table: mpc_table = mem.read_obj_from_addr(mpc_offset).unwrap();
             let mpc_end = mpc_offset