[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User Isaku Yamahata <yamahata@xxxxxxxxxxxxx> # Date 1228356113 -32400 # Node ID f4c5befcba8d78d4f93f58602e9ea942e7372496 # Parent 54e5d15af567012bb7e88b0ccb3bad9a7f0168a5 # Parent 7338f6301067c7298eb4b3ff44992c53488b0df7 merge with xen-unstable.hg --- stubdom/grub/mini-os.c | 2 tools/python/xen/xend/XendDomainInfo.py | 12 +++- tools/python/xen/xm/addlabel.py | 5 + tools/xcutils/xc_save.c | 38 +++++++++---- tools/xenpmd/xenpmd.c | 2 tools/xenstat/libxenstat/src/xenstat_linux.c | 27 ++------- xen/arch/ia64/xen/domain.c | 3 - xen/arch/x86/boot/wakeup.S | 3 - xen/arch/x86/domain.c | 10 ++- xen/arch/x86/domctl.c | 16 +---- xen/arch/x86/hpet.c | 3 + xen/arch/x86/irq.c | 70 +++++++++++++++++++++--- xen/arch/x86/mm/shadow/multi.c | 22 ++++--- xen/arch/x86/physdev.c | 43 +++++++++++++++ xen/arch/x86/x86_64/physdev.c | 3 + xen/arch/x86/x86_emulate/x86_emulate.c | 73 ++++++++------------------ xen/common/domain.c | 3 + xen/common/event_channel.c | 5 - xen/common/timer.c | 10 ++- xen/drivers/char/console.c | 2 xen/drivers/passthrough/amd/iommu_init.c | 71 +++++++++++++++++-------- xen/drivers/passthrough/amd/iommu_map.c | 44 +++++++++++++++ xen/drivers/passthrough/amd/pci_amd_iommu.c | 1 xen/drivers/passthrough/vtd/dmar.c | 26 +++++++-- xen/drivers/passthrough/vtd/dmar.h | 1 xen/drivers/passthrough/vtd/iommu.c | 39 +++++++------ xen/drivers/passthrough/vtd/iommu.h | 4 + xen/drivers/passthrough/vtd/qinval.c | 23 ++++---- xen/include/asm-x86/domain.h | 4 + xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 1 xen/include/asm-x86/page.h | 2 xen/include/public/physdev.h | 15 +++++ xen/include/xen/event.h | 3 + xen/include/xen/irq.h | 1 xen/tools/symbols.c | 3 - 35 files changed, 400 insertions(+), 190 deletions(-) diff -r 54e5d15af567 -r f4c5befcba8d stubdom/grub/mini-os.c --- a/stubdom/grub/mini-os.c Wed Dec 03 11:43:54 2008 +0900 +++ b/stubdom/grub/mini-os.c Thu Dec 04 11:01:53 2008 +0900 @@ -649,7 +649,7 @@ int getrtsecs (void) { struct timeval tv; gettimeofday(&tv, NULL); - return tv.tv_sec; + return tv.tv_sec % 10 + ((tv.tv_sec / 10) % 6) * 0x10; } int currticks (void) diff -r 54e5d15af567 -r f4c5befcba8d tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Dec 03 11:43:54 2008 +0900 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Dec 04 11:01:53 2008 +0900 @@ -1990,13 +1990,21 @@ class XendDomainInfo: for devclass in XendDevices.valid_devices(): for dev in t.list(devclass): try: + true_devclass = devclass + if devclass == 'vbd': + # In the case of "vbd", the true device class + # may possibly be "tap". Just in case, verify + # device class. + devid = dev.split('/')[-1] + true_devclass = self.getBlockDeviceClass(devid) log.debug("Removing %s", dev); - self.destroyDevice(devclass, dev, False); + self.destroyDevice(true_devclass, dev, False); except: # Log and swallow any exceptions in removal -- # there's nothing more we can do. log.exception("Device release failed: %s; %s; %s", - self.info['name_label'], devclass, dev) + self.info['name_label'], + true_devclass, dev) finally: t.abort() diff -r 54e5d15af567 -r f4c5befcba8d tools/python/xen/xm/addlabel.py --- a/tools/python/xen/xm/addlabel.py Wed Dec 03 11:43:54 2008 +0900 +++ b/tools/python/xen/xm/addlabel.py Thu Dec 04 11:01:53 2008 +0900 @@ -64,12 +64,13 @@ def validate_config_file(configfile): return 0 # sanity check on the data from the file + # requiring 'memory,' 'name,' and ether 'kernel' or 'bootloader' count = 0 - required = ['kernel', 'memory', 'name'] + required = ['kernel', 'bootloader', 'memory', 'name'] for (k, v) in locs.items(): if k in required: count += 1 - if count != 3: + if count < len(required) - 1: print "Invalid configuration file." return 0 else: diff -r 54e5d15af567 -r f4c5befcba8d tools/xcutils/xc_save.c --- a/tools/xcutils/xc_save.c Wed Dec 03 11:43:54 2008 +0900 +++ b/tools/xcutils/xc_save.c Thu Dec 04 11:01:53 2008 +0900 @@ -24,8 +24,11 @@ #include <xenguest.h> static struct suspendinfo { + int xc_fd; /* libxc handle */ int xce; /* event channel handle */ int suspend_evtchn; + int domid; + unsigned int flags; } si; /** @@ -161,6 +164,19 @@ static int evtchn_suspend(void) static int suspend(void) { + unsigned long sx_state = 0; + + /* Nothing to do if the guest is in an ACPI sleep state. */ + if (si.flags & XCFLAGS_HVM) + xc_get_hvm_param(si.xc_fd, si.domid, + HVM_PARAM_ACPI_S_STATE, &sx_state); + if (sx_state != 0) { + /* notify xend that it can do device migration */ + printf("suspended\n"); + fflush(stdout); + return 1; + } + if (si.suspend_evtchn >= 0) return evtchn_suspend(); @@ -297,32 +313,32 @@ int int main(int argc, char **argv) { - unsigned int domid, maxit, max_f, flags; - int xc_fd, io_fd, ret; + unsigned int maxit, max_f; + int io_fd, ret; if (argc != 6) errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]); - xc_fd = xc_interface_open(); - if (xc_fd < 0) + si.xc_fd = xc_interface_open(); + if (si.xc_fd < 0) errx(1, "failed to open control interface"); io_fd = atoi(argv[1]); - domid = atoi(argv[2]); + si.domid = atoi(argv[2]); maxit = atoi(argv[3]); max_f = atoi(argv[4]); - flags = atoi(argv[5]); - - if (suspend_evtchn_init(xc_fd, domid) < 0) + si.flags = atoi(argv[5]); + + if (suspend_evtchn_init(si.xc_fd, si.domid) < 0) warnx("suspend event channel initialization failed, using slow path"); - ret = xc_domain_save(xc_fd, io_fd, domid, maxit, max_f, flags, - &suspend, !!(flags & XCFLAGS_HVM), + ret = xc_domain_save(si.xc_fd, io_fd, si.domid, maxit, max_f, si.flags, + &suspend, !!(si.flags & XCFLAGS_HVM), &init_qemu_maps, &qemu_flip_buffer); suspend_evtchn_release(); - xc_interface_close(xc_fd); + xc_interface_close(si.xc_fd); return ret; } diff -r 54e5d15af567 -r f4c5befcba8d tools/xenpmd/xenpmd.c --- a/tools/xenpmd/xenpmd.c Wed Dec 03 11:43:54 2008 +0900 +++ b/tools/xenpmd/xenpmd.c Thu Dec 04 11:01:53 2008 +0900 @@ -373,7 +373,7 @@ void write_battery_info_to_xenstore(stru (unsigned int)strlen(info->serial_number), info->serial_number, (unsigned int)strlen(info->battery_type), info->battery_type, (unsigned int)strlen(info->oem_info), info->oem_info); - strncat(val+73, string_info, 1024); + strncat(val+73, string_info, 1024-73-1); xs_write(xs, XBT_NULL, "/pm/bif", val, 73+8+strlen(info->model_number)+strlen(info->serial_number)+ strlen(info->battery_type)+strlen(info->oem_info)+1); diff -r 54e5d15af567 -r f4c5befcba8d tools/xenstat/libxenstat/src/xenstat_linux.c --- a/tools/xenstat/libxenstat/src/xenstat_linux.c Wed Dec 03 11:43:54 2008 +0900 +++ b/tools/xenstat/libxenstat/src/xenstat_linux.c Thu Dec 04 11:01:53 2008 +0900 @@ -182,12 +182,6 @@ int xenstat_collect_vbds(xenstat_node * struct dirent *dp; struct priv_data *priv = get_priv_data(node->handle); - char *sys_prefix = "statistics/"; - - /* 23 = "statistics/" + "xxxx_xx_req" */ - char ooreq[23], rdreq[23], wrreq[23]; - char *stat_prefix = NULL; - if (priv == NULL) { perror("Allocation error"); return 0; @@ -215,16 +209,12 @@ int xenstat_collect_vbds(xenstat_node * if (ret != 3) continue; - - if (strcmp(buf,"vbd") == 0){ - stat_prefix = ""; + if (strcmp(buf,"vbd") == 0) vbd.back_type = 1; - } else if (strcmp(buf,"tap") == 0){ - stat_prefix = "tap_"; + else if (strcmp(buf,"tap") == 0) vbd.back_type = 2; - } else { - continue; - } + else + continue; domain = xenstat_node_domain(node, domid); if (domain == NULL) { @@ -235,22 +225,19 @@ int xenstat_collect_vbds(xenstat_node * continue; } - snprintf(ooreq, sizeof(ooreq), "%s%soo_req", sys_prefix, stat_prefix); - if((read_attributes_vbd(dp->d_name, ooreq, buf, 256)<=0) + if((read_attributes_vbd(dp->d_name, "statistics/oo_req", buf, 256)<=0) || ((ret = sscanf(buf, "%llu", &vbd.oo_reqs)) != 1)) { continue; } - snprintf(rdreq, sizeof(rdreq),"%s%srd_req", sys_prefix, stat_prefix); - if((read_attributes_vbd(dp->d_name, rdreq, buf, 256)<=0) + if((read_attributes_vbd(dp->d_name, "statistics/rd_req", buf, 256)<=0) || ((ret = sscanf(buf, "%llu", &vbd.rd_reqs)) != 1)) { continue; } - snprintf(wrreq, sizeof(wrreq),"%s%swr_req", sys_prefix, stat_prefix); - if((read_attributes_vbd(dp->d_name, wrreq, buf, 256)<=0) + if((read_attributes_vbd(dp->d_name, "statistics/wr_req", buf, 256)<=0) || ((ret = sscanf(buf, "%llu", &vbd.wr_reqs)) != 1)) { continue; diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/ia64/xen/domain.c Thu Dec 04 11:01:53 2008 +0900 @@ -1686,9 +1686,6 @@ int domain_relinquish_resources(struct d if (is_hvm_domain(d) && d->arch.sal_data) xfree(d->arch.sal_data); - /* Free page used by xen oprofile buffer */ - free_xenoprof_pages(d); - return 0; } diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/boot/wakeup.S --- a/xen/arch/x86/boot/wakeup.S Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/boot/wakeup.S Thu Dec 04 11:01:53 2008 +0900 @@ -50,8 +50,7 @@ 1: # Show some progress if VGA is r movw $1, %ax lmsw %ax # Turn on CR0.PE - jmp 1f -1: ljmpl $BOOT_CS32, $bootsym_phys(wakeup_32) + ljmpl $BOOT_CS32, $bootsym_phys(wakeup_32) /* This code uses an extended set of video mode numbers. These include: * Aliases for standard modes diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/domain.c Thu Dec 04 11:01:53 2008 +0900 @@ -1814,6 +1814,13 @@ int domain_relinquish_resources(struct d unmap_vcpu_info(v); } + if ( d->arch.pirq_eoi_map != NULL ) + { + unmap_domain_page_global(d->arch.pirq_eoi_map); + put_page_and_type(mfn_to_page(d->arch.pirq_eoi_map_mfn)); + d->arch.pirq_eoi_map = NULL; + } + d->arch.relmem = RELMEM_xen; /* fallthrough */ @@ -1856,9 +1863,6 @@ int domain_relinquish_resources(struct d default: BUG(); } - - /* Free page used by xen oprofile buffer. */ - free_xenoprof_pages(d); if ( is_hvm_domain(d) ) hvm_domain_relinquish_resources(d); diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/domctl.c Thu Dec 04 11:01:53 2008 +0900 @@ -326,13 +326,9 @@ long arch_do_domctl( case XEN_DOMCTL_sethvmcontext: { - struct hvm_domain_context c; - struct domain *d; - - c.cur = 0; - c.size = domctl->u.hvmcontext.size; - c.data = NULL; - + struct hvm_domain_context c = { .size = domctl->u.hvmcontext.size }; + struct domain *d; + ret = -ESRCH; if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) break; @@ -367,8 +363,8 @@ long arch_do_domctl( case XEN_DOMCTL_gethvmcontext: { - struct hvm_domain_context c; - struct domain *d; + struct hvm_domain_context c = { 0 }; + struct domain *d; ret = -ESRCH; if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) @@ -382,9 +378,7 @@ long arch_do_domctl( if ( !is_hvm_domain(d) ) goto gethvmcontext_out; - c.cur = 0; c.size = hvm_save_size(d); - c.data = NULL; if ( guest_handle_is_null(domctl->u.hvmcontext.buffer) ) { diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/hpet.c --- a/xen/arch/x86/hpet.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/hpet.c Thu Dec 04 11:01:53 2008 +0900 @@ -273,6 +273,9 @@ u64 hpet_setup(void) return hpet_rate; system_reset_latch = system_reset_counter; + if ( hpet_address == 0 ) + return 0; + set_fixmap_nocache(FIX_HPET_BASE, hpet_address); hpet_id = hpet_read32(HPET_ID); diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/irq.c Thu Dec 04 11:01:53 2008 +0900 @@ -18,6 +18,7 @@ #include <xen/iommu.h> #include <asm/msi.h> #include <asm/current.h> +#include <asm/flushtlb.h> #include <public/physdev.h> /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */ @@ -206,16 +207,42 @@ static DEFINE_PER_CPU(struct pending_eoi static DEFINE_PER_CPU(struct pending_eoi, pending_eoi[NR_VECTORS]); #define pending_eoi_sp(p) ((p)[NR_VECTORS-1].vector) +static inline void set_pirq_eoi(struct domain *d, unsigned int irq) +{ + if ( d->arch.pirq_eoi_map ) + set_bit(irq, d->arch.pirq_eoi_map); +} + +static inline void clear_pirq_eoi(struct domain *d, unsigned int irq) +{ + if ( d->arch.pirq_eoi_map ) + clear_bit(irq, d->arch.pirq_eoi_map); +} + +static void _irq_guest_eoi(irq_desc_t *desc) +{ + irq_guest_action_t *action = (irq_guest_action_t *)desc->action; + unsigned int i, vector = desc - irq_desc; + + if ( !(desc->status & IRQ_GUEST_EOI_PENDING) ) + return; + + for ( i = 0; i < action->nr_guests; ++i ) + clear_pirq_eoi(action->guest[i], + domain_vector_to_irq(action->guest[i], vector)); + + desc->status &= ~(IRQ_INPROGRESS|IRQ_GUEST_EOI_PENDING); + desc->handler->enable(vector); +} + static struct timer irq_guest_eoi_timer[NR_VECTORS]; static void irq_guest_eoi_timer_fn(void *data) { irq_desc_t *desc = data; - unsigned vector = desc - irq_desc; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); - desc->status &= ~IRQ_INPROGRESS; - desc->handler->enable(vector); + _irq_guest_eoi(desc); spin_unlock_irqrestore(&desc->lock, flags); } @@ -272,8 +299,22 @@ static void __do_IRQ_guest(int vector) if ( already_pending == action->nr_guests ) { + stop_timer(&irq_guest_eoi_timer[vector]); desc->handler->disable(vector); - stop_timer(&irq_guest_eoi_timer[vector]); + desc->status |= IRQ_GUEST_EOI_PENDING; + for ( i = 0; i < already_pending; ++i ) + { + d = action->guest[i]; + set_pirq_eoi(d, domain_vector_to_irq(d, vector)); + /* + * Could check here whether the guest unmasked the event by now + * (or perhaps just re-issue the send_guest_pirq()), and if it + * can now accept the event, + * - clear all the pirq_eoi bits we already set, + * - re-enable the vector, and + * - skip the timer setup below. + */ + } init_timer(&irq_guest_eoi_timer[vector], irq_guest_eoi_timer_fn, desc, smp_processor_id()); set_timer(&irq_guest_eoi_timer[vector], NOW() + MILLISECS(1)); @@ -310,7 +351,7 @@ irq_desc_t *domain_spin_lock_irq_desc( } /* Flush all ready EOIs from the top of this CPU's pending-EOI stack. */ -static void flush_ready_eoi(void *unused) +static void flush_ready_eoi(void) { struct pending_eoi *peoi = this_cpu(pending_eoi); irq_desc_t *desc; @@ -364,7 +405,7 @@ static void set_eoi_ready(void *data) __set_eoi_ready(desc); spin_unlock(&desc->lock); - flush_ready_eoi(NULL); + flush_ready_eoi(); } static void __pirq_guest_eoi(struct domain *d, int irq) @@ -382,8 +423,12 @@ static void __pirq_guest_eoi(struct doma action = (irq_guest_action_t *)desc->action; vector = desc - irq_desc; - ASSERT(!test_bit(irq, d->pirq_mask) || - (action->ack_type != ACKTYPE_NONE)); + if ( action->ack_type == ACKTYPE_NONE ) + { + ASSERT(!test_bit(irq, d->pirq_mask)); + stop_timer(&irq_guest_eoi_timer[vector]); + _irq_guest_eoi(desc); + } if ( unlikely(!test_and_clear_bit(irq, d->pirq_mask)) || unlikely(--action->in_flight != 0) ) @@ -408,7 +453,7 @@ static void __pirq_guest_eoi(struct doma { __set_eoi_ready(desc); spin_unlock(&desc->lock); - flush_ready_eoi(NULL); + flush_ready_eoi(); local_irq_enable(); } else @@ -606,6 +651,11 @@ int pirq_guest_bind(struct vcpu *v, int } action->guest[action->nr_guests++] = v->domain; + + if ( action->ack_type != ACKTYPE_NONE ) + set_pirq_eoi(v->domain, irq); + else + clear_pirq_eoi(v->domain, irq); unlock_out: spin_unlock_irq(&desc->lock); @@ -1050,6 +1100,6 @@ void fixup_irqs(cpumask_t map) peoi = this_cpu(pending_eoi); for ( sp = 0; sp < pending_eoi_sp(peoi); sp++ ) peoi[sp].ready = 1; - flush_ready_eoi(NULL); + flush_ready_eoi(); } #endif diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/mm/shadow/multi.c Thu Dec 04 11:01:53 2008 +0900 @@ -1886,13 +1886,6 @@ static shadow_l1e_t * shadow_get_and_cre if ( r & SHADOW_SET_ERROR ) return NULL; -#if (SHADOW_OPTIMIZATIONS && SHOPT_OUT_OF_SYNC ) - /* All pages walked are now pagetables. Safe to resync pages - in case level 4 or 3 shadows were set. */ - if ( resync ) - shadow_resync_all(v, 0); -#endif - /* This next line is important: in 32-on-PAE and 32-on-64 modes, * the guest l1 table has an 8k shadow, and we need to return * the right mfn of the pair. This call will set it for us as a @@ -1900,6 +1893,14 @@ static shadow_l1e_t * shadow_get_and_cre * compiled out.) */ (void) shadow_l1_index(sl1mfn, guest_l1_table_offset(gw->va)); } + +#if (SHADOW_OPTIMIZATIONS && SHOPT_OUT_OF_SYNC ) + /* All pages walked are now pagetables. Safe to resync pages + in case level 4 or 3 shadows were set. */ + if ( resync ) + shadow_resync_all(v, 0); +#endif + /* Now follow it down a level. Guaranteed to succeed. */ return sh_linear_l1_table(v) + shadow_l1_linear_offset(gw->va); } @@ -2176,7 +2177,8 @@ static int validate_gl4e(struct vcpu *v, result |= SHADOW_SET_ERROR; #if (SHADOW_OPTIMIZATIONS && SHOPT_OUT_OF_SYNC ) - shadow_resync_all(v, 0); + if ( mfn_valid(sl3mfn) ) + shadow_resync_all(v, 0); #endif } l4e_propagate_from_guest(v, new_gl4e, sl3mfn, &new_sl4e, ft_prefetch); @@ -2232,7 +2234,8 @@ static int validate_gl3e(struct vcpu *v, result |= SHADOW_SET_ERROR; #if (SHADOW_OPTIMIZATIONS && SHOPT_OUT_OF_SYNC ) - shadow_resync_all(v, 0); + if ( mfn_valid(sl2mfn) ) + shadow_resync_all(v, 0); #endif } l3e_propagate_from_guest(v, new_gl3e, sl2mfn, &new_sl3e, ft_prefetch); @@ -2924,6 +2927,7 @@ static int sh_page_fault(struct vcpu *v, writes to an out of sync page. */ if ( mfn_valid(gmfn) && mfn_is_out_of_sync(gmfn) ) { + fast_emul = 0; v->arch.paging.last_write_emul_ok = 0; goto page_fault_slow_path; } diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/physdev.c Thu Dec 04 11:01:53 2008 +0900 @@ -14,6 +14,7 @@ #include <public/xen.h> #include <public/physdev.h> #include <xsm/xsm.h> +#include <asm/p2m.h> #ifndef COMPAT typedef long ret_t; @@ -191,7 +192,49 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H ret = -EFAULT; if ( copy_from_guest(&eoi, arg, 1) != 0 ) break; + ret = -EINVAL; + if ( eoi.irq < 0 || eoi.irq >= NR_IRQS ) + break; + if ( v->domain->arch.pirq_eoi_map ) + evtchn_unmask(v->domain->pirq_to_evtchn[eoi.irq]); ret = pirq_guest_eoi(v->domain, eoi.irq); + break; + } + + case PHYSDEVOP_pirq_eoi_gmfn: { + struct physdev_pirq_eoi_gmfn info; + unsigned long mfn; + + BUILD_BUG_ON(NR_IRQS > (PAGE_SIZE * 8)); + + ret = -EFAULT; + if ( copy_from_guest(&info, arg, 1) != 0 ) + break; + + ret = -EINVAL; + mfn = gmfn_to_mfn(current->domain, info.gmfn); + if ( !mfn_valid(mfn) || + !get_page_and_type(mfn_to_page(mfn), v->domain, + PGT_writable_page) ) + break; + + if ( cmpxchg(&v->domain->arch.pirq_eoi_map_mfn, 0, mfn) != 0 ) + { + put_page_and_type(mfn_to_page(mfn)); + ret = -EBUSY; + break; + } + + v->domain->arch.pirq_eoi_map = map_domain_page_global(mfn); + if ( v->domain->arch.pirq_eoi_map == NULL ) + { + v->domain->arch.pirq_eoi_map_mfn = 0; + put_page_and_type(mfn_to_page(mfn)); + ret = -ENOSPC; + break; + } + + ret = 0; break; } diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/x86_64/physdev.c --- a/xen/arch/x86/x86_64/physdev.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/x86_64/physdev.c Thu Dec 04 11:01:53 2008 +0900 @@ -17,6 +17,9 @@ #define physdev_eoi compat_physdev_eoi #define physdev_eoi_t physdev_eoi_compat_t + +#define physdev_pirq_eoi_gmfn compat_physdev_pirq_eoi_gmfn +#define physdev_pirq_eoi_gmfn_t physdev_pirq_eoi_gmfn_compat_t #define physdev_set_iobitmap compat_physdev_set_iobitmap #define physdev_set_iobitmap_t physdev_set_iobitmap_compat_t diff -r 54e5d15af567 -r f4c5befcba8d xen/arch/x86/x86_emulate/x86_emulate.c --- a/xen/arch/x86/x86_emulate/x86_emulate.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c Thu Dec 04 11:01:53 2008 +0900 @@ -28,6 +28,7 @@ #define DstImplicit (0<<1) /* Destination operand is implicit in the opcode. */ #define DstBitBase (1<<1) /* Memory operand, bit string. */ #define DstReg (2<<1) /* Register operand. */ +#define DstEax DstReg /* Register EAX (aka DstReg with no ModRM) */ #define DstMem (3<<1) /* Memory operand. */ #define DstMask (3<<1) /* Source operand type. */ @@ -51,35 +52,35 @@ static uint8_t opcode_table[256] = { /* 0x00 - 0x07 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps, ImplicitOps, /* 0x08 - 0x0F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, 0, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps, 0, /* 0x10 - 0x17 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps, ImplicitOps, /* 0x18 - 0x1F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps, ImplicitOps, /* 0x20 - 0x27 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps, /* 0x28 - 0x2F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps, /* 0x30 - 0x37 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps, /* 0x38 - 0x3F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps, /* 0x40 - 0x4F */ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, @@ -125,7 +126,7 @@ static uint8_t opcode_table[256] = { ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps, ImplicitOps, /* 0xA8 - 0xAF */ - ByteOp|DstReg|SrcImm, DstReg|SrcImm, + ByteOp|DstEax|SrcImm, DstEax|SrcImm, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps, ImplicitOps, @@ -687,12 +688,12 @@ static void __put_rep_prefix( }) /* Clip maximum repetitions so that the index register only just wraps. */ -#define truncate_ea_and_reps(ea, reps, bytes_per_rep) ({ \ - unsigned long __todo = (ctxt->regs->eflags & EF_DF) ? (ea) : ~(ea); \ - __todo = truncate_word(__todo, ad_bytes); \ - __todo = (__todo / (bytes_per_rep)) + 1; \ - (reps) = (__todo < (reps)) ? __todo : (reps); \ - truncate_word((ea), ad_bytes); \ +#define truncate_ea_and_reps(ea, reps, bytes_per_rep) ({ \ + unsigned long __todo = (ctxt->regs->eflags & EFLG_DF) ? (ea) : ~(ea); \ + __todo = truncate_word(__todo, ad_bytes); \ + __todo = (__todo / (bytes_per_rep)) + 1; \ + (reps) = (__todo < (reps)) ? __todo : (reps); \ + truncate_word((ea), ad_bytes); \ }) /* Compatibility function: read guest memory, zero-extend result to a ulong. */ @@ -1574,59 +1575,35 @@ x86_emulate( switch ( b ) { - case 0x04 ... 0x05: /* add imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; - case 0x00 ... 0x03: add: /* add */ + case 0x00 ... 0x05: add: /* add */ emulate_2op_SrcV("add", src, dst, _regs.eflags); break; - case 0x0c ... 0x0d: /* or imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; - case 0x08 ... 0x0b: or: /* or */ + case 0x08 ... 0x0d: or: /* or */ emulate_2op_SrcV("or", src, dst, _regs.eflags); break; - case 0x14 ... 0x15: /* adc imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; - case 0x10 ... 0x13: adc: /* adc */ + case 0x10 ... 0x15: adc: /* adc */ emulate_2op_SrcV("adc", src, dst, _regs.eflags); break; - case 0x1c ... 0x1d: /* sbb imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; - case 0x18 ... 0x1b: sbb: /* sbb */ + case 0x18 ... 0x1d: sbb: /* sbb */ emulate_2op_SrcV("sbb", src, dst, _regs.eflags); break; - case 0x24 ... 0x25: /* and imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; - case 0x20 ... 0x23: and: /* and */ + case 0x20 ... 0x25: and: /* and */ emulate_2op_SrcV("and", src, dst, _regs.eflags); break; - case 0x2c ... 0x2d: /* sub imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; - case 0x28 ... 0x2b: sub: /* sub */ + case 0x28 ... 0x2d: sub: /* sub */ emulate_2op_SrcV("sub", src, dst, _regs.eflags); break; - case 0x34 ... 0x35: /* xor imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; - case 0x30 ... 0x33: xor: /* xor */ + case 0x30 ... 0x35: xor: /* xor */ emulate_2op_SrcV("xor", src, dst, _regs.eflags); break; - case 0x3c ... 0x3d: /* cmp imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; - case 0x38 ... 0x3b: cmp: /* cmp */ + case 0x38 ... 0x3d: cmp: /* cmp */ emulate_2op_SrcV("cmp", src, dst, _regs.eflags); dst.type = OP_NONE; break; @@ -1988,8 +1965,6 @@ x86_emulate( break; case 0xa8 ... 0xa9: /* test imm,%%eax */ - dst.reg = (unsigned long *)&_regs.eax; - dst.val = _regs.eax; case 0x84 ... 0x85: test: /* test */ emulate_2op_SrcV("test", src, dst, _regs.eflags); dst.type = OP_NONE; diff -r 54e5d15af567 -r f4c5befcba8d xen/common/domain.c --- a/xen/common/domain.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/common/domain.c Thu Dec 04 11:01:53 2008 +0900 @@ -553,6 +553,9 @@ static void complete_domain_destroy(stru sched_destroy_domain(d); + /* Free page used by xen oprofile buffer. */ + free_xenoprof_pages(d); + for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- ) if ( (v = d->vcpu[i]) != NULL ) free_vcpu_struct(v); diff -r 54e5d15af567 -r f4c5befcba8d xen/common/event_channel.c --- a/xen/common/event_channel.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/common/event_channel.c Thu Dec 04 11:01:53 2008 +0900 @@ -762,10 +762,9 @@ long evtchn_bind_vcpu(unsigned int port, } -static long evtchn_unmask(evtchn_unmask_t *unmask) +int evtchn_unmask(unsigned int port) { struct domain *d = current->domain; - int port = unmask->port; struct vcpu *v; spin_lock(&d->event_lock); @@ -916,7 +915,7 @@ long do_event_channel_op(int cmd, XEN_GU struct evtchn_unmask unmask; if ( copy_from_guest(&unmask, arg, 1) != 0 ) return -EFAULT; - rc = evtchn_unmask(&unmask); + rc = evtchn_unmask(unmask.port); break; } diff -r 54e5d15af567 -r f4c5befcba8d xen/common/timer.c --- a/xen/common/timer.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/common/timer.c Thu Dec 04 11:01:53 2008 +0900 @@ -494,12 +494,14 @@ static void dump_timerq(unsigned char ke for ( j = 1; j <= GET_HEAP_SIZE(ts->heap); j++ ) { t = ts->heap[j]; - printk (" %d : %p ex=0x%08X%08X %p\n", - j, t, (u32)(t->expires>>32), (u32)t->expires, t->data); + printk (" %d : %p ex=0x%08X%08X %p %p\n", + j, t, (u32)(t->expires>>32), (u32)t->expires, + t->data, t->function); } for ( t = ts->list, j = 0; t != NULL; t = t->list_next, j++ ) - printk (" L%d : %p ex=0x%08X%08X %p\n", - j, t, (u32)(t->expires>>32), (u32)t->expires, t->data); + printk (" L%d : %p ex=0x%08X%08X %p %p\n", + j, t, (u32)(t->expires>>32), (u32)t->expires, + t->data, t->function); spin_unlock_irqrestore(&ts->lock, flags); printk("\n"); } diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/char/console.c --- a/xen/drivers/char/console.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/char/console.c Thu Dec 04 11:01:53 2008 +0900 @@ -927,7 +927,7 @@ void panic(const char *fmt, ...) console_start_sync(); printk("\n****************************************\n"); printk("Panic on CPU %d:\n", smp_processor_id()); - printk(buf); + printk("%s", buf); printk("****************************************\n\n"); if ( opt_noreboot ) printk("Manual reset required ('noreboot' specified)\n"); diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/passthrough/amd/iommu_init.c --- a/xen/drivers/passthrough/amd/iommu_init.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/passthrough/amd/iommu_init.c Thu Dec 04 11:01:53 2008 +0900 @@ -152,13 +152,33 @@ static void __init set_iommu_translation { u32 entry; - entry = readl(iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); - set_field_in_reg_u32(iommu->ht_tunnel_support ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_ENABLED, entry, + entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET); + + if ( enable ) + { + set_field_in_reg_u32(iommu->ht_tunnel_support ? IOMMU_CONTROL_ENABLED : + IOMMU_CONTROL_DISABLED, entry, IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_MASK, IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT, &entry); + set_field_in_reg_u32(iommu->isochronous ? IOMMU_CONTROL_ENABLED : + IOMMU_CONTROL_DISABLED, entry, + IOMMU_CONTROL_ISOCHRONOUS_MASK, + IOMMU_CONTROL_ISOCHRONOUS_SHIFT, &entry); + set_field_in_reg_u32(iommu->coherent ? IOMMU_CONTROL_ENABLED : + IOMMU_CONTROL_DISABLED, entry, + IOMMU_CONTROL_COHERENT_MASK, + IOMMU_CONTROL_COHERENT_SHIFT, &entry); + set_field_in_reg_u32(iommu->res_pass_pw ? IOMMU_CONTROL_ENABLED : + IOMMU_CONTROL_DISABLED, entry, + IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_MASK, + IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT, &entry); + /* do not set PassPW bit */ + set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry, + IOMMU_CONTROL_PASS_POSTED_WRITE_MASK, + IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT, &entry); + } set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_ENABLED, entry, + IOMMU_CONTROL_DISABLED, entry, IOMMU_CONTROL_TRANSLATION_ENABLE_MASK, IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT, &entry); writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); @@ -171,7 +191,7 @@ static void __init set_iommu_command_buf entry = readl(iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_ENABLED, entry, + IOMMU_CONTROL_DISABLED, entry, IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_MASK, IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT, &entry); writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); @@ -235,8 +255,7 @@ static void __init set_iommu_event_log_c IOMMU_CONTROL_EVENT_LOG_INT_SHIFT, &entry); writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); - set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, entry, + set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry, IOMMU_CONTROL_COMP_WAIT_INT_MASK, IOMMU_CONTROL_COMP_WAIT_INT_SHIFT, &entry); writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); @@ -391,20 +410,19 @@ static void parse_event_log_entry(u32 en u32 code; u64 *addr; char * event_str[] = {"ILLEGAL_DEV_TABLE_ENTRY", - "IO_PAGE_FALT", - "DEV_TABLE_HW_ERROR", - "PAGE_TABLE_HW_ERROR", - "ILLEGAL_COMMAND_ERROR", - "COMMAND_HW_ERROR", - "IOTLB_INV_TIMEOUT", - "INVALID_DEV_REQUEST"}; - - code = get_field_from_reg_u32(entry[1], - IOMMU_EVENT_CODE_MASK, - IOMMU_EVENT_CODE_SHIFT); - - if ( (code > IOMMU_EVENT_INVALID_DEV_REQUEST) - || (code < IOMMU_EVENT_ILLEGAL_DEV_TABLE_ENTRY) ) + "IO_PAGE_FALT", + "DEV_TABLE_HW_ERROR", + "PAGE_TABLE_HW_ERROR", + "ILLEGAL_COMMAND_ERROR", + "COMMAND_HW_ERROR", + "IOTLB_INV_TIMEOUT", + "INVALID_DEV_REQUEST"}; + + code = get_field_from_reg_u32(entry[1], IOMMU_EVENT_CODE_MASK, + IOMMU_EVENT_CODE_SHIFT); + + if ( (code > IOMMU_EVENT_INVALID_DEV_REQUEST) || + (code < IOMMU_EVENT_ILLEGAL_DEV_TABLE_ENTRY) ) { amd_iov_error("Invalid event log entry!\n"); return; @@ -428,13 +446,20 @@ static void amd_iommu_page_fault(int vec static void amd_iommu_page_fault(int vector, void *dev_id, struct cpu_user_regs *regs) { - u32 event[4]; + u32 event[4]; + u32 entry; unsigned long flags; int ret = 0; struct amd_iommu *iommu = dev_id; spin_lock_irqsave(&iommu->lock, flags); ret = amd_iommu_read_event_log(iommu, event); + /* reset interrupt status bit */ + entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); + set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, + IOMMU_STATUS_EVENT_LOG_INT_MASK, + IOMMU_STATUS_EVENT_LOG_INT_SHIFT, &entry); + writel(entry, iommu->mmio_base+IOMMU_STATUS_MMIO_OFFSET); spin_unlock_irqrestore(&iommu->lock, flags); if ( ret != 0 ) @@ -466,7 +491,7 @@ static int set_iommu_interrupt_handler(s amd_iov_error("can't request irq\n"); return 0; } - + iommu->vector = vector; return vector; } diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/passthrough/amd/iommu_map.c --- a/xen/drivers/passthrough/amd/iommu_map.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/passthrough/amd/iommu_map.c Thu Dec 04 11:01:53 2008 +0900 @@ -580,3 +580,47 @@ out: spin_unlock_irqrestore(&hd->mapping_lock, flags); return 0; } + +void invalidate_all_iommu_pages(struct domain *d) +{ + u32 cmd[4], entry; + unsigned long flags; + struct amd_iommu *iommu; + int domain_id = d->domain_id; + u64 addr_lo = 0x7FFFFFFFFFFFF000ULL & DMA_32BIT_MASK; + u64 addr_hi = 0x7FFFFFFFFFFFF000ULL >> 32; + + set_field_in_reg_u32(domain_id, 0, + IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_MASK, + IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_SHIFT, &entry); + set_field_in_reg_u32(IOMMU_CMD_INVALIDATE_IOMMU_PAGES, entry, + IOMMU_CMD_OPCODE_MASK, IOMMU_CMD_OPCODE_SHIFT, + &entry); + cmd[1] = entry; + + set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0, + IOMMU_INV_IOMMU_PAGES_S_FLAG_MASK, + IOMMU_INV_IOMMU_PAGES_S_FLAG_SHIFT, &entry); + set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, + IOMMU_INV_IOMMU_PAGES_PDE_FLAG_MASK, + IOMMU_INV_IOMMU_PAGES_PDE_FLAG_SHIFT, &entry); + set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, entry, + IOMMU_INV_IOMMU_PAGES_ADDR_LOW_MASK, + IOMMU_INV_IOMMU_PAGES_ADDR_LOW_SHIFT, &entry); + cmd[2] = entry; + + set_field_in_reg_u32((u32)addr_hi, 0, + IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_MASK, + IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_SHIFT, &entry); + cmd[3] = entry; + + cmd[0] = 0; + + for_each_amd_iommu ( iommu ) + { + spin_lock_irqsave(&iommu->lock, flags); + send_iommu_command(iommu, cmd); + flush_command_buffer(iommu); + spin_unlock_irqrestore(&iommu->lock, flags); + } +} diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/passthrough/amd/pci_amd_iommu.c --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Thu Dec 04 11:01:53 2008 +0900 @@ -389,6 +389,7 @@ static void amd_iommu_domain_destroy(str static void amd_iommu_domain_destroy(struct domain *d) { deallocate_iommu_page_tables(d); + invalidate_all_iommu_pages(d); } static int amd_iommu_return_device( diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/passthrough/vtd/dmar.c --- a/xen/drivers/passthrough/vtd/dmar.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/passthrough/vtd/dmar.c Thu Dec 04 11:01:53 2008 +0900 @@ -172,6 +172,28 @@ struct acpi_drhd_unit * acpi_find_matche return found ? found : include_all; } +struct acpi_atsr_unit * acpi_find_matched_atsr_unit(u8 bus, u8 devfn) +{ + struct acpi_atsr_unit *atsr; + struct acpi_atsr_unit *found = NULL, *include_all = NULL; + int i; + + list_for_each_entry ( atsr, &acpi_atsr_units, list ) + { + for (i = 0; i < atsr->scope.devices_cnt; i++) + if ( atsr->scope.devices[i] == PCI_BDF2(bus, devfn) ) + return atsr; + + if ( test_bit(bus, atsr->scope.buses) ) + found = atsr; + + if ( atsr->all_ports ) + include_all = atsr; + } + + return found ? found : include_all; +} + /* * Count number of devices in device scope. Do not include PCI sub * hierarchies. @@ -242,7 +264,6 @@ static int __init acpi_parse_dev_scope(v switch ( acpi_scope->dev_type ) { case ACPI_DEV_P2PBRIDGE: - { sec_bus = pci_conf_read8( bus, path->dev, path->fn, PCI_SECONDARY_BUS); sub_bus = pci_conf_read8( @@ -253,7 +274,6 @@ static int __init acpi_parse_dev_scope(v dmar_scope_add_buses(scope, sec_bus, sub_bus); break; - } case ACPI_DEV_MSI_HPET: dprintk(XENLOG_INFO VTDPREFIX, "found MSI HPET: bdf = %x:%x.%x\n", @@ -268,7 +288,6 @@ static int __init acpi_parse_dev_scope(v break; case ACPI_DEV_IOAPIC: - { dprintk(XENLOG_INFO VTDPREFIX, "found IOAPIC: bdf = %x:%x.%x\n", bus, path->dev, path->fn); @@ -288,7 +307,6 @@ static int __init acpi_parse_dev_scope(v scope->devices[didx++] = PCI_BDF(bus, path->dev, path->fn); break; } - } start += acpi_scope->length; } diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/passthrough/vtd/dmar.h --- a/xen/drivers/passthrough/vtd/dmar.h Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/passthrough/vtd/dmar.h Thu Dec 04 11:01:53 2008 +0900 @@ -80,6 +80,7 @@ struct acpi_atsr_unit { idx < rmrr->scope.devices_cnt; idx++) struct acpi_drhd_unit * acpi_find_matched_drhd_unit(u8 bus, u8 devfn); +struct acpi_atsr_unit * acpi_find_matched_atsr_unit(u8 bus, u8 devfn); void dmar_scope_add_buses(struct dmar_scope *scope, u16 sec, u16 sub); void dmar_scope_remove_buses(struct dmar_scope *scope, u16 sec, u16 sub); diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/passthrough/vtd/iommu.c Thu Dec 04 11:01:53 2008 +0900 @@ -446,10 +446,6 @@ static int flush_iotlb_reg(void *_iommu, if ( DMA_TLB_IAIG(val) == 0 ) dprintk(XENLOG_ERR VTDPREFIX, "IOMMU: flush IOTLB failed\n"); - if ( DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type) ) - dprintk(XENLOG_INFO VTDPREFIX, - "IOMMU: tlb flush request %x, actual %x\n", - (u32)DMA_TLB_IIRG(type), (u32)DMA_TLB_IAIG(val)); /* flush iotlb entry will implicitly flush write buffer */ return 0; } @@ -714,22 +710,22 @@ static void iommu_fault_status(u32 fault if ( fault_status & DMA_FSTS_PFO ) dprintk(XENLOG_ERR VTDPREFIX, "iommu_fault_status: Fault Overflow\n"); - else if ( fault_status & DMA_FSTS_PPF ) + if ( fault_status & DMA_FSTS_PPF ) dprintk(XENLOG_ERR VTDPREFIX, "iommu_fault_status: Primary Pending Fault\n"); - else if ( fault_status & DMA_FSTS_AFO ) + if ( fault_status & DMA_FSTS_AFO ) dprintk(XENLOG_ERR VTDPREFIX, "iommu_fault_status: Advanced Fault Overflow\n"); - else if ( fault_status & DMA_FSTS_APF ) + if ( fault_status & DMA_FSTS_APF ) dprintk(XENLOG_ERR VTDPREFIX, "iommu_fault_status: Advanced Pending Fault\n"); - else if ( fault_status & DMA_FSTS_IQE ) + if ( fault_status & DMA_FSTS_IQE ) dprintk(XENLOG_ERR VTDPREFIX, "iommu_fault_status: Invalidation Queue Error\n"); - else if ( fault_status & DMA_FSTS_ICE ) + if ( fault_status & DMA_FSTS_ICE ) dprintk(XENLOG_ERR VTDPREFIX, "iommu_fault_status: Invalidation Completion Error\n"); - else if ( fault_status & DMA_FSTS_ITE ) + if ( fault_status & DMA_FSTS_ITE ) dprintk(XENLOG_ERR VTDPREFIX, "iommu_fault_status: Invalidation Time-out Error\n"); } @@ -754,10 +750,11 @@ static void iommu_page_fault(int vector, /* FIXME: ignore advanced fault log */ if ( !(fault_status & DMA_FSTS_PPF) ) - return; + goto clear_overflow; + fault_index = dma_fsts_fault_record_index(fault_status); reg = cap_fault_reg_offset(iommu->cap); - for ( ; ; ) + while (1) { u8 fault_reason; u16 source_id; @@ -797,8 +794,9 @@ static void iommu_page_fault(int vector, if ( fault_index > cap_num_fault_regs(iommu->cap) ) fault_index = 0; } - +clear_overflow: /* clear primary fault overflow */ + fault_status = readl(iommu->reg + DMAR_FSTS_REG); if ( fault_status & DMA_FSTS_PFO ) { spin_lock_irqsave(&iommu->register_lock, flags); @@ -1125,10 +1123,11 @@ static int domain_context_mapping_one( unmap_vtd_domain_page(context_entries); /* Context entry was previously non-present (with domid 0). */ - iommu_flush_context_device(iommu, 0, (((u16)bus) << 8) | devfn, - DMA_CCMD_MASK_NOBIT, 1); - if ( iommu_flush_iotlb_dsi(iommu, 0, 1) ) + if ( iommu_flush_context_device(iommu, 0, (((u16)bus) << 8) | devfn, + DMA_CCMD_MASK_NOBIT, 1) ) iommu_flush_write_buffer(iommu); + else + iommu_flush_iotlb_dsi(iommu, 0, 1); set_bit(iommu->index, &hd->iommu_bitmap); spin_unlock_irqrestore(&iommu->lock, flags); @@ -1308,8 +1307,12 @@ static int domain_context_unmap_one( context_clear_present(*context); context_clear_entry(*context); iommu_flush_cache_entry(context); - iommu_flush_context_domain(iommu, domain_iommu_domid(domain), 0); - iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0); + + if ( iommu_flush_context_domain(iommu, domain_iommu_domid(domain), 0) ) + iommu_flush_write_buffer(iommu); + else + iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0); + unmap_vtd_domain_page(context_entries); spin_unlock_irqrestore(&iommu->lock, flags); diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/passthrough/vtd/iommu.h --- a/xen/drivers/passthrough/vtd/iommu.h Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/passthrough/vtd/iommu.h Thu Dec 04 11:01:53 2008 +0900 @@ -310,6 +310,10 @@ struct qinval_entry { struct qinval_entry { union { struct { + u64 lo; + u64 hi; + }val; + struct { struct { u64 type : 4, granu : 2, diff -r 54e5d15af567 -r f4c5befcba8d xen/drivers/passthrough/vtd/qinval.c --- a/xen/drivers/passthrough/vtd/qinval.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/drivers/passthrough/vtd/qinval.c Thu Dec 04 11:01:53 2008 +0900 @@ -34,13 +34,13 @@ static void print_qi_regs(struct iommu * u64 val; val = dmar_readq(iommu->reg, DMAR_IQA_REG); - printk("DMAR_IAQ_REG = %"PRIx64"\n", val); + printk("DMAR_IQA_REG = %"PRIx64"\n", val); val = dmar_readq(iommu->reg, DMAR_IQH_REG); - printk("DMAR_IAH_REG = %"PRIx64"\n", val); + printk("DMAR_IQH_REG = %"PRIx64"\n", val); val = dmar_readq(iommu->reg, DMAR_IQT_REG); - printk("DMAR_IAT_REG = %"PRIx64"\n", val); + printk("DMAR_IQT_REG = %"PRIx64"\n", val); } static int qinval_next_index(struct iommu *iommu) @@ -252,14 +252,15 @@ static int gen_dev_iotlb_inv_dsc(struct qinval_entry->q.dev_iotlb_inv_dsc.lo.res_3 = 0; qinval_entry->q.dev_iotlb_inv_dsc.hi.size = size; - qinval_entry->q.dev_iotlb_inv_dsc.hi.addr = addr; - - unmap_vtd_domain_page(qinval_entries); - spin_unlock_irqrestore(&qi_ctrl->qinval_lock, flags); - return 0; -} - -int queue_invalidate_device_iotlb(struct iommu *iommu, + qinval_entry->q.dev_iotlb_inv_dsc.hi.res_1 = 0; + qinval_entry->q.dev_iotlb_inv_dsc.hi.addr = addr >> PAGE_SHIFT_4K; + + unmap_vtd_domain_page(qinval_entries); + spin_unlock_irqrestore(&qi_ctrl->qinval_lock, flags); + return 0; +} + +int qinval_device_iotlb(struct iommu *iommu, u32 max_invs_pend, u16 sid, u16 size, u64 addr) { int ret = -1; diff -r 54e5d15af567 -r f4c5befcba8d xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/include/asm-x86/domain.h Thu Dec 04 11:01:53 2008 +0900 @@ -237,6 +237,10 @@ struct arch_domain /* NB. protected by d->event_lock and by irq_desc[vector].lock */ int vector_pirq[NR_VECTORS]; s16 pirq_vector[NR_IRQS]; + + /* Shared page for notifying that explicit PIRQ EOI is required. */ + unsigned long *pirq_eoi_map; + unsigned long pirq_eoi_map_mfn; /* Pseudophysical e820 map (XENMEM_memory_map). */ struct e820entry e820[3]; diff -r 54e5d15af567 -r f4c5befcba8d xen/include/asm-x86/hvm/svm/amd-iommu-proto.h --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Thu Dec 04 11:01:53 2008 +0900 @@ -63,6 +63,7 @@ int amd_iommu_reserve_domain_unity_map(s int amd_iommu_reserve_domain_unity_map(struct domain *domain, unsigned long phys_addr, unsigned long size, int iw, int ir); int amd_iommu_sync_p2m(struct domain *d); +void invalidate_all_iommu_pages(struct domain *d); /* device table functions */ void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr, diff -r 54e5d15af567 -r f4c5befcba8d xen/include/asm-x86/page.h --- a/xen/include/asm-x86/page.h Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/include/asm-x86/page.h Thu Dec 04 11:01:53 2008 +0900 @@ -228,7 +228,7 @@ void copy_page_sse2(void *, const void * /* Convert between Xen-heap virtual addresses and machine frame numbers. */ #define virt_to_mfn(va) (virt_to_maddr(va) >> PAGE_SHIFT) -#define mfn_to_virt(mfn) (maddr_to_virt(mfn << PAGE_SHIFT)) +#define mfn_to_virt(mfn) (maddr_to_virt((paddr_t)(mfn) << PAGE_SHIFT)) /* Convert between machine frame numbers and page-info structures. */ #define mfn_to_page(mfn) (frame_table + (mfn)) diff -r 54e5d15af567 -r f4c5befcba8d xen/include/public/physdev.h --- a/xen/include/public/physdev.h Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/include/public/physdev.h Thu Dec 04 11:01:53 2008 +0900 @@ -41,6 +41,21 @@ DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t); DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t); /* + * Register a shared page for the hypervisor to indicate whether the guest + * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly + * once the guest used this function in that the associated event channel + * will automatically get unmasked. The page registered is used as a bit + * array indexed by Xen's PIRQ value. + */ +#define PHYSDEVOP_pirq_eoi_gmfn 17 +struct physdev_pirq_eoi_gmfn { + /* IN */ + xen_pfn_t gmfn; +}; +typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t); + +/* * Query the status of an IRQ line. * @arg == pointer to physdev_irq_status_query structure. */ diff -r 54e5d15af567 -r f4c5befcba8d xen/include/xen/event.h --- a/xen/include/xen/event.h Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/include/xen/event.h Thu Dec 04 11:01:53 2008 +0900 @@ -44,6 +44,9 @@ int evtchn_send(struct domain *d, unsign /* Bind a local event-channel port to the specified VCPU. */ long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id); +/* Unmask a local event-channel port. */ +int evtchn_unmask(unsigned int port); + /* Allocate/free a Xen-attached event channel port. */ int alloc_unbound_xen_event_channel( struct vcpu *local_vcpu, domid_t remote_domid); diff -r 54e5d15af567 -r f4c5befcba8d xen/include/xen/irq.h --- a/xen/include/xen/irq.h Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/include/xen/irq.h Thu Dec 04 11:01:53 2008 +0900 @@ -22,6 +22,7 @@ struct irqaction #define IRQ_PENDING 4 /* IRQ pending - replay on enable */ #define IRQ_REPLAY 8 /* IRQ has been replayed but not acked yet */ #define IRQ_GUEST 16 /* IRQ is handled by guest OS(es) */ +#define IRQ_GUEST_EOI_PENDING 32 /* IRQ was disabled, pending a guest EOI */ #define IRQ_PER_CPU 256 /* IRQ is per CPU */ /* diff -r 54e5d15af567 -r f4c5befcba8d xen/tools/symbols.c --- a/xen/tools/symbols.c Wed Dec 03 11:43:54 2008 +0900 +++ b/xen/tools/symbols.c Thu Dec 04 11:01:53 2008 +0900 @@ -81,7 +81,8 @@ static int read_symbol(FILE *in, struct if (rc != 3) { if (rc != EOF) { /* skip line */ - fgets(str, 500, in); + if (fgets(str, 500, in) == NULL) + return -1; /* must check fgets result */ } return -1; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |