Patch for Oracle bugs 7916406/7663716: JVM process hang after a #GPF.
Affects all 32-bit EL4 PV guests with more than one vcpu.

There are two ways to get to the saved value for a CPU's GDT. One is through
cpu_gdt_table[cpu#], the other is through cpu_gdt_descr[cpu#].  The factors
that determine the contents of the two tables are:

   1. if you are the boot CPU (CPU0)
   2. if you are a PV xen guest
   3. if you are non-virtualized (HVM guest or running on a non-virtualized
      system).

For a boot CPU, or for any non-virtualized guest/system CPU,
cpu_gdt_descr[CPU#] points to cpu_gdt_table[CPU#] so it is OK to use either
data structure.

A PV guest's non-boot CPU's cpu_gdt_descr[CPU#] will point to a separately
allocated page which is set up correctly. Its cpu_gdt_table[CPU#] is not set
up so the entries are NULL.

These two factors lead to a bug in an MP 32-bit PV guest's general protection
fault (#GPF) handler.  A PV guest's non-boot CPU will not handle a user mode
#GPF because that code path references cpu_gdt_table[CPU#].  It will load NULLs
into the GDT and retry the faulting user instruction.  This leads to an endless
loop.

This patch changes the #GPF handler to use cpu_gdt_descr[] by way of
get_cpu_gdt_table() instead of cpu_gdt_table[].

--- linux-2.6.9/arch/i386/kernel/traps-xen.c.orig	2009-02-12 16:27:17.000000000 -0800
+++ linux-2.6.9/arch/i386/kernel/traps-xen.c	2009-02-12 16:26:01.000000000 -0800
@@ -622,7 +622,7 @@
 		set_user_cs(&current->mm->context.user_cs, limit);
 
 		desc1 = &current->mm->context.user_cs;
-		desc2 = cpu_gdt_table[cpu] + GDT_ENTRY_DEFAULT_USER_CS;
+		desc2 = &get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS];
 
 		/*
 		 * The CS was not in sync - reload it and retry the
