[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 11/22] xen/x86: allow disabling emulated devices for HVM guests
> -----Original Message----- > From: xen-devel-bounces@xxxxxxxxxxxxx [mailto:xen-devel- > bounces@xxxxxxxxxxxxx] On Behalf Of Roger Pau Monne > Sent: 01 July 2015 15:46 > To: xen-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Kevin Tian; Jan Beulich; Jun Nakajima; Andrew Cooper; Eddie Dong; > Aravind Gopalakrishnan; Suravee Suthikulpanit; Boris Ostrovsky; Roger Pau > Monne > Subject: [Xen-devel] [PATCH v2 11/22] xen/x86: allow disabling emulated > devices for HVM guests > > Introduce a new DOMCTL flag that can be used to disable device emulation > inside of Xen for HVM guests. The following emulated devices are disabled > when the XEN_DOMCTL_CDF_noemu is used: hpet, pmtimer, rtc, ioapic, > lapic, > pic and pmu. Also all the MMIO handlers are disabled. > > Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx> This is going to conflict badly with my recent emulation cleanup series. Paul > Cc: Jan Beulich <jbeulich@xxxxxxxx> > Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > Cc: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> > Cc: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> > Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@xxxxxxx> > Cc: Jun Nakajima <jun.nakajima@xxxxxxxxx> > Cc: Eddie Dong <eddie.dong@xxxxxxxxx> > Cc: Kevin Tian <kevin.tian@xxxxxxxxx> > --- > xen/arch/x86/domain.c | 2 +- > xen/arch/x86/hvm/hpet.c | 8 +++++++- > xen/arch/x86/hvm/hvm.c | 19 +++++++++++++------ > xen/arch/x86/hvm/intercept.c | 31 ++++++++++++++++++++++++--- > ---- > xen/arch/x86/hvm/pmtimer.c | 7 +++++++ > xen/arch/x86/hvm/rtc.c | 9 +++++++++ > xen/arch/x86/hvm/stdvga.c | 6 ++++++ > xen/arch/x86/hvm/svm/svm.c | 17 +++++++++-------- > xen/arch/x86/hvm/vioapic.c | 8 +++++++- > xen/arch/x86/hvm/vlapic.c | 15 ++++++++++++--- > xen/arch/x86/hvm/vmsi.c | 2 +- > xen/arch/x86/hvm/vmx/vmcs.c | 14 ++++++++++++++ > xen/arch/x86/hvm/vmx/vmx.c | 9 ++++++++- > xen/arch/x86/hvm/vpic.c | 3 +++ > xen/arch/x86/hvm/vpmu.c | 2 +- > xen/arch/x86/hvm/vpt.c | 3 +++ > xen/common/domctl.c | 5 ++++- > xen/drivers/passthrough/amd/iommu_guest.c | 2 +- > xen/include/asm-x86/hvm/domain.h | 4 ++++ > xen/include/asm-x86/hvm/hvm.h | 2 +- > xen/include/asm-x86/hvm/io.h | 12 +++++++----- > xen/include/public/domctl.h | 3 +++ > xen/include/xen/sched.h | 9 +++++++++ > 23 files changed, 154 insertions(+), 38 deletions(-) > > diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c > index a112953..0916c39 100644 > --- a/xen/arch/x86/domain.c > +++ b/xen/arch/x86/domain.c > @@ -626,7 +626,7 @@ int arch_domain_create(struct domain *d, unsigned > int domcr_flags, > > if ( has_hvm_container_domain(d) ) > { > - if ( (rc = hvm_domain_initialise(d)) != 0 ) > + if ( (rc = hvm_domain_initialise(d, domcr_flags)) != 0 ) > { > iommu_domain_destroy(d); > goto fail; > diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c > index 9585ca8..b4c121d 100644 > --- a/xen/arch/x86/hvm/hpet.c > +++ b/xen/arch/x86/hvm/hpet.c > @@ -504,7 +504,7 @@ static int hpet_range(struct vcpu *v, unsigned long > addr) > (addr < (HPET_BASE_ADDRESS + HPET_MMAP_SIZE)) ); > } > > -const struct hvm_mmio_ops hpet_mmio_ops = { > +struct hvm_mmio_ops hpet_mmio_ops = { > .check = hpet_range, > .read = hpet_read, > .write = hpet_write > @@ -634,6 +634,9 @@ void hpet_init(struct domain *d) > HPETState *h = domain_vhpet(d); > int i; > > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > memset(h, 0, sizeof(HPETState)); > > rwlock_init(&h->lock); > @@ -666,6 +669,9 @@ void hpet_deinit(struct domain *d) > int i; > HPETState *h = domain_vhpet(d); > > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > write_lock(&h->lock); > > if ( hpet_enabled(h) ) > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c > index 535d622..66f95b2 100644 > --- a/xen/arch/x86/hvm/hvm.c > +++ b/xen/arch/x86/hvm/hvm.c > @@ -1423,7 +1423,7 @@ static int hvm_set_dm_domain(struct domain *d, > domid_t domid) > return rc; > } > > -int hvm_domain_initialise(struct domain *d) > +int hvm_domain_initialise(struct domain *d, unsigned int domcr_flags) > { > int rc; > > @@ -1491,10 +1491,12 @@ int hvm_domain_initialise(struct domain *d) > return 0; > } > > - hvm_init_guest_time(d); > + if ( domcr_flags & DOMCRF_noemu ) > + d->arch.hvm_domain.no_emu = 1; > + > + setup_mmio_handlers(d); > > - d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1; > - d->arch.hvm_domain.params[HVM_PARAM_TRIPLE_FAULT_REASON] = > SHUTDOWN_reboot; > + hvm_init_guest_time(d); > > vpic_init(d); > > @@ -1506,8 +1508,13 @@ int hvm_domain_initialise(struct domain *d) > > rtc_init(d); > > - register_portio_handler(d, 0xe9, 1, hvm_print_line); > - register_portio_handler(d, 0xcf8, 4, hvm_access_cf8); > + if ( !d->arch.hvm_domain.no_emu ) > + { > + d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1; > + d->arch.hvm_domain.params[HVM_PARAM_TRIPLE_FAULT_REASON] > = SHUTDOWN_reboot; > + register_portio_handler(d, 0xe9, 1, hvm_print_line); > + register_portio_handler(d, 0xcf8, 4, hvm_access_cf8); > + } > > rc = hvm_funcs.domain_initialise(d); > if ( rc != 0 ) > diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c > index cc44733..714e29d 100644 > --- a/xen/arch/x86/hvm/intercept.c > +++ b/xen/arch/x86/hvm/intercept.c > @@ -32,7 +32,7 @@ > #include <xen/event.h> > #include <xen/iommu.h> > > -static const struct hvm_mmio_ops *const > +static struct hvm_mmio_ops *const > hvm_mmio_handlers[HVM_MMIO_HANDLER_NR] = > { > &hpet_mmio_ops, > @@ -166,10 +166,12 @@ static int hvm_mmio_access(struct vcpu *v, > bool_t hvm_mmio_internal(paddr_t gpa) > { > struct vcpu *curr = current; > + struct hvm_mmio_ops *const *mmio_handlers = > + curr->domain->arch.hvm_domain.mmio_handlers; > unsigned int i; > > - for ( i = 0; i < HVM_MMIO_HANDLER_NR; ++i ) > - if ( hvm_mmio_handlers[i]->check(curr, gpa) ) > + for ( i = 0; i < curr->domain->arch.hvm_domain.nr_mmio_handlers; ++i ) > + if ( mmio_handlers[i]->check(curr, gpa) ) > return 1; > > return 0; > @@ -178,11 +180,13 @@ bool_t hvm_mmio_internal(paddr_t gpa) > int hvm_mmio_intercept(ioreq_t *p) > { > struct vcpu *v = current; > + struct hvm_mmio_ops *const *mmio_handlers = > + v->domain->arch.hvm_domain.mmio_handlers; > int i; > > - for ( i = 0; i < HVM_MMIO_HANDLER_NR; i++ ) > + for ( i = 0; i < v->domain->arch.hvm_domain.nr_mmio_handlers; i++ ) > { > - hvm_mmio_check_t check = hvm_mmio_handlers[i]->check; > + hvm_mmio_check_t check = mmio_handlers[i]->check; > > if ( check(v, p->addr) ) > { > @@ -194,8 +198,8 @@ int hvm_mmio_intercept(ioreq_t *p) > > return hvm_mmio_access( > v, p, > - hvm_mmio_handlers[i]->read, > - hvm_mmio_handlers[i]->write); > + mmio_handlers[i]->read, > + mmio_handlers[i]->write); > } > } > > @@ -398,6 +402,19 @@ void relocate_io_handler( > handler->hdl_list[i].addr = new_addr; > } > > +void setup_mmio_handlers(struct domain *d) > +{ > + if ( d->arch.hvm_domain.no_emu ) > + { > + d->arch.hvm_domain.nr_mmio_handlers = 0; > + } > + else > + { > + d->arch.hvm_domain.mmio_handlers = hvm_mmio_handlers; > + d->arch.hvm_domain.nr_mmio_handlers = > HVM_MMIO_HANDLER_NR; > + } > +} > + > /* > * Local variables: > * mode: C > diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c > index 6ad2797..01ae274 100644 > --- a/xen/arch/x86/hvm/pmtimer.c > +++ b/xen/arch/x86/hvm/pmtimer.c > @@ -329,6 +329,9 @@ void pmtimer_init(struct vcpu *v) > { > PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt; > > + if ( v->domain->arch.hvm_domain.no_emu ) > + return; > + > spin_lock_init(&s->lock); > > s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / SYSTEM_TIME_HZ; > @@ -349,6 +352,10 @@ void pmtimer_init(struct vcpu *v) > void pmtimer_deinit(struct domain *d) > { > PMTState *s = &d->arch.hvm_domain.pl_time.vpmt; > + > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > kill_timer(&s->timer); > } > > diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c > index 3448971..b5dfb2c 100644 > --- a/xen/arch/x86/hvm/rtc.c > +++ b/xen/arch/x86/hvm/rtc.c > @@ -726,6 +726,9 @@ void rtc_migrate_timers(struct vcpu *v) > { > RTCState *s = vcpu_vrtc(v); > > + if ( v->domain->arch.hvm_domain.no_emu ) > + return; > + > if ( v->vcpu_id == 0 ) > { > migrate_timer(&s->update_timer, v->processor);; > @@ -790,6 +793,9 @@ void rtc_init(struct domain *d) > { > RTCState *s = domain_vrtc(d); > > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > spin_lock_init(&s->lock); > > init_timer(&s->update_timer, rtc_update_timer, s, smp_processor_id()); > @@ -820,6 +826,9 @@ void rtc_deinit(struct domain *d) > { > RTCState *s = domain_vrtc(d); > > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > spin_barrier(&s->lock); > > TRACE_0D(TRC_HVM_EMUL_RTC_STOP_TIMER); > diff --git a/xen/arch/x86/hvm/stdvga.c b/xen/arch/x86/hvm/stdvga.c > index 13d1029..61718c7 100644 > --- a/xen/arch/x86/hvm/stdvga.c > +++ b/xen/arch/x86/hvm/stdvga.c > @@ -599,6 +599,9 @@ void stdvga_init(struct domain *d) > void *p; > int i; > > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > memset(s, 0, sizeof(*s)); > spin_lock_init(&s->lock); > > @@ -630,6 +633,9 @@ void stdvga_deinit(struct domain *d) > struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga; > int i; > > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > for ( i = 0; i != ARRAY_SIZE(s->vram_page); i++ ) > { > if ( s->vram_page[i] == NULL ) > diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c > index a02f983..0b1175d 100644 > --- a/xen/arch/x86/hvm/svm/svm.c > +++ b/xen/arch/x86/hvm/svm/svm.c > @@ -1035,6 +1035,7 @@ static void noreturn svm_do_resume(struct vcpu > *v) > { > struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; > bool_t debug_state = v->domain->debugger_attached; > + struct vlapic *vlapic = vcpu_vlapic(v); > bool_t vcpu_guestmode = 0; > > if ( nestedhvm_enabled(v->domain) && > nestedhvm_vcpu_in_guestmode(v) ) > @@ -1059,14 +1060,13 @@ static void noreturn svm_do_resume(struct vcpu > *v) > hvm_asid_flush_vcpu(v); > } > > - if ( !vcpu_guestmode ) > + if ( !vcpu_guestmode && !vlapic_hw_disabled(vlapic)) > { > vintr_t intr; > > /* Reflect the vlapic's TPR in the hardware vtpr */ > intr = vmcb_get_vintr(vmcb); > - intr.fields.tpr = > - (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4; > + intr.fields.tpr = (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xFF) >> 4; > vmcb_set_vintr(vmcb, intr); > } > > @@ -2295,6 +2295,7 @@ void svm_vmexit_handler(struct cpu_user_regs > *regs) > int inst_len, rc; > vintr_t intr; > bool_t vcpu_guestmode = 0; > + struct vlapic *vlapic = vcpu_vlapic(v); > > hvm_invalidate_regs_fields(regs); > > @@ -2312,11 +2313,11 @@ void svm_vmexit_handler(struct cpu_user_regs > *regs) > * NB. We need to preserve the low bits of the TPR to make checked builds > * of Windows work, even though they don't actually do anything. > */ > - if ( !vcpu_guestmode ) { > + if ( !vcpu_guestmode && !vlapic_hw_disabled(vlapic) ) { > intr = vmcb_get_vintr(vmcb); > - vlapic_set_reg(vcpu_vlapic(v), APIC_TASKPRI, > + vlapic_set_reg(vlapic, APIC_TASKPRI, > ((intr.fields.tpr & 0x0F) << 4) | > - (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0x0F)); > + (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0x0F)); > } > > exit_reason = vmcb->exitcode; > @@ -2698,14 +2699,14 @@ void svm_vmexit_handler(struct cpu_user_regs > *regs) > } > > out: > - if ( vcpu_guestmode ) > + if ( vcpu_guestmode || vlapic_hw_disabled(vlapic) ) > /* Don't clobber TPR of the nested guest. */ > return; > > /* The exit may have updated the TPR: reflect this in the hardware vtpr > */ > intr = vmcb_get_vintr(vmcb); > intr.fields.tpr = > - (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4; > + (vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xFF) >> 4; > vmcb_set_vintr(vmcb, intr); > } > > diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c > index cbbef9f..efa1930 100644 > --- a/xen/arch/x86/hvm/vioapic.c > +++ b/xen/arch/x86/hvm/vioapic.c > @@ -250,7 +250,7 @@ static int vioapic_range(struct vcpu *v, unsigned long > addr) > (addr < vioapic->base_address + VIOAPIC_MEM_LENGTH))); > } > > -const struct hvm_mmio_ops vioapic_mmio_ops = { > +struct hvm_mmio_ops vioapic_mmio_ops = { > .check = vioapic_range, > .read = vioapic_read, > .write = vioapic_write > @@ -449,6 +449,9 @@ void vioapic_reset(struct domain *d) > > int vioapic_init(struct domain *d) > { > + if ( d->arch.hvm_domain.no_emu ) > + return 0; > + > if ( (d->arch.hvm_domain.vioapic == NULL) && > ((d->arch.hvm_domain.vioapic = xmalloc(struct hvm_vioapic)) == NULL) > ) > return -ENOMEM; > @@ -461,6 +464,9 @@ int vioapic_init(struct domain *d) > > void vioapic_deinit(struct domain *d) > { > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > xfree(d->arch.hvm_domain.vioapic); > d->arch.hvm_domain.vioapic = NULL; > } > diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c > index 32e649e..606cafe 100644 > --- a/xen/arch/x86/hvm/vlapic.c > +++ b/xen/arch/x86/hvm/vlapic.c > @@ -977,7 +977,7 @@ static int vlapic_range(struct vcpu *v, unsigned long > addr) > (offset < PAGE_SIZE); > } > > -const struct hvm_mmio_ops vlapic_mmio_ops = { > +struct hvm_mmio_ops vlapic_mmio_ops = { > .check = vlapic_range, > .read = vlapic_read, > .write = vlapic_write > @@ -994,6 +994,9 @@ static void set_x2apic_id(struct vlapic *vlapic) > > bool_t vlapic_msr_set(struct vlapic *vlapic, uint64_t value) > { > + if ( vlapic_domain(vlapic)->arch.hvm_domain.no_emu ) > + return 0; > + > if ( (vlapic->hw.apic_base_msr ^ value) & MSR_IA32_APICBASE_ENABLE ) > { > if ( unlikely(value & MSR_IA32_APICBASE_EXTD) ) > @@ -1044,7 +1047,7 @@ void vlapic_tdt_msr_set(struct vlapic *vlapic, > uint64_t value) > struct vcpu *v = vlapic_vcpu(vlapic); > > /* may need to exclude some other conditions like vlapic->hw.disabled */ > - if ( !vlapic_lvtt_tdt(vlapic) ) > + if ( !vlapic_lvtt_tdt(vlapic) || vlapic_hw_disabled(vlapic) ) > { > HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "ignore tsc deadline msr > write"); > return; > @@ -1119,6 +1122,9 @@ static int __vlapic_accept_pic_intr(struct vcpu *v) > > int vlapic_accept_pic_intr(struct vcpu *v) > { > + if ( v->domain->arch.hvm_domain.no_emu ) > + return 0; > + > TRACE_2D(TRC_HVM_EMUL_LAPIC_PIC_INTR, > (v == v->domain->arch.hvm_domain.i8259_target), > v ? __vlapic_accept_pic_intr(v) : -1); > @@ -1400,7 +1406,7 @@ int vlapic_init(struct vcpu *v) > > HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id); > > - if ( is_pvh_vcpu(v) ) > + if ( is_pvh_vcpu(v) || v->domain->arch.hvm_domain.no_emu ) > { > vlapic->hw.disabled = VLAPIC_HW_DISABLED; > return 0; > @@ -1450,6 +1456,9 @@ void vlapic_destroy(struct vcpu *v) > { > struct vlapic *vlapic = vcpu_vlapic(v); > > + if ( v->domain->arch.hvm_domain.no_emu ) > + return; > + > tasklet_kill(&vlapic->init_sipi.tasklet); > TRACE_0D(TRC_HVM_EMUL_LAPIC_STOP_TIMER); > destroy_periodic_time(&vlapic->pt); > diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c > index f89233d..2962042 100644 > --- a/xen/arch/x86/hvm/vmsi.c > +++ b/xen/arch/x86/hvm/vmsi.c > @@ -344,7 +344,7 @@ static int msixtbl_range(struct vcpu *v, unsigned long > addr) > return !!desc; > } > > -const struct hvm_mmio_ops msixtbl_mmio_ops = { > +struct hvm_mmio_ops msixtbl_mmio_ops = { > .check = msixtbl_range, > .read = msixtbl_read, > .write = msixtbl_write > diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c > index 4c5ceb5..a27f117 100644 > --- a/xen/arch/x86/hvm/vmx/vmcs.c > +++ b/xen/arch/x86/hvm/vmx/vmcs.c > @@ -992,6 +992,20 @@ static int construct_vmcs(struct vcpu *v) > ASSERT(!(v->arch.hvm_vmx.exec_control & > CPU_BASED_RDTSC_EXITING)); > } > > + if ( d->arch.hvm_domain.no_emu ) > + { > + /* Disable virtual apics, TPR */ > + v->arch.hvm_vmx.secondary_exec_control &= > + ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES > + | SECONDARY_EXEC_APIC_REGISTER_VIRT > + | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY); > + v->arch.hvm_vmx.exec_control &= ~CPU_BASED_TPR_SHADOW; > + > + /* In turn, disable posted interrupts. */ > + __vmwrite(PIN_BASED_VM_EXEC_CONTROL, > + vmx_pin_based_exec_control & > ~PIN_BASED_POSTED_INTERRUPT); > + } > + > vmx_update_cpu_exec_control(v); > > __vmwrite(VM_EXIT_CONTROLS, vmexit_ctl); > diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c > index fc29b89..0d04623 100644 > --- a/xen/arch/x86/hvm/vmx/vmx.c > +++ b/xen/arch/x86/hvm/vmx/vmx.c > @@ -88,6 +88,9 @@ static int vmx_domain_initialise(struct domain *d) > { > int rc; > > + if ( d->arch.hvm_domain.no_emu ) > + return 0; > + > if ( (rc = vmx_alloc_vlapic_mapping(d)) != 0 ) > return rc; > > @@ -96,6 +99,9 @@ static int vmx_domain_initialise(struct domain *d) > > static void vmx_domain_destroy(struct domain *d) > { > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > vmx_free_vlapic_mapping(d); > } > > @@ -2240,7 +2246,8 @@ static void vmx_install_vlapic_mapping(struct vcpu > *v) > { > paddr_t virt_page_ma, apic_page_ma; > > - if ( !cpu_has_vmx_virtualize_apic_accesses ) > + if ( !cpu_has_vmx_virtualize_apic_accesses || > + v->domain->arch.hvm_domain.vmx.apic_access_mfn == 0 ) > return; > > virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page); > diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c > index 8eea061..169e870 100644 > --- a/xen/arch/x86/hvm/vpic.c > +++ b/xen/arch/x86/hvm/vpic.c > @@ -425,6 +425,9 @@ void vpic_reset(struct domain *d) > > void vpic_init(struct domain *d) > { > + if ( d->arch.hvm_domain.no_emu ) > + return; > + > vpic_reset(d); > > register_portio_handler(d, 0x20, 2, vpic_intercept_pic_io); > diff --git a/xen/arch/x86/hvm/vpmu.c b/xen/arch/x86/hvm/vpmu.c > index c3273ee..d625365 100644 > --- a/xen/arch/x86/hvm/vpmu.c > +++ b/xen/arch/x86/hvm/vpmu.c > @@ -233,7 +233,7 @@ void vpmu_initialise(struct vcpu *v) > uint8_t vendor = current_cpu_data.x86_vendor; > int ret; > > - if ( is_pvh_vcpu(v) ) > + if ( is_pvh_vcpu(v) || v->domain->arch.hvm_domain.no_emu ) > return; > > ASSERT(!vpmu->flags && !vpmu->context); > diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c > index 7c6549c..c3a8534 100644 > --- a/xen/arch/x86/hvm/vpt.c > +++ b/xen/arch/x86/hvm/vpt.c > @@ -375,6 +375,9 @@ void pt_migrate(struct vcpu *v) > struct list_head *head = &v->arch.hvm_vcpu.tm_list; > struct periodic_time *pt; > > + if ( v->domain->arch.hvm_domain.no_emu ) > + return; > + > spin_lock(&v->arch.hvm_vcpu.tm_lock); > > list_for_each_entry ( pt, head, list ) > diff --git a/xen/common/domctl.c b/xen/common/domctl.c > index 2a2d203..b327596 100644 > --- a/xen/common/domctl.c > +++ b/xen/common/domctl.c > @@ -551,7 +551,8 @@ long > do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) > | XEN_DOMCTL_CDF_pvh_guest > | XEN_DOMCTL_CDF_hap > | XEN_DOMCTL_CDF_s3_integrity > - | XEN_DOMCTL_CDF_oos_off)) ) > + | XEN_DOMCTL_CDF_oos_off > + | XEN_DOMCTL_CDF_noemu)) ) > break; > > dom = op->domain; > @@ -593,6 +594,8 @@ long > do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) > 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_noemu ) > + domcr_flags |= DOMCRF_noemu; > > d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref, > &op->u.createdomain.config); > diff --git a/xen/drivers/passthrough/amd/iommu_guest.c > b/xen/drivers/passthrough/amd/iommu_guest.c > index 7b0c102..7266b6c 100644 > --- a/xen/drivers/passthrough/amd/iommu_guest.c > +++ b/xen/drivers/passthrough/amd/iommu_guest.c > @@ -919,7 +919,7 @@ static int guest_iommu_mmio_range(struct vcpu *v, > unsigned long addr) > addr < iommu->mmio_base + IOMMU_MMIO_SIZE; > } > > -const struct hvm_mmio_ops iommu_mmio_ops = { > +struct hvm_mmio_ops iommu_mmio_ops = { > .check = guest_iommu_mmio_range, > .read = guest_iommu_mmio_read, > .write = guest_iommu_mmio_write > diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm- > x86/hvm/domain.h > index ad68fcf..03d223d 100644 > --- a/xen/include/asm-x86/hvm/domain.h > +++ b/xen/include/asm-x86/hvm/domain.h > @@ -135,6 +135,7 @@ struct hvm_domain { > bool_t mem_sharing_enabled; > bool_t qemu_mapcache_invalidate; > bool_t is_s3_suspended; > + bool_t no_emu; > > /* > * TSC value that VCPUs use to calculate their tsc_offset value. > @@ -144,6 +145,9 @@ struct hvm_domain { > > unsigned long *io_bitmap; > > + struct hvm_mmio_ops *const *mmio_handlers; > + int nr_mmio_handlers; > + > union { > struct vmx_domain vmx; > struct svm_domain svm; > diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm- > x86/hvm/hvm.h > index 57f9605..d62c2b8 100644 > --- a/xen/include/asm-x86/hvm/hvm.h > +++ b/xen/include/asm-x86/hvm/hvm.h > @@ -217,7 +217,7 @@ extern s8 hvm_port80_allowed; > extern const struct hvm_function_table *start_svm(void); > extern const struct hvm_function_table *start_vmx(void); > > -int hvm_domain_initialise(struct domain *d); > +int hvm_domain_initialise(struct domain *d, unsigned int domcr_flags); > void hvm_domain_relinquish_resources(struct domain *d); > void hvm_domain_destroy(struct domain *d); > > diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h > index f2aaec5..bd948e7 100644 > --- a/xen/include/asm-x86/hvm/io.h > +++ b/xen/include/asm-x86/hvm/io.h > @@ -65,11 +65,11 @@ struct hvm_mmio_ops { > hvm_mmio_write_t write; > }; > > -extern const struct hvm_mmio_ops hpet_mmio_ops; > -extern const struct hvm_mmio_ops vlapic_mmio_ops; > -extern const struct hvm_mmio_ops vioapic_mmio_ops; > -extern const struct hvm_mmio_ops msixtbl_mmio_ops; > -extern const struct hvm_mmio_ops iommu_mmio_ops; > +extern struct hvm_mmio_ops hpet_mmio_ops; > +extern struct hvm_mmio_ops vlapic_mmio_ops; > +extern struct hvm_mmio_ops vioapic_mmio_ops; > +extern struct hvm_mmio_ops msixtbl_mmio_ops; > +extern struct hvm_mmio_ops iommu_mmio_ops; > > #define HVM_MMIO_HANDLER_NR 5 > > @@ -81,6 +81,8 @@ void relocate_io_handler( > struct domain *d, unsigned long old_addr, unsigned long new_addr, > unsigned long size, int type); > > +void setup_mmio_handlers(struct domain *d); > + > static inline int hvm_portio_intercept(ioreq_t *p) > { > return hvm_io_intercept(p, HVM_PORTIO); > diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h > index bc45ea5..4e9d7e7 100644 > --- a/xen/include/public/domctl.h > +++ b/xen/include/public/domctl.h > @@ -63,6 +63,9 @@ struct xen_domctl_createdomain { > /* Is this a PVH guest (as opposed to an HVM or PV guest)? */ > #define _XEN_DOMCTL_CDF_pvh_guest 4 > #define XEN_DOMCTL_CDF_pvh_guest > (1U<<_XEN_DOMCTL_CDF_pvh_guest) > + /* Disable emulated devices */ > +#define _XEN_DOMCTL_CDF_noemu 5 > +#define XEN_DOMCTL_CDF_noemu > (1U<<_XEN_DOMCTL_CDF_noemu) > uint32_t flags; > struct xen_arch_domainconfig config; > }; > diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h > index b29d9e7..d88c6aa 100644 > --- a/xen/include/xen/sched.h > +++ b/xen/include/xen/sched.h > @@ -557,6 +557,15 @@ struct domain *domain_create(domid_t domid, > unsigned int domcr_flags, > /* DOMCRF_pvh: Create PV domain in HVM container. */ > #define _DOMCRF_pvh 5 > #define DOMCRF_pvh (1U<<_DOMCRF_pvh) > +/* > + * DOMCRF_noemu: Create a HVM domain without emulated devices. > + * > + * This currently disables the following emulated devices inside of Xen: > + * hpet, pmtimer, rtc, ioapic, lapic, pic and pmu. > + * It also disables all the MMIO handlers. > + */ > +#define _DOMCRF_noemu 6 > +#define DOMCRF_noemu (1U<<_DOMCRF_noemu) > > /* > * rcu_lock_domain_by_id() is more efficient than get_domain_by_id(). > -- > 1.9.5 (Apple Git-50.3) > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |