# HG changeset patch # User cegger # Date 1271330313 -7200 Implement generic piece to finally enable nested virtualization diff -r d6e8a032d71f -r f96f6f2cd19a xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -411,6 +411,10 @@ int arch_domain_create(struct domain *d, (domcr_flags & DOMCRF_hap); d->arch.hvm_domain.mem_sharing_enabled = 0; + d->arch.hvm_domain.nestedhvm_enabled = + is_hvm_domain(d) && + (domcr_flags & DOMCRF_nestedhvm); + d->arch.s3_integrity = !!(domcr_flags & DOMCRF_s3_integrity); INIT_LIST_HEAD(&d->arch.pdev_list); diff -r d6e8a032d71f -r f96f6f2cd19a xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -798,10 +798,16 @@ int hvm_vcpu_initialise(struct vcpu *v) if ( (rc = hvm_funcs.vcpu_initialise(v)) != 0 ) goto fail2; + rc = nestedhvm_vcpu_initialise(v); + if ( rc < 0 ) { + printk("%s: nestedhvm_vcpu_initialise returned %i\n", __func__, rc); + goto fail3; + } + /* Create ioreq event channel. */ rc = alloc_unbound_xen_event_channel(v, 0); if ( rc < 0 ) - goto fail3; + goto fail4; /* Register ioreq event channel. */ v->arch.hvm_vcpu.xen_port = rc; @@ -815,7 +821,7 @@ int hvm_vcpu_initialise(struct vcpu *v) rc = hvm_vcpu_cacheattr_init(v); if ( rc != 0 ) - goto fail3; + goto fail4; tasklet_init(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet, (void(*)(unsigned long))hvm_assert_evtchn_irq, @@ -840,6 +846,8 @@ int hvm_vcpu_initialise(struct vcpu *v) return 0; + fail4: + nestedhvm_vcpu_destroy(v); fail3: hvm_funcs.vcpu_destroy(v); fail2: @@ -850,6 +858,12 @@ int hvm_vcpu_initialise(struct vcpu *v) void hvm_vcpu_destroy(struct vcpu *v) { + int rc; + + rc = nestedhvm_vcpu_destroy(v); + if (rc < 0) + printk("%s: nestedhvm_vcpu_destroy() failed with %i\n", __func__, rc); + tasklet_kill(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet); hvm_vcpu_cacheattr_destroy(v); vlapic_destroy(v); @@ -3217,6 +3231,7 @@ int hvm_debug_op(struct vcpu *v, int32_t return rc; } + int hvm_nestedhvm_vcpu_initialise(struct vcpu *v) { if (hvm_funcs.nestedhvm_vcpu_initialise) diff -r d6e8a032d71f -r f96f6f2cd19a xen/common/domctl.c --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -430,6 +430,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc domcr_flags |= DOMCRF_s3_integrity; if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_oos_off ) domcr_flags |= DOMCRF_oos_off; + if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_nestedhvm ) + domcr_flags |= DOMCRF_nestedhvm; ret = -ENOMEM; d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref); diff -r d6e8a032d71f -r f96f6f2cd19a xen/include/xen/sched.h --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -391,8 +391,13 @@ struct domain *domain_create( #define _DOMCRF_dummy 3 #define DOMCRF_dummy (1U<<_DOMCRF_dummy) /* DOMCRF_oos_off: dont use out-of-sync optimization for shadow page tables */ -#define _DOMCRF_oos_off 4 -#define DOMCRF_oos_off (1U<<_DOMCRF_oos_off) +#define _DOMCRF_oos_off 4 +#define DOMCRF_oos_off (1U<<_DOMCRF_oos_off) + /* DOMCRF_nestedhvm: Create a domain with SVM capability. + * Only valid for HVM domains. + */ +#define _DOMCRF_nestedhvm 5 +#define DOMCRF_nestedhvm (1U<<_DOMCRF_nestedhvm) /* * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().