From: Roger Pau Monne Date: Thu, 11 Jan 2018 11:41:19 +0000 (+0000) Subject: xen/pvshim: set correct domid value X-Git-Tag: archive/raspbian/4.11.1-1+rpi1~1^2~66^2~782 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=785190fa86512637e1b369cd53ac529a5441bceb;p=xen.git xen/pvshim: set correct domid value If domid is not provided by L0 set domid to 1 by default. Note that L0 not provinding the domid can cause trouble if the guest tries to use it's domid instead of DOMID_SELF when performing hypercalls that are forwarded to the L0 hypervisor. Since the domain created is no longer the hardware domain add a hook to the domain shutdown path in order to forward shutdown operations to the L0 hypervisor. Signed-off-by: Roger Pau Monné Signed-off-by: Sergey Dyasli --- diff --git a/xen/arch/x86/dom0_build.c b/xen/arch/x86/dom0_build.c index 907acad060..8600123516 100644 --- a/xen/arch/x86/dom0_build.c +++ b/xen/arch/x86/dom0_build.c @@ -472,7 +472,7 @@ int __init construct_dom0(struct domain *d, const module_t *image, int rc; /* Sanity! */ - BUG_ON(d->domain_id != 0); + BUG_ON(!pv_shim && d->domain_id != 0); BUG_ON(d->vcpu[0] == NULL); BUG_ON(d->vcpu[0]->is_initialised); diff --git a/xen/arch/x86/guest/xen.c b/xen/arch/x86/guest/xen.c index 27a6c47753..aff16a0e35 100644 --- a/xen/arch/x86/guest/xen.c +++ b/xen/arch/x86/guest/xen.c @@ -322,6 +322,11 @@ const unsigned long *__init hypervisor_reserved_pages(unsigned int *size) return reserved_pages; } +uint32_t hypervisor_cpuid_base(void) +{ + return xen_cpuid_base; +} + /* * Local variables: * mode: C diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c index 75365b0697..78351c9ee0 100644 --- a/xen/arch/x86/pv/shim.c +++ b/xen/arch/x86/pv/shim.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include @@ -27,6 +28,8 @@ #include #include +#include + #ifndef CONFIG_PV_SHIM_EXCLUSIVE bool pv_shim; boolean_param("pv-shim", pv_shim); @@ -91,6 +94,24 @@ void __init pv_shim_setup_dom(struct domain *d, l4_pgentry_t *l4start, #undef SET_AND_MAP_PARAM } +void pv_shim_shutdown(uint8_t reason) +{ + /* XXX: handle suspend */ + xen_hypercall_shutdown(reason); +} + +domid_t get_initial_domain_id(void) +{ + uint32_t eax, ebx, ecx, edx; + + if ( !pv_shim ) + return 0; + + cpuid(hypervisor_cpuid_base() + 4, &eax, &ebx, &ecx, &edx); + + return (eax & XEN_HVM_CPUID_DOMID_PRESENT) ? ecx : 1; +} + /* * Local variables: * mode: C diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 3ef70d1346..f329e6ce0a 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -105,6 +105,12 @@ unsigned long __read_mostly mmu_cr4_features = XEN_MINIMAL_CR4; #define SMEP_HVM_ONLY (-1) static s8 __initdata opt_smep = 1; +/* + * Initial domain place holder. Needs to be global so it can be created in + * __start_xen and unpaused in init_done. + */ +static struct domain *__initdata dom0; + static int __init parse_smep_param(const char *s) { if ( !*s ) @@ -577,11 +583,11 @@ static void noinline init_done(void) system_state = SYS_STATE_active; + domain_unpause_by_systemcontroller(dom0); + /* MUST be done prior to removing .init data. */ unregister_init_virtual_region(); - domain_unpause_by_systemcontroller(hardware_domain); - /* Zero the .init code and data. */ for ( va = __init_begin; va < _p(__init_end); va += PAGE_SIZE ) clear_page(va); @@ -660,7 +666,6 @@ void __init noreturn __start_xen(unsigned long mbi_p) unsigned long nr_pages, raw_max_page, modules_headroom, *module_map; int i, j, e820_warn = 0, bytes = 0; bool acpi_boot_table_init_done = false, relocated = false; - struct domain *dom0; struct ns16550_defaults ns16550 = { .data_bits = 8, .parity = 'n', @@ -1620,11 +1625,12 @@ void __init noreturn __start_xen(unsigned long mbi_p) } /* Create initial domain 0. */ - dom0 = domain_create(0, domcr_flags, 0, &config); + dom0 = domain_create(get_initial_domain_id(), domcr_flags, 0, &config); if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) ) panic("Error creating domain 0"); - dom0->is_privileged = 1; + if ( !pv_shim ) + dom0->is_privileged = 1; dom0->target = NULL; /* Grab the DOM0 command line. */ diff --git a/xen/common/domain.c b/xen/common/domain.c index 7af8d12512..ef566f7f45 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -43,6 +43,10 @@ #include #include +#ifdef CONFIG_X86 +#include +#endif + /* Linux config option: propageted to domain0 */ /* xen_processor_pmbits: xen control Cx, Px, ... */ unsigned int xen_processor_pmbits = XEN_PROCESSOR_PM_PX; @@ -697,6 +701,14 @@ void domain_shutdown(struct domain *d, u8 reason) { struct vcpu *v; +#ifdef CONFIG_X86 + if ( pv_shim ) + { + pv_shim_shutdown(reason); + return; + } +#endif + spin_lock(&d->shutdown_lock); if ( d->shutdown_code == SHUTDOWN_CODE_INVALID ) diff --git a/xen/include/asm-x86/guest/xen.h b/xen/include/asm-x86/guest/xen.h index 62255fda8b..ac48dcbe44 100644 --- a/xen/include/asm-x86/guest/xen.h +++ b/xen/include/asm-x86/guest/xen.h @@ -38,6 +38,7 @@ int hypervisor_alloc_unused_page(mfn_t *mfn); int hypervisor_free_unused_page(mfn_t mfn); void hypervisor_fixup_e820(struct e820map *e820); const unsigned long *hypervisor_reserved_pages(unsigned int *size); +uint32_t hypervisor_cpuid_base(void); DECLARE_PER_CPU(unsigned int, vcpu_id); DECLARE_PER_CPU(struct vcpu_info *, vcpu_info); @@ -66,6 +67,11 @@ static inline const unsigned long *hypervisor_reserved_pages(unsigned int *size) ASSERT_UNREACHABLE(); return NULL; }; +static inline uint32_t hypervisor_cpuid_base(void) +{ + ASSERT_UNREACHABLE(); + return 0; +}; #endif /* CONFIG_XEN_GUEST */ #endif /* __X86_GUEST_XEN_H__ */ diff --git a/xen/include/asm-x86/pv/shim.h b/xen/include/asm-x86/pv/shim.h index b0c361cba1..ff7c050dc6 100644 --- a/xen/include/asm-x86/pv/shim.h +++ b/xen/include/asm-x86/pv/shim.h @@ -35,6 +35,8 @@ void pv_shim_setup_dom(struct domain *d, l4_pgentry_t *l4start, unsigned long va_start, unsigned long store_va, unsigned long console_va, unsigned long vphysmap, start_info_t *si); +void pv_shim_shutdown(uint8_t reason); +domid_t get_initial_domain_id(void); #else @@ -47,6 +49,14 @@ static inline void pv_shim_setup_dom(struct domain *d, l4_pgentry_t *l4start, { ASSERT_UNREACHABLE(); } +static inline void pv_shim_shutdown(uint8_t reason) +{ + ASSERT_UNREACHABLE(); +} +static inline domid_t get_initial_domain_id(void) +{ + return 0; +} #endif