1 This patch must be applied to Pintos before Checkbochs may be usefully
2 applied to it. To apply it, `cd' to pintos/src and type
3 patch -p2 < misc/checkbochs.patch
5 Written by Sorav Bansal <sbansal@stanford.edu>.
6 Modified by Ben Pfaff <blp@cs.stanford.edu>.
8 diff -X ignore -urpN pintos.orig/src/lib/debug.h pintos.eraser/src/lib/debug.h
9 --- pintos.orig/src/lib/debug.h 2005-06-18 20:20:49.000000000 -0700
10 +++ pintos.eraser/src/lib/debug.h 2005-06-29 22:38:01.000000000 -0700
17 /* GCC lets us add "attributes" to functions, function
18 parameters, etc. to indicate their properties.
19 See the GCC manual for details. */
20 @@ -27,10 +29,13 @@ void debug_backtrace (void);
24 -#define ASSERT(CONDITION) \
25 - if (CONDITION) { } else { \
26 - PANIC ("assertion `%s' failed.", #CONDITION); \
28 +#define ASSERT(CONDITION) \
30 + eraser_ignore_on (); \
32 + PANIC ("assertion `%s' failed.", #CONDITION); \
33 + eraser_ignore_off (); \
35 #define NOT_REACHED() PANIC ("executed an unreachable statement");
37 #define ASSERT(CONDITION) ((void) 0)
38 diff -X ignore -urpN pintos.orig/src/lib/eraser.h pintos.eraser/src/lib/eraser.h
39 --- pintos.orig/src/lib/eraser.h 1969-12-31 16:00:00.000000000 -0800
40 +++ pintos.eraser/src/lib/eraser.h 2005-07-02 16:12:28.000000000 -0700
42 +#ifndef __LIB_ERASER_H
43 +#define __LIB_ERASER_H
45 +/* New instruction to indicate the lock at ECX is locked. */
46 +#define ERASER_LOCK ".byte 0x0f, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00;"
48 +/* New instruction to indicate the lock at ECX is unlocked. */
49 +#define ERASER_UNLOCK ".byte 0x0f, 0x04, 0x18, 0x00, 0x00, 0x00, 0x00;"
51 +/* New instruction for various Eraser purposes.
52 + EAX indicates an operation subcode.
53 + ECX, EDX may be used for arguments. */
54 +#define ERASER_OPS ".byte 0x0f, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00;"
56 +/* Operation subcodes for ERASER_OPS. */
57 +#define ERASER_OP_IGNORE 0 /* Suppress warnings for ECX bytes at EDX. */
58 +#define ERASER_OP_INIT_LOCK 1 /* New lock at ECX. */
59 +#define ERASER_OP_IGNORE_ON 2 /* Suppress all warnings. */
60 +#define ERASER_OP_IGNORE_OFF 3 /* Re-enable warnings. */
61 +#define ERASER_OP_REUSE 4 /* ECX bytes at EDX are (re)allocated. */
62 +#define ERASER_OP_DBG_MARK 5 /* Debug message for file EDX, line ECX. */
63 +#define ERASER_OP_STARTUP 6 /* Start tracking locks. */
65 +/* Returns true if running under Checkbochs, false otherwise. */
67 +running_on_checkbochs (void)
69 + unsigned dummy, cpuid;
71 + : "=a" (dummy), "=b" (cpuid)
74 + return cpuid == 0x6e696154;
77 +/* Registers LOCK as a lock. */
79 +eraser_init (unsigned lock)
81 + if (running_on_checkbochs ())
82 + asm volatile (ERASER_OPS :: "a" (ERASER_OP_INIT_LOCK), "c" (lock));
85 +/* Indicates that LOCK is locked. */
87 +eraser_lock (unsigned lock)
89 + if (running_on_checkbochs ())
91 + asm volatile (ERASER_LOCK :: "c" (lock));
92 + eraser_ignore ((void *) lock, 4);
96 +/* Indicates that LOCK is unlocked. */
98 +eraser_unlock (unsigned lock)
100 + if (running_on_checkbochs ())
101 + asm volatile (ERASER_UNLOCK :: "c" (lock));
104 +/* Suppresses warnings for LENGTH bytes starting at START. */
106 +eraser_ignore (void *start, size_t length)
108 + if (running_on_checkbochs ())
109 + asm volatile (ERASER_OPS
110 + :: "a" (ERASER_OP_IGNORE), "d" (start), "c" (length));
113 +/* Suppresses all warnings. */
115 +eraser_ignore_on (void)
117 + if (running_on_checkbochs ())
118 + asm volatile (ERASER_OPS :: "a" (ERASER_OP_IGNORE_ON));
121 +/* Re-enables warnings. */
123 +eraser_ignore_off (void)
125 + if (running_on_checkbochs ())
126 + asm volatile (ERASER_OPS :: "a" (ERASER_OP_IGNORE_OFF));
129 +/* Indicates that LENGTH bytes starting at START have been
132 +eraser_reuse (void *start, size_t length)
134 + if (running_on_checkbochs ())
135 + asm volatile (ERASER_OPS
136 + :: "a" (ERASER_OP_REUSE), "d" (start), "c" (length));
139 +/* Emits a debug message for the source file and line number of
141 +#define eraser_debug_mark() do { \
142 + if (running_on_checkbochs ()) \
143 + asm volatile (ERASER_OPS \
144 + :: "a" (ERASER_OP_DBG_MARK), \
145 + "d" (__FILE__), "c" (__LINE__)); \
148 +/* Starts up the lock checking algorithm. */
150 +eraser_startup (void)
152 + if (running_on_checkbochs ())
153 + asm volatile (ERASER_OPS :: "a" (ERASER_OP_STARTUP));
156 +#endif /* lib/eraser.h */
157 diff -X ignore -urpN pintos.orig/src/threads/init.c pintos.eraser/src/threads/init.c
158 --- pintos.orig/src/threads/init.c 2005-06-18 20:21:19.000000000 -0700
159 +++ pintos.eraser/src/threads/init.c 2005-07-02 16:13:32.000000000 -0700
160 @@ -132,6 +132,8 @@ main (void)
163 printf ("Boot complete.\n");
167 /* Run actions specified on kernel command line. */
169 diff -X ignore -urpN pintos.orig/src/threads/interrupt.c pintos.eraser/src/threads/interrupt.c
170 --- pintos.orig/src/threads/interrupt.c 2005-06-18 20:21:19.000000000 -0700
171 +++ pintos.eraser/src/threads/interrupt.c 2005-06-29 22:38:37.000000000 -0700
172 @@ -135,6 +135,8 @@ intr_init (void)
173 intr_names[17] = "#AC Alignment Check Exception";
174 intr_names[18] = "#MC Machine-Check Exception";
175 intr_names[19] = "#XF SIMD Floating-Point Exception";
177 + eraser_ignore (&in_external_intr, 4);
180 /* Registers interrupt VEC_NO to invoke HANDLER with descriptor
181 diff -X ignore -urpN pintos.orig/src/threads/malloc.c pintos.eraser/src/threads/malloc.c
182 --- pintos.orig/src/threads/malloc.c 2005-06-18 20:21:19.000000000 -0700
183 +++ pintos.eraser/src/threads/malloc.c 2005-07-02 16:17:07.000000000 -0700
184 @@ -150,6 +150,7 @@ malloc (size_t size)
185 a = block_to_arena (b);
187 lock_release (&d->lock);
188 + eraser_reuse (b, size);
192 @@ -171,6 +172,7 @@ calloc (size_t a, size_t b)
196 + eraser_reuse (p, size);
200 @@ -228,6 +230,7 @@ free (void *p)
202 /* It's a normal block. We handle it here. */
204 + eraser_reuse (b, d->block_size);
206 /* Clear the block to help detect use-after-free bugs. */
207 memset (b, 0xcc, d->block_size);
208 diff -X ignore -urpN pintos.orig/src/threads/palloc.c pintos.eraser/src/threads/palloc.c
209 --- pintos.orig/src/threads/palloc.c 2005-06-18 20:21:19.000000000 -0700
210 +++ pintos.eraser/src/threads/palloc.c 2005-07-02 16:16:18.000000000 -0700
211 @@ -104,6 +104,7 @@ palloc_get_multiple (enum palloc_flags f
212 PANIC ("palloc_get: out of pages");
215 + eraser_reuse (pages, PGSIZE * page_cnt);
219 @@ -139,6 +140,7 @@ palloc_free_multiple (void *pages, size_
221 page_idx = pg_no (pages) - pg_no (pool->base);
223 + eraser_reuse (pages, PGSIZE * page_cnt);
225 memset (pages, 0xcc, PGSIZE * page_cnt);
227 diff -X ignore -urpN pintos.orig/src/threads/synch.c pintos.eraser/src/threads/synch.c
228 --- pintos.orig/src/threads/synch.c 2005-06-18 20:21:19.000000000 -0700
229 +++ pintos.eraser/src/threads/synch.c 2005-06-29 22:48:42.000000000 -0700
230 @@ -179,6 +179,7 @@ lock_init (struct lock *lock)
233 sema_init (&lock->semaphore, 1);
234 + eraser_init (lock);
237 /* Acquires LOCK, sleeping until it becomes available if
238 @@ -200,6 +201,7 @@ lock_acquire (struct lock *lock)
240 old_level = intr_disable ();
241 sema_down (&lock->semaphore);
242 + eraser_lock (lock);
243 lock->holder = thread_current ();
244 intr_set_level (old_level);
246 @@ -245,6 +247,7 @@ lock_release (struct lock *lock)
248 sema_up (&lock->semaphore);
249 intr_set_level (old_level);
250 + eraser_unlock (lock);
253 /* Returns true if the current thread holds LOCK, false
254 @@ -253,9 +256,15 @@ lock_release (struct lock *lock)
256 lock_held_by_current_thread (const struct lock *lock)
260 ASSERT (lock != NULL);
262 - return lock->holder == thread_current ();
263 + eraser_ignore_on ();
264 + ret = lock->holder == thread_current ();
265 + eraser_ignore_off ();
270 /* One semaphore in a list. */
271 diff -X ignore -urpN pintos.orig/src/threads/thread.c pintos.eraser/src/threads/thread.c
272 --- pintos.orig/src/threads/thread.c 2005-06-18 20:21:20.000000000 -0700
273 +++ pintos.eraser/src/threads/thread.c 2005-07-02 16:16:03.000000000 -0700
274 @@ -85,6 +85,7 @@ thread_init (void)
275 init_thread (initial_thread, "main", PRI_DEFAULT);
276 initial_thread->status = THREAD_RUNNING;
277 initial_thread->tid = allocate_tid ();
278 + eraser_ignore (&initial_thread->status, 4);
281 /* Starts preemptive thread scheduling by enabling interrupts.
282 @@ -157,6 +158,9 @@ thread_create (const char *name, int pri
286 + eraser_ignore (&t->status, 4);
287 + eraser_ignore_on ();
289 /* Initialize thread. */
290 init_thread (t, name, priority);
291 tid = t->tid = allocate_tid ();
292 @@ -175,6 +179,8 @@ thread_create (const char *name, int pri
293 sf = alloc_frame (t, sizeof *sf);
294 sf->eip = switch_entry;
296 + eraser_ignore_off ();
298 /* Add to run queue. */
301 @@ -361,6 +367,7 @@ kernel_thread (thread_func *function, vo
303 ASSERT (function != NULL);
305 + eraser_lock (thread_current ()->tid);
306 intr_enable (); /* The scheduler runs with interrupts off. */
307 function (aux); /* Execute the thread function. */
308 thread_exit (); /* If function() returns, kill the thread. */
309 @@ -396,12 +403,16 @@ init_thread (struct thread *t, const cha
310 ASSERT (PRI_MIN <= priority && priority <= PRI_MAX);
311 ASSERT (name != NULL);
313 + eraser_ignore_on ();
315 memset (t, 0, sizeof *t);
316 t->status = THREAD_BLOCKED;
317 strlcpy (t->name, name, sizeof t->name);
318 t->stack = (uint8_t *) t + PGSIZE;
319 t->priority = priority;
320 t->magic = THREAD_MAGIC;
322 + eraser_ignore_off ();
325 /* Allocates a SIZE-byte frame at the top of thread T's stack and
326 @@ -471,7 +482,7 @@ schedule_tail (struct thread *prev)
327 if (prev != NULL && prev->status == THREAD_DYING)
329 ASSERT (prev != cur);
330 - if (prev != initial_thread)
331 + if (prev != initial_thread)
332 palloc_free_page (prev);
335 diff -X ignore -urpN pintos.orig/src/userprog/tss.c pintos.eraser/src/userprog/tss.c
336 --- pintos.orig/src/userprog/tss.c 2004-09-22 17:58:29.000000000 -0700
337 +++ pintos.eraser/src/userprog/tss.c 2005-06-29 22:41:09.000000000 -0700
338 @@ -84,6 +84,8 @@ tss_init (void)
339 tss->esp0 = ptov(0x20000);
340 tss->ss0 = SEL_KDSEG;
341 tss->bitmap = 0xdfff;
343 + eraser_ignore (tss, sizeof *tss);
346 /* Returns the kernel TSS. */