aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/lguest/boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/lguest/boot.c')
-rw-r--r--arch/x86/lguest/boot.c173
1 files changed, 153 insertions, 20 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index c1c1544b8485..ac4453d8520e 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -56,6 +56,9 @@
56#include <linux/virtio_console.h> 56#include <linux/virtio_console.h>
57#include <linux/pm.h> 57#include <linux/pm.h>
58#include <linux/export.h> 58#include <linux/export.h>
59#include <linux/pci.h>
60#include <linux/virtio_pci.h>
61#include <asm/acpi.h>
59#include <asm/apic.h> 62#include <asm/apic.h>
60#include <asm/lguest.h> 63#include <asm/lguest.h>
61#include <asm/paravirt.h> 64#include <asm/paravirt.h>
@@ -71,6 +74,8 @@
71#include <asm/stackprotector.h> 74#include <asm/stackprotector.h>
72#include <asm/reboot.h> /* for struct machine_ops */ 75#include <asm/reboot.h> /* for struct machine_ops */
73#include <asm/kvm_para.h> 76#include <asm/kvm_para.h>
77#include <asm/pci_x86.h>
78#include <asm/pci-direct.h>
74 79
75/*G:010 80/*G:010
76 * Welcome to the Guest! 81 * Welcome to the Guest!
@@ -831,6 +836,24 @@ static struct irq_chip lguest_irq_controller = {
831 .irq_unmask = enable_lguest_irq, 836 .irq_unmask = enable_lguest_irq,
832}; 837};
833 838
839static int lguest_enable_irq(struct pci_dev *dev)
840{
841 u8 line = 0;
842
843 /* We literally use the PCI interrupt line as the irq number. */
844 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
845 irq_set_chip_and_handler_name(line, &lguest_irq_controller,
846 handle_level_irq, "level");
847 dev->irq = line;
848 return 0;
849}
850
851/* We don't do hotplug PCI, so this shouldn't be called. */
852static void lguest_disable_irq(struct pci_dev *dev)
853{
854 WARN_ON(1);
855}
856
834/* 857/*
835 * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware 858 * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware
836 * interrupt (except 128, which is used for system calls), and then tells the 859 * interrupt (except 128, which is used for system calls), and then tells the
@@ -1181,25 +1204,136 @@ static __init char *lguest_memory_setup(void)
1181 return "LGUEST"; 1204 return "LGUEST";
1182} 1205}
1183 1206
1207/* Offset within PCI config space of BAR access capability. */
1208static int console_cfg_offset = 0;
1209static int console_access_cap;
1210
1211/* Set up so that we access off in bar0 (on bus 0, device 1, function 0) */
1212static void set_cfg_window(u32 cfg_offset, u32 off)
1213{
1214 write_pci_config_byte(0, 1, 0,
1215 cfg_offset + offsetof(struct virtio_pci_cap, bar),
1216 0);
1217 write_pci_config(0, 1, 0,
1218 cfg_offset + offsetof(struct virtio_pci_cap, length),
1219 4);
1220 write_pci_config(0, 1, 0,
1221 cfg_offset + offsetof(struct virtio_pci_cap, offset),
1222 off);
1223}
1224
1225static void write_bar_via_cfg(u32 cfg_offset, u32 off, u32 val)
1226{
1227 /*
1228 * We could set this up once, then leave it; nothing else in the *
1229 * kernel should touch these registers. But if it went wrong, that
1230 * would be a horrible bug to find.
1231 */
1232 set_cfg_window(cfg_offset, off);
1233 write_pci_config(0, 1, 0,
1234 cfg_offset + sizeof(struct virtio_pci_cap), val);
1235}
1236
1237static void probe_pci_console(void)
1238{
1239 u8 cap, common_cap = 0, device_cap = 0;
1240 /* Offset within BAR0 */
1241 u32 device_offset;
1242 u32 device_len;
1243
1244 /* Avoid recursive printk into here. */
1245 console_cfg_offset = -1;
1246
1247 if (!early_pci_allowed()) {
1248 printk(KERN_ERR "lguest: early PCI access not allowed!\n");
1249 return;
1250 }
1251
1252 /* We expect a console PCI device at BUS0, slot 1. */
1253 if (read_pci_config(0, 1, 0, 0) != 0x10431AF4) {
1254 printk(KERN_ERR "lguest: PCI device is %#x!\n",
1255 read_pci_config(0, 1, 0, 0));
1256 return;
1257 }
1258
1259 /* Find the capabilities we need (must be in bar0) */
1260 cap = read_pci_config_byte(0, 1, 0, PCI_CAPABILITY_LIST);
1261 while (cap) {
1262 u8 vndr = read_pci_config_byte(0, 1, 0, cap);
1263 if (vndr == PCI_CAP_ID_VNDR) {
1264 u8 type, bar;
1265 u32 offset, length;
1266
1267 type = read_pci_config_byte(0, 1, 0,
1268 cap + offsetof(struct virtio_pci_cap, cfg_type));
1269 bar = read_pci_config_byte(0, 1, 0,
1270 cap + offsetof(struct virtio_pci_cap, bar));
1271 offset = read_pci_config(0, 1, 0,
1272 cap + offsetof(struct virtio_pci_cap, offset));
1273 length = read_pci_config(0, 1, 0,
1274 cap + offsetof(struct virtio_pci_cap, length));
1275
1276 switch (type) {
1277 case VIRTIO_PCI_CAP_DEVICE_CFG:
1278 if (bar == 0) {
1279 device_cap = cap;
1280 device_offset = offset;
1281 device_len = length;
1282 }
1283 break;
1284 case VIRTIO_PCI_CAP_PCI_CFG:
1285 console_access_cap = cap;
1286 break;
1287 }
1288 }
1289 cap = read_pci_config_byte(0, 1, 0, cap + PCI_CAP_LIST_NEXT);
1290 }
1291 if (!device_cap || !console_access_cap) {
1292 printk(KERN_ERR "lguest: No caps (%u/%u/%u) in console!\n",
1293 common_cap, device_cap, console_access_cap);
1294 return;
1295 }
1296
1297 /*
1298 * Note that we can't check features, until we've set the DRIVER
1299 * status bit. We don't want to do that until we have a real driver,
1300 * so we just check that the device-specific config has room for
1301 * emerg_wr. If it doesn't support VIRTIO_CONSOLE_F_EMERG_WRITE
1302 * it should ignore the access.
1303 */
1304 if (device_len < (offsetof(struct virtio_console_config, emerg_wr)
1305 + sizeof(u32))) {
1306 printk(KERN_ERR "lguest: console missing emerg_wr field\n");
1307 return;
1308 }
1309
1310 console_cfg_offset = device_offset;
1311 printk(KERN_INFO "lguest: Console via virtio-pci emerg_wr\n");
1312}
1313
1184/* 1314/*
1185 * We will eventually use the virtio console device to produce console output, 1315 * We will eventually use the virtio console device to produce console output,
1186 * but before that is set up we use LHCALL_NOTIFY on normal memory to produce 1316 * but before that is set up we use the virtio PCI console's backdoor mmio
1187 * console output. 1317 * access and the "emergency" write facility (which is legal even before the
1318 * device is configured).
1188 */ 1319 */
1189static __init int early_put_chars(u32 vtermno, const char *buf, int count) 1320static __init int early_put_chars(u32 vtermno, const char *buf, int count)
1190{ 1321{
1191 char scratch[17]; 1322 /* If we couldn't find PCI console, forget it. */
1192 unsigned int len = count; 1323 if (console_cfg_offset < 0)
1324 return count;
1193 1325
1194 /* We use a nul-terminated string, so we make a copy. Icky, huh? */ 1326 if (unlikely(!console_cfg_offset)) {
1195 if (len > sizeof(scratch) - 1) 1327 probe_pci_console();
1196 len = sizeof(scratch) - 1; 1328 if (console_cfg_offset < 0)
1197 scratch[len] = '\0'; 1329 return count;
1198 memcpy(scratch, buf, len); 1330 }
1199 hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0);
1200 1331
1201 /* This routine returns the number of bytes actually written. */ 1332 write_bar_via_cfg(console_access_cap,
1202 return len; 1333 console_cfg_offset
1334 + offsetof(struct virtio_console_config, emerg_wr),
1335 buf[0]);
1336 return 1;
1203} 1337}
1204 1338
1205/* 1339/*
@@ -1400,14 +1534,6 @@ __init void lguest_init(void)
1400 atomic_notifier_chain_register(&panic_notifier_list, &paniced); 1534 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
1401 1535
1402 /* 1536 /*
1403 * The IDE code spends about 3 seconds probing for disks: if we reserve
1404 * all the I/O ports up front it can't get them and so doesn't probe.
1405 * Other device drivers are similar (but less severe). This cuts the
1406 * kernel boot time on my machine from 4.1 seconds to 0.45 seconds.
1407 */
1408 paravirt_disable_iospace();
1409
1410 /*
1411 * This is messy CPU setup stuff which the native boot code does before 1537 * This is messy CPU setup stuff which the native boot code does before
1412 * start_kernel, so we have to do, too: 1538 * start_kernel, so we have to do, too:
1413 */ 1539 */
@@ -1436,6 +1562,13 @@ __init void lguest_init(void)
1436 /* Register our very early console. */ 1562 /* Register our very early console. */
1437 virtio_cons_early_init(early_put_chars); 1563 virtio_cons_early_init(early_put_chars);
1438 1564
1565 /* Don't let ACPI try to control our PCI interrupts. */
1566 disable_acpi();
1567
1568 /* We control them ourselves, by overriding these two hooks. */
1569 pcibios_enable_irq = lguest_enable_irq;
1570 pcibios_disable_irq = lguest_disable_irq;
1571
1439 /* 1572 /*
1440 * Last of all, we set the power management poweroff hook to point to 1573 * Last of all, we set the power management poweroff hook to point to
1441 * the Guest routine to power off, and the reboot hook to our restart 1574 * the Guest routine to power off, and the reboot hook to our restart