Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sheng Yang and committed by
Jeremy Fitzhardinge
bee6ab53 18f19aa6

+122 -5
+1
arch/x86/include/asm/hypervisor.h
··· 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
+1
arch/x86/kernel/cpu/hypervisor.c
··· 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;
+100
arch/x86/xen/enlighten.c
··· 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> ··· 56 55 #include <asm/pgtable.h> 57 56 #include <asm/tlbflush.h> 58 57 #include <asm/reboot.h> 58 + #include <asm/setup.h> 59 59 #include <asm/stackprotector.h> 60 + #include <asm/hypervisor.h> 60 61 61 62 #include "xen-ops.h" 62 63 #include "mmu.h" ··· 78 75 struct shared_info xen_dummy_shared_info; 79 76 80 77 void *xen_initial_gdt; 78 + 79 + RESERVE_BRK(shared_info_page_brk, PAGE_SIZE); 81 80 82 81 /* 83 82 * Point at some empty memory to start with. We map the real shared_info ··· 1211 1206 x86_64_start_reservations((char *)__pa_symbol(&boot_params)); 1212 1207 #endif 1213 1208 } 1209 + 1210 + static uint32_t xen_cpuid_base(void) 1211 + { 1212 + uint32_t base, eax, ebx, ecx, edx; 1213 + char signature[13]; 1214 + 1215 + for (base = 0x40000000; base < 0x40010000; base += 0x100) { 1216 + cpuid(base, &eax, &ebx, &ecx, &edx); 1217 + *(uint32_t *)(signature + 0) = ebx; 1218 + *(uint32_t *)(signature + 4) = ecx; 1219 + *(uint32_t *)(signature + 8) = edx; 1220 + signature[12] = 0; 1221 + 1222 + if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2)) 1223 + return base; 1224 + } 1225 + 1226 + return 0; 1227 + } 1228 + 1229 + static int init_hvm_pv_info(int *major, int *minor) 1230 + { 1231 + uint32_t eax, ebx, ecx, edx, pages, msr, base; 1232 + u64 pfn; 1233 + 1234 + base = xen_cpuid_base(); 1235 + cpuid(base + 1, &eax, &ebx, &ecx, &edx); 1236 + 1237 + *major = eax >> 16; 1238 + *minor = eax & 0xffff; 1239 + printk(KERN_INFO "Xen version %d.%d.\n", *major, *minor); 1240 + 1241 + cpuid(base + 2, &pages, &msr, &ecx, &edx); 1242 + 1243 + pfn = __pa(hypercall_page); 1244 + wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32)); 1245 + 1246 + xen_setup_features(); 1247 + 1248 + pv_info = xen_info; 1249 + pv_info.kernel_rpl = 0; 1250 + 1251 + xen_domain_type = XEN_HVM_DOMAIN; 1252 + 1253 + return 0; 1254 + } 1255 + 1256 + static void __init init_shared_info(void) 1257 + { 1258 + struct xen_add_to_physmap xatp; 1259 + struct shared_info *shared_info_page; 1260 + 1261 + shared_info_page = (struct shared_info *) 1262 + extend_brk(PAGE_SIZE, PAGE_SIZE); 1263 + xatp.domid = DOMID_SELF; 1264 + xatp.idx = 0; 1265 + xatp.space = XENMAPSPACE_shared_info; 1266 + xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT; 1267 + if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) 1268 + BUG(); 1269 + 1270 + HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; 1271 + 1272 + per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; 1273 + } 1274 + 1275 + static void __init xen_hvm_guest_init(void) 1276 + { 1277 + int r; 1278 + int major, minor; 1279 + 1280 + r = init_hvm_pv_info(&major, &minor); 1281 + if (r < 0) 1282 + return; 1283 + 1284 + init_shared_info(); 1285 + } 1286 + 1287 + static bool __init xen_hvm_platform(void) 1288 + { 1289 + if (xen_pv_domain()) 1290 + return false; 1291 + 1292 + if (!xen_cpuid_base()) 1293 + return false; 1294 + 1295 + return true; 1296 + } 1297 + 1298 + const __refconst struct hypervisor_x86 x86_hyper_xen_hvm = { 1299 + .name = "Xen HVM", 1300 + .detect = xen_hvm_platform, 1301 + .init_platform = xen_hvm_guest_init, 1302 + }; 1303 + EXPORT_SYMBOL(x86_hyper_xen_hvm);
+1 -1
drivers/input/xen-kbdfront.c
··· 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. */
+1 -1
drivers/video/xen-fbfront.c
··· 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. */
+18 -3
drivers/xen/xenbus/xenbus_probe.c
··· 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 ··· 807 805 if (xen_initial_domain()) { 808 806 /* dom0 not yet supported */ 809 807 } else { 808 + if (xen_hvm_domain()) { 809 + uint64_t v = 0; 810 + err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); 811 + if (err) 812 + goto out_error; 813 + xen_store_evtchn = (int)v; 814 + err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v); 815 + if (err) 816 + goto out_error; 817 + xen_store_mfn = (unsigned long)v; 818 + xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE); 819 + } else { 820 + xen_store_evtchn = xen_start_info->store_evtchn; 821 + xen_store_mfn = xen_start_info->store_mfn; 822 + xen_store_interface = mfn_to_virt(xen_store_mfn); 823 + } 810 824 xenstored_ready = 1; 811 - xen_store_evtchn = xen_start_info->store_evtchn; 812 - xen_store_mfn = xen_start_info->store_mfn; 813 825 } 814 - xen_store_interface = mfn_to_virt(xen_store_mfn); 815 826 816 827 /* Initialize the interface to xenstore. */ 817 828 err = xs_init();