diff options
author | Sheng Yang <sheng@linux.intel.com> | 2010-05-14 07:39:33 -0400 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2010-07-22 19:45:35 -0400 |
commit | bee6ab53e652a414af20392899879b58cd80d033 (patch) | |
tree | 96351c583984ec497feae270f09f445a4703a676 | |
parent | 18f19aa62a267f2f759e278018f1032adf4c3774 (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.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(); |