Commit bee6ab53e652a414af20392899879b58cd80d033

Authored by Sheng Yang
Committed by Jeremy Fitzhardinge
1 parent 18f19aa62a

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>

Showing 6 changed files with 122 additions and 5 deletions Side-by-side Diff

arch/x86/include/asm/hypervisor.h
... ... @@ -45,6 +45,7 @@
45 45 /* Recognized hypervisors */
46 46 extern const struct hypervisor_x86 x86_hyper_vmware;
47 47 extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
  48 +extern const struct hypervisor_x86 x86_hyper_xen_hvm;
48 49  
49 50 #endif
arch/x86/kernel/cpu/hypervisor.c
... ... @@ -34,6 +34,7 @@
34 34 {
35 35 &x86_hyper_vmware,
36 36 &x86_hyper_ms_hyperv,
  37 + &x86_hyper_xen_hvm,
37 38 };
38 39  
39 40 const struct hypervisor_x86 *x86_hyper;
arch/x86/xen/enlighten.c
... ... @@ -35,6 +35,7 @@
35 35 #include <xen/interface/version.h>
36 36 #include <xen/interface/physdev.h>
37 37 #include <xen/interface/vcpu.h>
  38 +#include <xen/interface/memory.h>
38 39 #include <xen/features.h>
39 40 #include <xen/page.h>
40 41 #include <xen/hvc-console.h>
41 42  
... ... @@ -55,7 +56,9 @@
55 56 #include <asm/pgtable.h>
56 57 #include <asm/tlbflush.h>
57 58 #include <asm/reboot.h>
  59 +#include <asm/setup.h>
58 60 #include <asm/stackprotector.h>
  61 +#include <asm/hypervisor.h>
59 62  
60 63 #include "xen-ops.h"
61 64 #include "mmu.h"
... ... @@ -76,6 +79,8 @@
76 79  
77 80 void *xen_initial_gdt;
78 81  
  82 +RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
  83 +
79 84 /*
80 85 * Point at some empty memory to start with. We map the real shared_info
81 86 * page as soon as fixmap is up and running.
... ... @@ -1206,4 +1211,99 @@
1206 1211 x86_64_start_reservations((char *)__pa_symbol(&boot_params));
1207 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);
drivers/input/xen-kbdfront.c
... ... @@ -339,7 +339,7 @@
339 339  
340 340 static int __init xenkbd_init(void)
341 341 {
342   - if (!xen_domain())
  342 + if (!xen_pv_domain())
343 343 return -ENODEV;
344 344  
345 345 /* Nothing to do if running in dom0. */
drivers/video/xen-fbfront.c
... ... @@ -684,7 +684,7 @@
684 684  
685 685 static int __init xenfb_init(void)
686 686 {
687   - if (!xen_domain())
  687 + if (!xen_pv_domain())
688 688 return -ENODEV;
689 689  
690 690 /* Nothing to do if running in dom0. */
drivers/xen/xenbus/xenbus_probe.c
... ... @@ -56,6 +56,8 @@
56 56 #include <xen/events.h>
57 57 #include <xen/page.h>
58 58  
  59 +#include <xen/hvm.h>
  60 +
59 61 #include "xenbus_comms.h"
60 62 #include "xenbus_probe.h"
61 63  
62 64  
63 65  
... ... @@ -805,11 +807,24 @@
805 807 if (xen_initial_domain()) {
806 808 /* dom0 not yet supported */
807 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 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 829 /* Initialize the interface to xenstore. */
815 830 err = xs_init();