Commit bee6ab53e652a414af20392899879b58cd80d033
Committed by
Jeremy Fitzhardinge
1 parent
18f19aa62a
Exists in
master
and in
7 other branches
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
arch/x86/kernel/cpu/hypervisor.c
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
drivers/video/xen-fbfront.c
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(); |