ia64/xen-unstable
changeset 18691:b0426fc080f3
[IA64] Add glue code for VTD
Signed-off-by: Anthony Xu <anthony.xu@intel.com>
Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author | Isaku Yamahata <yamahata@valinux.co.jp> |
---|---|
date | Fri Oct 24 13:49:58 2008 +0900 (2008-10-24) |
parents | c19871b66cea |
children | ecfb1637cef9 |
files | xen/arch/ia64/linux-xen/acpi.c xen/arch/ia64/vmx/viosapic.c xen/arch/ia64/vmx/vmx_fault.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/irq.c xen/arch/ia64/xen/mm.c xen/include/asm-ia64/linux-xen/asm/acpi.h xen/include/asm-ia64/linux-xen/asm/iosapic.h xen/include/asm-ia64/viosapic.h |
line diff
1.1 --- a/xen/arch/ia64/linux-xen/acpi.c Fri Oct 24 11:47:29 2008 +0900 1.2 +++ b/xen/arch/ia64/linux-xen/acpi.c Fri Oct 24 13:49:58 2008 +0900 1.3 @@ -797,6 +797,10 @@ int __init acpi_boot_init(void) 1.4 if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt)) 1.5 printk(KERN_ERR PREFIX "Can't find FADT\n"); 1.6 1.7 +#ifdef XEN 1.8 + acpi_dmar_init(); 1.9 +#endif 1.10 + 1.11 #ifdef CONFIG_SMP 1.12 if (available_cpus == 0) { 1.13 printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
2.1 --- a/xen/arch/ia64/vmx/viosapic.c Fri Oct 24 11:47:29 2008 +0900 2.2 +++ b/xen/arch/ia64/vmx/viosapic.c Fri Oct 24 13:49:58 2008 +0900 2.3 @@ -121,6 +121,13 @@ static void viosapic_update_EOI(struct v 2.4 redir_num, vector); 2.5 return; 2.6 } 2.7 + if ( iommu_enabled ) 2.8 + { 2.9 + spin_unlock(&viosapic->lock); 2.10 + hvm_dpci_eoi(current->domain, redir_num, &viosapic->redirtbl[redir_num]); 2.11 + spin_lock(&viosapic->lock); 2.12 + } 2.13 + 2.14 service_iosapic(viosapic); 2.15 spin_unlock(&viosapic->lock); 2.16 }
3.1 --- a/xen/arch/ia64/vmx/vmx_fault.c Fri Oct 24 11:47:29 2008 +0900 3.2 +++ b/xen/arch/ia64/vmx/vmx_fault.c Fri Oct 24 13:49:58 2008 +0900 3.3 @@ -54,6 +54,7 @@ 3.4 #include <asm/shadow.h> 3.5 #include <asm/sioemu.h> 3.6 #include <public/arch-ia64/sioemu.h> 3.7 +#include <xen/hvm/irq.h> 3.8 3.9 /* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */ 3.10 #define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034 3.11 @@ -306,6 +307,7 @@ void leave_hypervisor_tail(void) 3.12 viosapic_set_irq(d, callback_irq, 0); 3.13 } 3.14 } 3.15 + hvm_dirq_assist(v); 3.16 } 3.17 3.18 rmb();
4.1 --- a/xen/arch/ia64/xen/domain.c Fri Oct 24 11:47:29 2008 +0900 4.2 +++ b/xen/arch/ia64/xen/domain.c Fri Oct 24 13:49:58 2008 +0900 4.3 @@ -602,6 +602,11 @@ int arch_domain_create(struct domain *d, 4.4 if ((d->arch.mm.pgd = pgd_alloc(&d->arch.mm)) == NULL) 4.5 goto fail_nomem; 4.6 4.7 + if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){ 4.8 + if(iommu_domain_init(d) != 0) 4.9 + goto fail_iommu; 4.10 + } 4.11 + 4.12 /* 4.13 * grant_table_create() can't fully initialize grant table for domain 4.14 * because it is called before arch_domain_create(). 4.15 @@ -618,6 +623,8 @@ int arch_domain_create(struct domain *d, 4.16 dprintk(XENLOG_DEBUG, "arch_domain_create: domain=%p\n", d); 4.17 return 0; 4.18 4.19 +fail_iommu: 4.20 + iommu_domain_destroy(d); 4.21 fail_nomem: 4.22 tlb_track_destroy(d); 4.23 fail_nomem1: 4.24 @@ -637,6 +644,11 @@ void arch_domain_destroy(struct domain * 4.25 free_xenheap_pages(d->shared_info, 4.26 get_order_from_shift(XSI_SHIFT)); 4.27 4.28 + if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ) { 4.29 + pci_release_devices(d); 4.30 + iommu_domain_destroy(d); 4.31 + } 4.32 + 4.33 tlb_track_destroy(d); 4.34 4.35 /* Clear vTLB for the next domain. */
5.1 --- a/xen/arch/ia64/xen/irq.c Fri Oct 24 11:47:29 2008 +0900 5.2 +++ b/xen/arch/ia64/xen/irq.c Fri Oct 24 13:49:58 2008 +0900 5.3 @@ -312,12 +312,25 @@ typedef struct { 5.4 struct domain *guest[IRQ_MAX_GUESTS]; 5.5 } irq_guest_action_t; 5.6 5.7 +static struct timer irq_guest_eoi_timer[NR_IRQS]; 5.8 +static void irq_guest_eoi_timer_fn(void *data) 5.9 +{ 5.10 + irq_desc_t *desc = data; 5.11 + unsigned vector = desc - irq_desc; 5.12 + unsigned long flags; 5.13 + 5.14 + spin_lock_irqsave(&desc->lock, flags); 5.15 + desc->status &= ~IRQ_INPROGRESS; 5.16 + desc->handler->enable(vector); 5.17 + spin_unlock_irqrestore(&desc->lock, flags); 5.18 +} 5.19 + 5.20 void __do_IRQ_guest(int irq) 5.21 { 5.22 irq_desc_t *desc = &irq_desc[irq]; 5.23 irq_guest_action_t *action = (irq_guest_action_t *)desc->action; 5.24 struct domain *d; 5.25 - int i; 5.26 + int i, already_pending = 0; 5.27 5.28 for ( i = 0; i < action->nr_guests; i++ ) 5.29 { 5.30 @@ -325,8 +338,29 @@ void __do_IRQ_guest(int irq) 5.31 if ( (action->ack_type != ACKTYPE_NONE) && 5.32 !test_and_set_bit(irq, &d->pirq_mask) ) 5.33 action->in_flight++; 5.34 - send_guest_pirq(d, irq); 5.35 - } 5.36 + if ( hvm_do_IRQ_dpci(d, irq) ) 5.37 + { 5.38 + if ( action->ack_type == ACKTYPE_NONE ) 5.39 + { 5.40 + already_pending += !!(desc->status & IRQ_INPROGRESS); 5.41 + desc->status |= IRQ_INPROGRESS; /* cleared during hvm eoi */ 5.42 + } 5.43 + } 5.44 + else if ( send_guest_pirq(d, irq) && 5.45 + (action->ack_type == ACKTYPE_NONE) ) 5.46 + { 5.47 + already_pending++; 5.48 + } 5.49 + } 5.50 + 5.51 + if ( already_pending == action->nr_guests ) 5.52 + { 5.53 + desc->handler->disable(irq); 5.54 + stop_timer(&irq_guest_eoi_timer[irq]); 5.55 + init_timer(&irq_guest_eoi_timer[irq], 5.56 + irq_guest_eoi_timer_fn, desc, smp_processor_id()); 5.57 + set_timer(&irq_guest_eoi_timer[irq], NOW() + MILLISECS(1)); 5.58 + } 5.59 } 5.60 5.61 int pirq_acktype(int irq)
6.1 --- a/xen/arch/ia64/xen/mm.c Fri Oct 24 11:47:29 2008 +0900 6.2 +++ b/xen/arch/ia64/xen/mm.c Fri Oct 24 13:49:58 2008 +0900 6.3 @@ -1435,6 +1435,8 @@ zap_domain_page_one(struct domain *d, un 6.4 if (mfn == INVALID_MFN) { 6.5 // clear pte 6.6 old_pte = ptep_get_and_clear(mm, mpaddr, pte); 6.7 + if(!pte_mem(old_pte)) 6.8 + return; 6.9 mfn = pte_pfn(old_pte); 6.10 } else { 6.11 unsigned long old_arflags; 6.12 @@ -1472,6 +1474,13 @@ zap_domain_page_one(struct domain *d, un 6.13 if(!mfn_valid(mfn)) 6.14 return; 6.15 6.16 + if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){ 6.17 + int i, j; 6.18 + j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K); 6.19 + for(i = 0 ; i < j; i++) 6.20 + iommu_unmap_page(d, (mpaddr>>PAGE_SHIFT)*j + i); 6.21 + } 6.22 + 6.23 page = mfn_to_page(mfn); 6.24 BUG_ON((page->count_info & PGC_count_mask) == 0); 6.25 6.26 @@ -2856,6 +2865,12 @@ static void 6.27 smp_mb(); 6.28 assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 6.29 ASSIGN_writable | ASSIGN_pgc_allocated); 6.30 + if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){ 6.31 + int i, j; 6.32 + j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K); 6.33 + for(i = 0 ; i < j; i++) 6.34 + iommu_map_page(d, gpfn*j + i, mfn*j + i); 6.35 + } 6.36 } 6.37 6.38 int
7.1 --- a/xen/include/asm-ia64/linux-xen/asm/acpi.h Fri Oct 24 11:47:29 2008 +0900 7.2 +++ b/xen/include/asm-ia64/linux-xen/asm/acpi.h Fri Oct 24 13:49:58 2008 +0900 7.3 @@ -38,6 +38,7 @@ 7.4 #include <asm/numa.h> 7.5 #ifdef XEN 7.6 #include <xen/nodemask.h> 7.7 +extern int acpi_dmar_init(void); 7.8 #endif 7.9 7.10 #define COMPILER_DEPENDENT_INT64 long
8.1 --- a/xen/include/asm-ia64/linux-xen/asm/iosapic.h Fri Oct 24 11:47:29 2008 +0900 8.2 +++ b/xen/include/asm-ia64/linux-xen/asm/iosapic.h Fri Oct 24 13:49:58 2008 +0900 8.3 @@ -83,12 +83,25 @@ static inline int find_iosapic_by_addr(u 8.4 8.5 static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int reg) 8.6 { 8.7 +#ifdef XEN 8.8 + if(iommu_enabled && (reg >= 10)){ 8.9 + int apic = find_iosapic_by_addr((unsigned long)iosapic); 8.10 + return io_apic_read_remap_rte(apic, reg); 8.11 + } 8.12 +#endif 8.13 writel(reg, iosapic + IOSAPIC_REG_SELECT); 8.14 return readl(iosapic + IOSAPIC_WINDOW); 8.15 } 8.16 8.17 static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) 8.18 { 8.19 +#ifdef XEN 8.20 + if (iommu_enabled && (reg >= 10)){ 8.21 + int apic = find_iosapic_by_addr((unsigned long)iosapic); 8.22 + iommu_update_ire_from_apic(apic, reg, val); 8.23 + return; 8.24 + } 8.25 +#endif 8.26 writel(reg, iosapic + IOSAPIC_REG_SELECT); 8.27 writel(val, iosapic + IOSAPIC_WINDOW); 8.28 }
9.1 --- a/xen/include/asm-ia64/viosapic.h Fri Oct 24 11:47:29 2008 +0900 9.2 +++ b/xen/include/asm-ia64/viosapic.h Fri Oct 24 13:49:58 2008 +0900 9.3 @@ -70,5 +70,7 @@ void viosapic_write(struct vcpu *v, unsi 9.4 9.5 unsigned long viosapic_read(struct vcpu *v, unsigned long addr, 9.6 unsigned long length); 9.7 +void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi, 9.8 + union vioapic_redir_entry *ent); 9.9 9.10 #endif /* __ASM_IA64_VMX_VIOSAPIC_H__ */