linux/drivers/lguest/hypercalls.c
<<
>>
Prefs
   1/*P:500 Just as userspace programs request kernel operations through a system
   2 * call, the Guest requests Host operations through a "hypercall".  You might
   3 * notice this nomenclature doesn't really follow any logic, but the name has
   4 * been around for long enough that we're stuck with it.  As you'd expect, this
   5 * code is basically a one big switch statement. :*/
   6
   7/*  Copyright (C) 2006 Rusty Russell IBM Corporation
   8
   9    This program is free software; you can redistribute it and/or modify
  10    it under the terms of the GNU General Public License as published by
  11    the Free Software Foundation; either version 2 of the License, or
  12    (at your option) any later version.
  13
  14    This program is distributed in the hope that it will be useful,
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17    GNU General Public License for more details.
  18
  19    You should have received a copy of the GNU General Public License
  20    along with this program; if not, write to the Free Software
  21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  22*/
  23#include <linux/uaccess.h>
  24#include <linux/syscalls.h>
  25#include <linux/mm.h>
  26#include <linux/ktime.h>
  27#include <asm/page.h>
  28#include <asm/pgtable.h>
  29#include "lg.h"
  30
  31/*H:120 This is the core hypercall routine: where the Guest gets what it wants.
  32 * Or gets killed.  Or, in the case of LHCALL_SHUTDOWN, both. */
  33static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
  34{
  35        switch (args->arg0) {
  36        case LHCALL_FLUSH_ASYNC:
  37                /* This call does nothing, except by breaking out of the Guest
  38                 * it makes us process all the asynchronous hypercalls. */
  39                break;
  40        case LHCALL_LGUEST_INIT:
  41                /* You can't get here unless you're already initialized.  Don't
  42                 * do that. */
  43                kill_guest(cpu, "already have lguest_data");
  44                break;
  45        case LHCALL_SHUTDOWN: {
  46                /* Shutdown is such a trivial hypercall that we do it in four
  47                 * lines right here. */
  48                char msg[128];
  49                /* If the lgread fails, it will call kill_guest() itself; the
  50                 * kill_guest() with the message will be ignored. */
  51                __lgread(cpu, msg, args->arg1, sizeof(msg));
  52                msg[sizeof(msg)-1] = '\0';
  53                kill_guest(cpu, "CRASH: %s", msg);
  54                if (args->arg2 == LGUEST_SHUTDOWN_RESTART)
  55                        cpu->lg->dead = ERR_PTR(-ERESTART);
  56                break;
  57        }
  58        case LHCALL_FLUSH_TLB:
  59                /* FLUSH_TLB comes in two flavors, depending on the
  60                 * argument: */
  61                if (args->arg1)
  62                        guest_pagetable_clear_all(cpu);
  63                else
  64                        guest_pagetable_flush_user(cpu);
  65                break;
  66
  67        /* All these calls simply pass the arguments through to the right
  68         * routines. */
  69        case LHCALL_NEW_PGTABLE:
  70                guest_new_pagetable(cpu, args->arg1);
  71                break;
  72        case LHCALL_SET_STACK:
  73                guest_set_stack(cpu, args->arg1, args->arg2, args->arg3);
  74                break;
  75        case LHCALL_SET_PTE:
  76                guest_set_pte(cpu, args->arg1, args->arg2, __pte(args->arg3));
  77                break;
  78        case LHCALL_SET_PMD:
  79                guest_set_pmd(cpu->lg, args->arg1, args->arg2);
  80                break;
  81        case LHCALL_SET_CLOCKEVENT:
  82                guest_set_clockevent(cpu, args->arg1);
  83                break;
  84        case LHCALL_TS:
  85                /* This sets the TS flag, as we saw used in run_guest(). */
  86                cpu->ts = args->arg1;
  87                break;
  88        case LHCALL_HALT:
  89                /* Similarly, this sets the halted flag for run_guest(). */
  90                cpu->halted = 1;
  91                break;
  92        case LHCALL_NOTIFY:
  93                cpu->pending_notify = args->arg1;
  94                break;
  95        default:
  96                /* It should be an architecture-specific hypercall. */
  97                if (lguest_arch_do_hcall(cpu, args))
  98                        kill_guest(cpu, "Bad hypercall %li\n", args->arg0);
  99        }
 100}
 101/*:*/
 102
 103/*H:124 Asynchronous hypercalls are easy: we just look in the array in the
 104 * Guest's "struct lguest_data" to see if any new ones are marked "ready".
 105 *
 106 * We are careful to do these in order: obviously we respect the order the
 107 * Guest put them in the ring, but we also promise the Guest that they will
 108 * happen before any normal hypercall (which is why we check this before
 109 * checking for a normal hcall). */
 110static void do_async_hcalls(struct lg_cpu *cpu)
 111{
 112        unsigned int i;
 113        u8 st[LHCALL_RING_SIZE];
 114
 115        /* For simplicity, we copy the entire call status array in at once. */
 116        if (copy_from_user(&st, &cpu->lg->lguest_data->hcall_status, sizeof(st)))
 117                return;
 118
 119        /* We process "struct lguest_data"s hcalls[] ring once. */
 120        for (i = 0; i < ARRAY_SIZE(st); i++) {
 121                struct hcall_args args;
 122                /* We remember where we were up to from last time.  This makes
 123                 * sure that the hypercalls are done in the order the Guest
 124                 * places them in the ring. */
 125                unsigned int n = cpu->next_hcall;
 126
 127                /* 0xFF means there's no call here (yet). */
 128                if (st[n] == 0xFF)
 129                        break;
 130
 131                /* OK, we have hypercall.  Increment the "next_hcall" cursor,
 132                 * and wrap back to 0 if we reach the end. */
 133                if (++cpu->next_hcall == LHCALL_RING_SIZE)
 134                        cpu->next_hcall = 0;
 135
 136                /* Copy the hypercall arguments into a local copy of
 137                 * the hcall_args struct. */
 138                if (copy_from_user(&args, &cpu->lg->lguest_data->hcalls[n],
 139                                   sizeof(struct hcall_args))) {
 140                        kill_guest(cpu, "Fetching async hypercalls");
 141                        break;
 142                }
 143
 144                /* Do the hypercall, same as a normal one. */
 145                do_hcall(cpu, &args);
 146
 147                /* Mark the hypercall done. */
 148                if (put_user(0xFF, &cpu->lg->lguest_data->hcall_status[n])) {
 149                        kill_guest(cpu, "Writing result for async hypercall");
 150                        break;
 151                }
 152
 153                /* Stop doing hypercalls if they want to notify the Launcher:
 154                 * it needs to service this first. */
 155                if (cpu->pending_notify)
 156                        break;
 157        }
 158}
 159
 160/* Last of all, we look at what happens first of all.  The very first time the
 161 * Guest makes a hypercall, we end up here to set things up: */
 162static void initialize(struct lg_cpu *cpu)
 163{
 164        /* You can't do anything until you're initialized.  The Guest knows the
 165         * rules, so we're unforgiving here. */
 166        if (cpu->hcall->arg0 != LHCALL_LGUEST_INIT) {
 167                kill_guest(cpu, "hypercall %li before INIT", cpu->hcall->arg0);
 168                return;
 169        }
 170
 171        if (lguest_arch_init_hypercalls(cpu))
 172                kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);
 173
 174        /* The Guest tells us where we're not to deliver interrupts by putting
 175         * the range of addresses into "struct lguest_data". */
 176        if (get_user(cpu->lg->noirq_start, &cpu->lg->lguest_data->noirq_start)
 177            || get_user(cpu->lg->noirq_end, &cpu->lg->lguest_data->noirq_end))
 178                kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);
 179
 180        /* We write the current time into the Guest's data page once so it can
 181         * set its clock. */
 182        write_timestamp(cpu);
 183
 184        /* page_tables.c will also do some setup. */
 185        page_table_guest_data_init(cpu);
 186
 187        /* This is the one case where the above accesses might have been the
 188         * first write to a Guest page.  This may have caused a copy-on-write
 189         * fault, but the old page might be (read-only) in the Guest
 190         * pagetable. */
 191        guest_pagetable_clear_all(cpu);
 192}
 193/*:*/
 194
 195/*M:013 If a Guest reads from a page (so creates a mapping) that it has never
 196 * written to, and then the Launcher writes to it (ie. the output of a virtual
 197 * device), the Guest will still see the old page.  In practice, this never
 198 * happens: why would the Guest read a page which it has never written to?  But
 199 * a similar scenario might one day bite us, so it's worth mentioning. :*/
 200
 201/*H:100
 202 * Hypercalls
 203 *
 204 * Remember from the Guest, hypercalls come in two flavors: normal and
 205 * asynchronous.  This file handles both of types.
 206 */
 207void do_hypercalls(struct lg_cpu *cpu)
 208{
 209        /* Not initialized yet?  This hypercall must do it. */
 210        if (unlikely(!cpu->lg->lguest_data)) {
 211                /* Set up the "struct lguest_data" */
 212                initialize(cpu);
 213                /* Hcall is done. */
 214                cpu->hcall = NULL;
 215                return;
 216        }
 217
 218        /* The Guest has initialized.
 219         *
 220         * Look in the hypercall ring for the async hypercalls: */
 221        do_async_hcalls(cpu);
 222
 223        /* If we stopped reading the hypercall ring because the Guest did a
 224         * NOTIFY to the Launcher, we want to return now.  Otherwise we do
 225         * the hypercall. */
 226        if (!cpu->pending_notify) {
 227                do_hcall(cpu, cpu->hcall);
 228                /* Tricky point: we reset the hcall pointer to mark the
 229                 * hypercall as "done".  We use the hcall pointer rather than
 230                 * the trap number to indicate a hypercall is pending.
 231                 * Normally it doesn't matter: the Guest will run again and
 232                 * update the trap number before we come back here.
 233                 *
 234                 * However, if we are signalled or the Guest sends I/O to the
 235                 * Launcher, the run_guest() loop will exit without running the
 236                 * Guest.  When it comes back it would try to re-run the
 237                 * hypercall.  Finding that bug sucked. */
 238                cpu->hcall = NULL;
 239        }
 240}
 241
 242/* This routine supplies the Guest with time: it's used for wallclock time at
 243 * initial boot and as a rough time source if the TSC isn't available. */
 244void write_timestamp(struct lg_cpu *cpu)
 245{
 246        struct timespec now;
 247        ktime_get_real_ts(&now);
 248        if (copy_to_user(&cpu->lg->lguest_data->time,
 249                         &now, sizeof(struct timespec)))
 250                kill_guest(cpu, "Writing timestamp");
 251}
 252