12e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell/*P:500 22e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Just as userspace programs request kernel operations through a system 3f938d2c892db0d80d144253d4a7b7083efdbedebRusty Russell * call, the Guest requests Host operations through a "hypercall". You might 4f938d2c892db0d80d144253d4a7b7083efdbedebRusty Russell * notice this nomenclature doesn't really follow any logic, but the name has 5f938d2c892db0d80d144253d4a7b7083efdbedebRusty Russell * been around for long enough that we're stuck with it. As you'd expect, this 62e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * code is basically a one big switch statement. 72e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell:*/ 8f938d2c892db0d80d144253d4a7b7083efdbedebRusty Russell 9f938d2c892db0d80d144253d4a7b7083efdbedebRusty Russell/* Copyright (C) 2006 Rusty Russell IBM Corporation 10d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 11d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell This program is free software; you can redistribute it and/or modify 12d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell it under the terms of the GNU General Public License as published by 13d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell the Free Software Foundation; either version 2 of the License, or 14d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell (at your option) any later version. 15d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 16d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell This program is distributed in the hope that it will be useful, 17d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell but WITHOUT ANY WARRANTY; without even the implied warranty of 18d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell GNU General Public License for more details. 20d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 21d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell You should have received a copy of the GNU General Public License 22d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell along with this program; if not, write to the Free Software 23d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell*/ 25d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include <linux/uaccess.h> 26d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include <linux/syscalls.h> 27d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include <linux/mm.h> 28ca94f2bdd1be626361fcfbd474d6b8823ed39f74Glauber de Oliveira Costa#include <linux/ktime.h> 29d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include <asm/page.h> 30d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include <asm/pgtable.h> 31d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell#include "lg.h" 32d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 332e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell/*H:120 342e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * This is the core hypercall routine: where the Guest gets what it wants. 352e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Or gets killed. Or, in the case of LHCALL_SHUTDOWN, both. 362e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 3773044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costastatic void do_hcall(struct lg_cpu *cpu, struct hcall_args *args) 38d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 39b410e7b1499c49513cab18275db8a8ab549d9e09Jes Sorensen switch (args->arg0) { 40d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_FLUSH_ASYNC: 412e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 422e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * This call does nothing, except by breaking out of the Guest 432e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * it makes us process all the asynchronous hypercalls. 442e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 45d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 46a32a8813d0173163ba44d8f9556e0d89fdc4fb46Rusty Russell case LHCALL_SEND_INTERRUPTS: 472e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 482e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * This call does nothing too, but by breaking out of the Guest 492e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * it makes us process any pending interrupts. 502e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 51a32a8813d0173163ba44d8f9556e0d89fdc4fb46Rusty Russell break; 52d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_LGUEST_INIT: 532e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 542e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * You can't get here unless you're already initialized. Don't 552e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * do that. 562e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 57382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "already have lguest_data"); 58d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 59ec04b13f67be3c90b38c625f4b8bdfea54c1ff60Balaji Rao case LHCALL_SHUTDOWN: { 60d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell char msg[128]; 612e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 62a91d74a3c4de8115295ee87350c13a329164aaafRusty Russell * Shutdown is such a trivial hypercall that we do it in five 632e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * lines right here. 642e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * 652e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * If the lgread fails, it will call kill_guest() itself; the 662e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * kill_guest() with the message will be ignored. 672e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 68382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa __lgread(cpu, msg, args->arg1, sizeof(msg)); 69d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell msg[sizeof(msg)-1] = '\0'; 70382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "CRASH: %s", msg); 71ec04b13f67be3c90b38c625f4b8bdfea54c1ff60Balaji Rao if (args->arg2 == LGUEST_SHUTDOWN_RESTART) 72382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa cpu->lg->dead = ERR_PTR(-ERESTART); 73d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 74d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 75d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_FLUSH_TLB: 762e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* FLUSH_TLB comes in two flavors, depending on the argument: */ 77b410e7b1499c49513cab18275db8a8ab549d9e09Jes Sorensen if (args->arg1) 784665ac8e28c30c2a015c617c55783c0bf3a49c05Glauber de Oliveira Costa guest_pagetable_clear_all(cpu); 79d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell else 801713608f280002d9ffc6de89d7de5cf367072d63Glauber de Oliveira Costa guest_pagetable_flush_user(cpu); 81d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 82bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell 832e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 842e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * All these calls simply pass the arguments through to the right 852e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * routines. 862e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 87d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_NEW_PGTABLE: 884665ac8e28c30c2a015c617c55783c0bf3a49c05Glauber de Oliveira Costa guest_new_pagetable(cpu, args->arg1); 89d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 90d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_SET_STACK: 914665ac8e28c30c2a015c617c55783c0bf3a49c05Glauber de Oliveira Costa guest_set_stack(cpu, args->arg1, args->arg2, args->arg3); 92d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 93d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_SET_PTE: 94acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui#ifdef CONFIG_X86_PAE 95acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui guest_set_pte(cpu, args->arg1, args->arg2, 96acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui __pte(args->arg3 | (u64)args->arg4 << 32)); 97acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui#else 98382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa guest_set_pte(cpu, args->arg1, args->arg2, __pte(args->arg3)); 99acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui#endif 100d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 101ebe0ba84f55950a89cb7af94c7ffc35ee3992f9eMatias Zabaljauregui case LHCALL_SET_PGD: 102ebe0ba84f55950a89cb7af94c7ffc35ee3992f9eMatias Zabaljauregui guest_set_pgd(cpu->lg, args->arg1, args->arg2); 103d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 104acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui#ifdef CONFIG_X86_PAE 105acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui case LHCALL_SET_PMD: 106acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui guest_set_pmd(cpu->lg, args->arg1, args->arg2); 107acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui break; 108acdd0b6292b282c4511897ac2691a47befbf1c6aMatias Zabaljauregui#endif 109d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_SET_CLOCKEVENT: 110ad8d8f3bc61ec712dd141e1029ae68c47fadc4a7Glauber de Oliveira Costa guest_set_clockevent(cpu, args->arg1); 111d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 112d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_TS: 113bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell /* This sets the TS flag, as we saw used in run_guest(). */ 1144665ac8e28c30c2a015c617c55783c0bf3a49c05Glauber de Oliveira Costa cpu->ts = args->arg1; 115d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 116d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell case LHCALL_HALT: 117bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell /* Similarly, this sets the halted flag for run_guest(). */ 11866686c2ab08feb721ca4d98285fba64acdf6017fGlauber de Oliveira Costa cpu->halted = 1; 119d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 12015045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell case LHCALL_NOTIFY: 1215e232f4f428c4266ba5cdae9f23ba19a0913dcf9Glauber de Oliveira Costa cpu->pending_notify = args->arg1; 12215045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell break; 123d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell default: 124e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell /* It should be an architecture-specific hypercall. */ 12573044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa if (lguest_arch_do_hcall(cpu, args)) 126382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "Bad hypercall %li\n", args->arg0); 127d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 128d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 129d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 1302e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell/*H:124 1312e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Asynchronous hypercalls are easy: we just look in the array in the 132b410e7b1499c49513cab18275db8a8ab549d9e09Jes Sorensen * Guest's "struct lguest_data" to see if any new ones are marked "ready". 133bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * 134bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * We are careful to do these in order: obviously we respect the order the 135bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * Guest put them in the ring, but we also promise the Guest that they will 136bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * happen before any normal hypercall (which is why we check this before 1372e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * checking for a normal hcall). 1382e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 13973044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costastatic void do_async_hcalls(struct lg_cpu *cpu) 140d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 141d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell unsigned int i; 142d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell u8 st[LHCALL_RING_SIZE]; 143d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 144bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell /* For simplicity, we copy the entire call status array in at once. */ 145382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa if (copy_from_user(&st, &cpu->lg->lguest_data->hcall_status, sizeof(st))) 146d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return; 147d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 148bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell /* We process "struct lguest_data"s hcalls[] ring once. */ 149d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell for (i = 0; i < ARRAY_SIZE(st); i++) { 150b410e7b1499c49513cab18275db8a8ab549d9e09Jes Sorensen struct hcall_args args; 1512e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 1522e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * We remember where we were up to from last time. This makes 153bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * sure that the hypercalls are done in the order the Guest 1542e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * places them in the ring. 1552e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 15673044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa unsigned int n = cpu->next_hcall; 157d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 158bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell /* 0xFF means there's no call here (yet). */ 159d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell if (st[n] == 0xFF) 160d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 161d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 1622e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 1632e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * OK, we have hypercall. Increment the "next_hcall" cursor, 1642e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * and wrap back to 0 if we reach the end. 1652e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 16673044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa if (++cpu->next_hcall == LHCALL_RING_SIZE) 16773044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa cpu->next_hcall = 0; 168d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 1692e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 1702e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Copy the hypercall arguments into a local copy of the 1712e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * hcall_args struct. 1722e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 173382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa if (copy_from_user(&args, &cpu->lg->lguest_data->hcalls[n], 174b410e7b1499c49513cab18275db8a8ab549d9e09Jes Sorensen sizeof(struct hcall_args))) { 175382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "Fetching async hypercalls"); 176d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 177d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 178d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 179bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell /* Do the hypercall, same as a normal one. */ 18073044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa do_hcall(cpu, &args); 181bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell 182bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell /* Mark the hypercall done. */ 183382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa if (put_user(0xFF, &cpu->lg->lguest_data->hcall_status[n])) { 184382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "Writing result for async hypercall"); 185d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 186d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 187d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 1882e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 1892e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Stop doing hypercalls if they want to notify the Launcher: 1902e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * it needs to service this first. 1912e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 1925e232f4f428c4266ba5cdae9f23ba19a0913dcf9Glauber de Oliveira Costa if (cpu->pending_notify) 193d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell break; 194d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 195d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 196d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 1972e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell/* 1982e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Last of all, we look at what happens first of all. The very first time the 1992e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Guest makes a hypercall, we end up here to set things up: 2002e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 20173044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costastatic void initialize(struct lg_cpu *cpu) 202d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 2032e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 2042e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * You can't do anything until you're initialized. The Guest knows the 2052e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * rules, so we're unforgiving here. 2062e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 20773044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa if (cpu->hcall->arg0 != LHCALL_LGUEST_INIT) { 208382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "hypercall %li before INIT", cpu->hcall->arg0); 209d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return; 210d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 211d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 21273044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa if (lguest_arch_init_hypercalls(cpu)) 213382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data); 2143c6b5bfa3cf3b4057788e08482a468cc3bc00780Rusty Russell 2152e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 2162e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * The Guest tells us where we're not to deliver interrupts by putting 2172e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * the range of addresses into "struct lguest_data". 2182e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 219382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa if (get_user(cpu->lg->noirq_start, &cpu->lg->lguest_data->noirq_start) 220382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa || get_user(cpu->lg->noirq_end, &cpu->lg->lguest_data->noirq_end)) 221382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data); 222d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 2232e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 2242e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * We write the current time into the Guest's data page once so it can 2252e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * set its clock. 2262e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 227382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa write_timestamp(cpu); 2286c8dca5d53f95009d4fff00195bf38f277dc4366Rusty Russell 22947436aa4ad054c1c7c8231618e86ebd9305308dcRusty Russell /* page_tables.c will also do some setup. */ 230382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa page_table_guest_data_init(cpu); 23147436aa4ad054c1c7c8231618e86ebd9305308dcRusty Russell 2322e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 2332e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * This is the one case where the above accesses might have been the 234bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * first write to a Guest page. This may have caused a copy-on-write 235e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * fault, but the old page might be (read-only) in the Guest 2362e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * pagetable. 2372e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 2384665ac8e28c30c2a015c617c55783c0bf3a49c05Glauber de Oliveira Costa guest_pagetable_clear_all(cpu); 239d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 240a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell/*:*/ 241a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell 2422e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell/*M:013 2432e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * If a Guest reads from a page (so creates a mapping) that it has never 244a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * written to, and then the Launcher writes to it (ie. the output of a virtual 245a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * device), the Guest will still see the old page. In practice, this never 246a6bd8e13034dd7d60b6f14217096efa192d0adc1Rusty Russell * happens: why would the Guest read a page which it has never written to? But 2472e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * a similar scenario might one day bite us, so it's worth mentioning. 248a91d74a3c4de8115295ee87350c13a329164aaafRusty Russell * 249a91d74a3c4de8115295ee87350c13a329164aaafRusty Russell * Note that if we used a shared anonymous mapping in the Launcher instead of 250a91d74a3c4de8115295ee87350c13a329164aaafRusty Russell * mapping /dev/zero private, we wouldn't worry about cop-on-write. And we 251a91d74a3c4de8115295ee87350c13a329164aaafRusty Russell * need that to switch the Launcher to processes (away from threads) anyway. 2522e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell:*/ 253d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 254bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell/*H:100 255bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * Hypercalls 256bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * 257bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * Remember from the Guest, hypercalls come in two flavors: normal and 258bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * asynchronous. This file handles both of types. 259bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell */ 26073044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costavoid do_hypercalls(struct lg_cpu *cpu) 261d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell{ 262cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell /* Not initialized yet? This hypercall must do it. */ 26373044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa if (unlikely(!cpu->lg->lguest_data)) { 264cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell /* Set up the "struct lguest_data" */ 26573044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa initialize(cpu); 266cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell /* Hcall is done. */ 26773044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa cpu->hcall = NULL; 268d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell return; 269d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 270d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell 2712e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 2722e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * The Guest has initialized. 273bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell * 2742e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Look in the hypercall ring for the async hypercalls: 2752e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 27673044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa do_async_hcalls(cpu); 277bff672e630a015d5b54c8bfb16160b7edc39a57cRusty Russell 2782e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 2792e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * If we stopped reading the hypercall ring because the Guest did a 28015045275c32bf6d15d32c2eca8157be9c0ba6e45Rusty Russell * NOTIFY to the Launcher, we want to return now. Otherwise we do 2812e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * the hypercall. 2822e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 2835e232f4f428c4266ba5cdae9f23ba19a0913dcf9Glauber de Oliveira Costa if (!cpu->pending_notify) { 28473044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa do_hcall(cpu, cpu->hcall); 2852e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell /* 2862e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * Tricky point: we reset the hcall pointer to mark the 287cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell * hypercall as "done". We use the hcall pointer rather than 288cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell * the trap number to indicate a hypercall is pending. 289cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell * Normally it doesn't matter: the Guest will run again and 290cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell * update the trap number before we come back here. 291cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell * 292e1e72965ec2c02db99b415cd06c17ea90767e3a4Rusty Russell * However, if we are signalled or the Guest sends I/O to the 293cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell * Launcher, the run_guest() loop will exit without running the 294cc6d4fbcef328acdc9fa7023e69f39f753f72fe1Rusty Russell * Guest. When it comes back it would try to re-run the 2952e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * hypercall. Finding that bug sucked. 2962e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 29773044f05a4ac65f2df42753e9566444b9d2a660fGlauber de Oliveira Costa cpu->hcall = NULL; 298d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell } 299d7e28ffe6c74416b54345d6004fd0964c115b12cRusty Russell} 3006c8dca5d53f95009d4fff00195bf38f277dc4366Rusty Russell 3012e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell/* 3022e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * This routine supplies the Guest with time: it's used for wallclock time at 3032e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell * initial boot and as a rough time source if the TSC isn't available. 3042e04ef76916d1e29a077ea9d0f2003c8fd86724dRusty Russell */ 305382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costavoid write_timestamp(struct lg_cpu *cpu) 3066c8dca5d53f95009d4fff00195bf38f277dc4366Rusty Russell{ 3076c8dca5d53f95009d4fff00195bf38f277dc4366Rusty Russell struct timespec now; 3086c8dca5d53f95009d4fff00195bf38f277dc4366Rusty Russell ktime_get_real_ts(&now); 309382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa if (copy_to_user(&cpu->lg->lguest_data->time, 310382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa &now, sizeof(struct timespec))) 311382ac6b3fbc0ea6a5697fc6caaf7e7de12fa8b96Glauber de Oliveira Costa kill_guest(cpu, "Writing timestamp"); 3126c8dca5d53f95009d4fff00195bf38f277dc4366Rusty Russell} 313