aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSheng Yang <sheng@linux.intel.com>2010-05-14 07:39:33 -0400
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2010-07-22 19:45:35 -0400
commitbee6ab53e652a414af20392899879b58cd80d033 (patch)
tree96351c583984ec497feae270f09f445a4703a676
parent18f19aa62a267f2f759e278018f1032adf4c3774 (diff)
x86: early PV on HVM features initialization.
Initialize basic pv on hvm features adding a new Xen HVM specific hypervisor_x86 structure. Don't try to initialize xen-kbdfront and xen-fbfront when running on HVM because the backends are not available. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Sheng Yang <sheng@linux.intel.com> Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
-rw-r--r--arch/x86/include/asm/hypervisor.h1
-rw-r--r--arch/x86/kernel/cpu/hypervisor.c1
-rw-r--r--arch/x86/xen/enlighten.c100
-rw-r--r--drivers/input/xen-kbdfront.c2
-rw-r--r--drivers/video/xen-fbfront.c2
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c21
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 */
46extern const struct hypervisor_x86 x86_hyper_vmware; 46extern const struct hypervisor_x86 x86_hyper_vmware;
47extern const struct hypervisor_x86 x86_hyper_ms_hyperv; 47extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
48extern 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
39const struct hypervisor_x86 *x86_hyper; 40const 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
77void *xen_initial_gdt; 80void *xen_initial_gdt;
78 81
82RESERVE_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
1215static 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
1234static 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
1261static 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
1280static 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
1292static 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
1303const __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};
1308EXPORT_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
340static int __init xenkbd_init(void) 340static 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
685static int __init xenfb_init(void) 685static 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();