diff options
| -rw-r--r-- | arch/x86/include/asm/hypervisor.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/hypervisor.c | 1 | ||||
| -rw-r--r-- | arch/x86/xen/enlighten.c | 100 | ||||
| -rw-r--r-- | drivers/input/xen-kbdfront.c | 2 | ||||
| -rw-r--r-- | drivers/video/xen-fbfront.c | 2 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_probe.c | 21 |
6 files changed, 122 insertions, 5 deletions
diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index 70abda7058c8..ff2546ce7178 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h | |||
| @@ -45,5 +45,6 @@ extern const struct hypervisor_x86 *x86_hyper; | |||
| 45 | /* Recognized hypervisors */ | 45 | /* Recognized hypervisors */ |
| 46 | extern const struct hypervisor_x86 x86_hyper_vmware; | 46 | extern const struct hypervisor_x86 x86_hyper_vmware; |
| 47 | extern const struct hypervisor_x86 x86_hyper_ms_hyperv; | 47 | extern const struct hypervisor_x86 x86_hyper_ms_hyperv; |
| 48 | extern const struct hypervisor_x86 x86_hyper_xen_hvm; | ||
| 48 | 49 | ||
| 49 | #endif | 50 | #endif |
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index dd531cc56a8f..bffd47c10fed 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c | |||
| @@ -34,6 +34,7 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] = | |||
| 34 | { | 34 | { |
| 35 | &x86_hyper_vmware, | 35 | &x86_hyper_vmware, |
| 36 | &x86_hyper_ms_hyperv, | 36 | &x86_hyper_ms_hyperv, |
| 37 | &x86_hyper_xen_hvm, | ||
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | const struct hypervisor_x86 *x86_hyper; | 40 | const struct hypervisor_x86 *x86_hyper; |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 65d8d79b46a8..09b36e9d507a 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <xen/interface/version.h> | 35 | #include <xen/interface/version.h> |
| 36 | #include <xen/interface/physdev.h> | 36 | #include <xen/interface/physdev.h> |
| 37 | #include <xen/interface/vcpu.h> | 37 | #include <xen/interface/vcpu.h> |
| 38 | #include <xen/interface/memory.h> | ||
| 38 | #include <xen/features.h> | 39 | #include <xen/features.h> |
| 39 | #include <xen/page.h> | 40 | #include <xen/page.h> |
| 40 | #include <xen/hvc-console.h> | 41 | #include <xen/hvc-console.h> |
| @@ -55,7 +56,9 @@ | |||
| 55 | #include <asm/pgtable.h> | 56 | #include <asm/pgtable.h> |
| 56 | #include <asm/tlbflush.h> | 57 | #include <asm/tlbflush.h> |
| 57 | #include <asm/reboot.h> | 58 | #include <asm/reboot.h> |
| 59 | #include <asm/setup.h> | ||
| 58 | #include <asm/stackprotector.h> | 60 | #include <asm/stackprotector.h> |
| 61 | #include <asm/hypervisor.h> | ||
| 59 | 62 | ||
| 60 | #include "xen-ops.h" | 63 | #include "xen-ops.h" |
| 61 | #include "mmu.h" | 64 | #include "mmu.h" |
| @@ -76,6 +79,8 @@ struct shared_info xen_dummy_shared_info; | |||
| 76 | 79 | ||
| 77 | void *xen_initial_gdt; | 80 | void *xen_initial_gdt; |
| 78 | 81 | ||
| 82 | RESERVE_BRK(shared_info_page_brk, PAGE_SIZE); | ||
| 83 | |||
| 79 | /* | 84 | /* |
| 80 | * Point at some empty memory to start with. We map the real shared_info | 85 | * Point at some empty memory to start with. We map the real shared_info |
| 81 | * page as soon as fixmap is up and running. | 86 | * page as soon as fixmap is up and running. |
| @@ -1206,3 +1211,98 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1206 | x86_64_start_reservations((char *)__pa_symbol(&boot_params)); | 1211 | x86_64_start_reservations((char *)__pa_symbol(&boot_params)); |
| 1207 | #endif | 1212 | #endif |
| 1208 | } | 1213 | } |
| 1214 | |||
| 1215 | static uint32_t xen_cpuid_base(void) | ||
| 1216 | { | ||
| 1217 | uint32_t base, eax, ebx, ecx, edx; | ||
| 1218 | char signature[13]; | ||
| 1219 | |||
| 1220 | for (base = 0x40000000; base < 0x40010000; base += 0x100) { | ||
| 1221 | cpuid(base, &eax, &ebx, &ecx, &edx); | ||
| 1222 | *(uint32_t *)(signature + 0) = ebx; | ||
| 1223 | *(uint32_t *)(signature + 4) = ecx; | ||
| 1224 | *(uint32_t *)(signature + 8) = edx; | ||
| 1225 | signature[12] = 0; | ||
| 1226 | |||
| 1227 | if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2)) | ||
| 1228 | return base; | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | return 0; | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | static int init_hvm_pv_info(int *major, int *minor) | ||
| 1235 | { | ||
| 1236 | uint32_t eax, ebx, ecx, edx, pages, msr, base; | ||
| 1237 | u64 pfn; | ||
| 1238 | |||
| 1239 | base = xen_cpuid_base(); | ||
| 1240 | cpuid(base + 1, &eax, &ebx, &ecx, &edx); | ||
| 1241 | |||
| 1242 | *major = eax >> 16; | ||
| 1243 | *minor = eax & 0xffff; | ||
| 1244 | printk(KERN_INFO "Xen version %d.%d.\n", *major, *minor); | ||
| 1245 | |||
| 1246 | cpuid(base + 2, &pages, &msr, &ecx, &edx); | ||
| 1247 | |||
| 1248 | pfn = __pa(hypercall_page); | ||
| 1249 | wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32)); | ||
| 1250 | |||
| 1251 | xen_setup_features(); | ||
| 1252 | |||
| 1253 | pv_info = xen_info; | ||
| 1254 | pv_info.kernel_rpl = 0; | ||
| 1255 | |||
| 1256 | xen_domain_type = XEN_HVM_DOMAIN; | ||
| 1257 | |||
| 1258 | return 0; | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | static void __init init_shared_info(void) | ||
| 1262 | { | ||
| 1263 | struct xen_add_to_physmap xatp; | ||
| 1264 | struct shared_info *shared_info_page; | ||
| 1265 | |||
| 1266 | shared_info_page = (struct shared_info *) | ||
| 1267 | extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
| 1268 | xatp.domid = DOMID_SELF; | ||
| 1269 | xatp.idx = 0; | ||
| 1270 | xatp.space = XENMAPSPACE_shared_info; | ||
| 1271 | xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT; | ||
| 1272 | if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) | ||
| 1273 | BUG(); | ||
| 1274 | |||
| 1275 | HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; | ||
| 1276 | |||
| 1277 | per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | static void __init xen_hvm_guest_init(void) | ||
| 1281 | { | ||
| 1282 | int r; | ||
| 1283 | int major, minor; | ||
| 1284 | |||
| 1285 | r = init_hvm_pv_info(&major, &minor); | ||
| 1286 | if (r < 0) | ||
| 1287 | return; | ||
| 1288 | |||
| 1289 | init_shared_info(); | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | static bool __init xen_hvm_platform(void) | ||
| 1293 | { | ||
| 1294 | if (xen_pv_domain()) | ||
| 1295 | return false; | ||
| 1296 | |||
| 1297 | if (!xen_cpuid_base()) | ||
| 1298 | return false; | ||
| 1299 | |||
| 1300 | return true; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | const __refconst struct hypervisor_x86 x86_hyper_xen_hvm = { | ||
| 1304 | .name = "Xen HVM", | ||
| 1305 | .detect = xen_hvm_platform, | ||
| 1306 | .init_platform = xen_hvm_guest_init, | ||
| 1307 | }; | ||
| 1308 | EXPORT_SYMBOL(x86_hyper_xen_hvm); | ||
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index e14081675bb2..ebb11907d402 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c | |||
| @@ -339,7 +339,7 @@ static struct xenbus_driver xenkbd_driver = { | |||
| 339 | 339 | ||
| 340 | static int __init xenkbd_init(void) | 340 | static int __init xenkbd_init(void) |
| 341 | { | 341 | { |
| 342 | if (!xen_domain()) | 342 | if (!xen_pv_domain()) |
| 343 | return -ENODEV; | 343 | return -ENODEV; |
| 344 | 344 | ||
| 345 | /* Nothing to do if running in dom0. */ | 345 | /* Nothing to do if running in dom0. */ |
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index fa97d3e7c21a..7c7f42a12796 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c | |||
| @@ -684,7 +684,7 @@ static struct xenbus_driver xenfb_driver = { | |||
| 684 | 684 | ||
| 685 | static int __init xenfb_init(void) | 685 | static int __init xenfb_init(void) |
| 686 | { | 686 | { |
| 687 | if (!xen_domain()) | 687 | if (!xen_pv_domain()) |
| 688 | return -ENODEV; | 688 | return -ENODEV; |
| 689 | 689 | ||
| 690 | /* Nothing to do if running in dom0. */ | 690 | /* Nothing to do if running in dom0. */ |
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 3479332113e9..d96fa75b45ec 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
| @@ -56,6 +56,8 @@ | |||
| 56 | #include <xen/events.h> | 56 | #include <xen/events.h> |
| 57 | #include <xen/page.h> | 57 | #include <xen/page.h> |
| 58 | 58 | ||
| 59 | #include <xen/hvm.h> | ||
| 60 | |||
| 59 | #include "xenbus_comms.h" | 61 | #include "xenbus_comms.h" |
| 60 | #include "xenbus_probe.h" | 62 | #include "xenbus_probe.h" |
| 61 | 63 | ||
| @@ -805,11 +807,24 @@ static int __init xenbus_probe_init(void) | |||
| 805 | if (xen_initial_domain()) { | 807 | if (xen_initial_domain()) { |
| 806 | /* dom0 not yet supported */ | 808 | /* dom0 not yet supported */ |
| 807 | } else { | 809 | } else { |
| 810 | if (xen_hvm_domain()) { | ||
| 811 | uint64_t v = 0; | ||
| 812 | err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); | ||
| 813 | if (err) | ||
| 814 | goto out_error; | ||
| 815 | xen_store_evtchn = (int)v; | ||
| 816 | err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v); | ||
| 817 | if (err) | ||
| 818 | goto out_error; | ||
| 819 | xen_store_mfn = (unsigned long)v; | ||
| 820 | xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE); | ||
| 821 | } else { | ||
| 822 | xen_store_evtchn = xen_start_info->store_evtchn; | ||
| 823 | xen_store_mfn = xen_start_info->store_mfn; | ||
| 824 | xen_store_interface = mfn_to_virt(xen_store_mfn); | ||
| 825 | } | ||
| 808 | xenstored_ready = 1; | 826 | xenstored_ready = 1; |
| 809 | xen_store_evtchn = xen_start_info->store_evtchn; | ||
| 810 | xen_store_mfn = xen_start_info->store_mfn; | ||
| 811 | } | 827 | } |
| 812 | xen_store_interface = mfn_to_virt(xen_store_mfn); | ||
| 813 | 828 | ||
| 814 | /* Initialize the interface to xenstore. */ | 829 | /* Initialize the interface to xenstore. */ |
| 815 | err = xs_init(); | 830 | err = xs_init(); |
