aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/hypercalls.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-07-26 23:42:52 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-28 22:54:33 -0400
commit6c8dca5d53f95009d4fff00195bf38f277dc4366 (patch)
tree60cc83cf949d6e598e6dc80dc668aebd42c65540 /drivers/lguest/hypercalls.c
parenta8a11f06973fa63ad692a8f97694cb5eeb70b3f3 (diff)
Provide timespec to guests rather than jiffies clock.
A non-periodic clock_event_device and the "jiffies" clock don't mix well: tick_handle_periodic() can go into an infinite loop. Currently lguest guests use the jiffies clock when the TSC is unusable. Instead, make the Host write the current time into the lguest page on every interrupt. This doesn't cost much but is more precise and at least as accurate as the jiffies clock. It also gets rid of the GET_WALLCLOCK hypercall. Also, delay setting sched_clock until our clock is set up, otherwise the early printk timestamps can go backwards (not harmful, just ugly). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/lguest/hypercalls.c')
-rw-r--r--drivers/lguest/hypercalls.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 7a5299f9679d..db6caace3b9c 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -64,14 +64,6 @@ static void do_hcall(struct lguest *lg, struct lguest_regs *regs)
64 else 64 else
65 guest_pagetable_flush_user(lg); 65 guest_pagetable_flush_user(lg);
66 break; 66 break;
67 case LHCALL_GET_WALLCLOCK: {
68 /* The Guest wants to know the real time in seconds since 1970,
69 * in good Unix tradition. */
70 struct timespec ts;
71 ktime_get_real_ts(&ts);
72 regs->eax = ts.tv_sec;
73 break;
74 }
75 case LHCALL_BIND_DMA: 67 case LHCALL_BIND_DMA:
76 /* BIND_DMA really wants four arguments, but it's the only call 68 /* BIND_DMA really wants four arguments, but it's the only call
77 * which does. So the Guest packs the number of buffers and 69 * which does. So the Guest packs the number of buffers and
@@ -235,6 +227,9 @@ static void initialize(struct lguest *lg)
235 || put_user(lg->guestid, &lg->lguest_data->guestid)) 227 || put_user(lg->guestid, &lg->lguest_data->guestid))
236 kill_guest(lg, "bad guest page %p", lg->lguest_data); 228 kill_guest(lg, "bad guest page %p", lg->lguest_data);
237 229
230 /* We write the current time into the Guest's data page once now. */
231 write_timestamp(lg);
232
238 /* This is the one case where the above accesses might have been the 233 /* This is the one case where the above accesses might have been the
239 * first write to a Guest page. This may have caused a copy-on-write 234 * first write to a Guest page. This may have caused a copy-on-write
240 * fault, but the Guest might be referring to the old (read-only) 235 * fault, but the Guest might be referring to the old (read-only)
@@ -293,3 +288,13 @@ void do_hypercalls(struct lguest *lg)
293 clear_hcall(lg); 288 clear_hcall(lg);
294 } 289 }
295} 290}
291
292/* This routine supplies the Guest with time: it's used for wallclock time at
293 * initial boot and as a rough time source if the TSC isn't available. */
294void write_timestamp(struct lguest *lg)
295{
296 struct timespec now;
297 ktime_get_real_ts(&now);
298 if (put_user(now, &lg->lguest_data->time))
299 kill_guest(lg, "Writing timestamp");
300}