Magellan Linux

Contents of /trunk/kernel26-xen/patches-2.6.25-r1/1003-2.6.25-xen-execshield-fix-endless-GPF-fault-loop.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 606 - (show annotations) (download)
Thu May 22 23:13:13 2008 UTC (15 years, 11 months ago) by niro
File size: 2143 byte(s)
-ver bump to 2.6.25-magellan-r1:
- linux-2.6.25.4
- fbcondecor-0.9.4
- squashfs-3.3
- unionfs-2.3.3
- tuxonice-3.0-rc7
- linux-phc-0.3.0
- acpi-dstd-0.9a
- reiser4
- xen-3.2.0
. ipw3945-1.2.2

1 From a59694addaf0470886d211735d6df258f7273387 Mon Sep 17 00:00:00 2001
2 From: Stephen Tweedie <sct@redhat.com>
3 Date: Tue, 11 Mar 2008 18:07:31 +0000
4 Subject: [PATCH] xen execshield: fix endless GPF fault loop
5
6 Under Xen, loading the user_cs descriptor does not necessarily load
7 the descriptor with the exact same values the kernel requested: some
8 of the control bits in the descriptor may be modified by the
9 hypervisor.
10
11 With execshield, the check_lazy_exec_limit() function is needed to
12 test whether a fault has been caused by the existing user_cs
13 descriptor being too constrained: if so, it performs a lazy expansion
14 of the legal cs segment bounds. But it does so via an exact match on
15 the descriptor values against their current expected values, so if
16 Xen modifies any control bits in the descriptor, it looks as if the
17 user_cs is out-of-sync; so check_lazy_exec_limit() resets the
18 descriptor and retakes the fault unnecessarily.
19
20 This means that a GPF fault can be retried indefinitely, with the
21 kernel always seeing the wrong values in user_cs and continually
22 trying to correct them and retake the fault.
23
24 Fix it by masking off the xen-sensitive control bits when checking
25 that the segment descriptor is up-to-date, and comparing only the
26 bits which affect the segment base and limit.
27
28 Affects 32-bit only; execshield on 64-bit uses NX for this
29 functionality.
30
31 Signed-off-by: Stephen Tweedie <sct@redhat.com>
32 ---
33 arch/x86/kernel/traps_32.c | 3 ++-
34 1 files changed, 2 insertions(+), 1 deletions(-)
35
36 diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
37 index 7865615..3d36a99 100644
38 --- a/arch/x86/kernel/traps_32.c
39 +++ b/arch/x86/kernel/traps_32.c
40 @@ -629,7 +629,8 @@ check_lazy_exec_limit(int cpu, struct pt_regs *regs, long error_code)
41 desc1 = &current->mm->context.user_cs;
42 desc2 = get_cpu_gdt_table(cpu) + GDT_ENTRY_DEFAULT_USER_CS;
43
44 - if (desc1->a != desc2->a || desc1->b != desc2->b) {
45 + if ((desc1->a & 0xff0000ff) != (desc2->a & 0xff0000ff) ||
46 + desc1->b != desc2->b) {
47 /*
48 * The CS was not in sync - reload it and retry the
49 * instruction. If the instruction still faults then
50 --
51 1.5.4.1
52