# HG changeset patch # User cegger # Date 1281004722 -7200 Implement generic piece to finally enable nested virtualization diff -r 092d43f1ba2a -r cffdbc93e781 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -828,10 +828,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; @@ -845,7 +851,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, @@ -870,6 +876,8 @@ int hvm_vcpu_initialise(struct vcpu *v) return 0; + fail4: + nestedhvm_vcpu_destroy(v); fail3: hvm_funcs.vcpu_destroy(v); fail2: @@ -880,6 +888,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); @@ -3021,6 +3035,16 @@ long do_hvm_op(unsigned long op, XEN_GUE rc = -EINVAL; break; + case HVM_PARAM_NESTEDHVM: + if ( a.value > 1 ) + rc = -EINVAL; + if ( !is_hvm_domain(d) ) + rc = -EINVAL; + /* Remove the check below once we have + * shadow-on-shadow. + */ + if ( !paging_mode_hap(d) && a.value ) + rc = -EINVAL; } if ( rc == 0 )