# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1224823798 -32400
# Node ID b0426fc080f3560eb37fb10597f79f92aa2c86c3
# Parent c19871b66cea01eeb5d67352e4251f43f50bf1e1
[IA64] Add glue code for VTD
Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
xen/arch/ia64/linux-xen/acpi.c | 4 ++
xen/arch/ia64/vmx/viosapic.c | 7 ++++
xen/arch/ia64/vmx/vmx_fault.c | 2 +
xen/arch/ia64/xen/domain.c | 12 ++++++++
xen/arch/ia64/xen/irq.c | 40 ++++++++++++++++++++++++---
xen/arch/ia64/xen/mm.c | 15 ++++++++++
xen/include/asm-ia64/linux-xen/asm/acpi.h | 1
xen/include/asm-ia64/linux-xen/asm/iosapic.h | 13 ++++++++
xen/include/asm-ia64/viosapic.h | 2 +
9 files changed, 93 insertions(+), 3 deletions(-)
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/linux-xen/acpi.c
--- a/xen/arch/ia64/linux-xen/acpi.c Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/linux-xen/acpi.c Fri Oct 24 13:49:58 2008 +0900
@@ -797,6 +797,10 @@ int __init acpi_boot_init(void)
if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt))
printk(KERN_ERR PREFIX "Can't find FADT\n");
+#ifdef XEN
+ acpi_dmar_init();
+#endif
+
#ifdef CONFIG_SMP
if (available_cpus == 0) {
printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/vmx/viosapic.c
--- a/xen/arch/ia64/vmx/viosapic.c Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/vmx/viosapic.c Fri Oct 24 13:49:58 2008 +0900
@@ -121,6 +121,13 @@ static void viosapic_update_EOI(struct v
redir_num, vector);
return;
}
+ if ( iommu_enabled )
+ {
+ spin_unlock(&viosapic->lock);
+ hvm_dpci_eoi(current->domain, redir_num,
&viosapic->redirtbl[redir_num]);
+ spin_lock(&viosapic->lock);
+ }
+
service_iosapic(viosapic);
spin_unlock(&viosapic->lock);
}
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/vmx/vmx_fault.c
--- a/xen/arch/ia64/vmx/vmx_fault.c Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/vmx/vmx_fault.c Fri Oct 24 13:49:58 2008 +0900
@@ -54,6 +54,7 @@
#include <asm/shadow.h>
#include <asm/sioemu.h>
#include <public/arch-ia64/sioemu.h>
+#include <xen/hvm/irq.h>
/* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */
#define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
@@ -306,6 +307,7 @@ void leave_hypervisor_tail(void)
viosapic_set_irq(d, callback_irq, 0);
}
}
+ hvm_dirq_assist(v);
}
rmb();
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/xen/domain.c Fri Oct 24 13:49:58 2008 +0900
@@ -602,6 +602,11 @@ int arch_domain_create(struct domain *d,
if ((d->arch.mm.pgd = pgd_alloc(&d->arch.mm)) == NULL)
goto fail_nomem;
+ if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
+ if(iommu_domain_init(d) != 0)
+ goto fail_iommu;
+ }
+
/*
* grant_table_create() can't fully initialize grant table for domain
* because it is called before arch_domain_create().
@@ -618,6 +623,8 @@ int arch_domain_create(struct domain *d,
dprintk(XENLOG_DEBUG, "arch_domain_create: domain=%p\n", d);
return 0;
+fail_iommu:
+ iommu_domain_destroy(d);
fail_nomem:
tlb_track_destroy(d);
fail_nomem1:
@@ -636,6 +643,11 @@ void arch_domain_destroy(struct domain *
if (d->shared_info != NULL)
free_xenheap_pages(d->shared_info,
get_order_from_shift(XSI_SHIFT));
+
+ if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ) {
+ pci_release_devices(d);
+ iommu_domain_destroy(d);
+ }
tlb_track_destroy(d);
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/xen/irq.c
--- a/xen/arch/ia64/xen/irq.c Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/xen/irq.c Fri Oct 24 13:49:58 2008 +0900
@@ -312,12 +312,25 @@ typedef struct {
struct domain *guest[IRQ_MAX_GUESTS];
} irq_guest_action_t;
+static struct timer irq_guest_eoi_timer[NR_IRQS];
+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);
+ spin_unlock_irqrestore(&desc->lock, flags);
+}
+
void __do_IRQ_guest(int irq)
{
irq_desc_t *desc = &irq_desc[irq];
irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
struct domain *d;
- int i;
+ int i, already_pending = 0;
for ( i = 0; i < action->nr_guests; i++ )
{
@@ -325,8 +338,29 @@ void __do_IRQ_guest(int irq)
if ( (action->ack_type != ACKTYPE_NONE) &&
!test_and_set_bit(irq, &d->pirq_mask) )
action->in_flight++;
- send_guest_pirq(d, irq);
- }
+ if ( hvm_do_IRQ_dpci(d, irq) )
+ {
+ if ( action->ack_type == ACKTYPE_NONE )
+ {
+ already_pending += !!(desc->status &
IRQ_INPROGRESS);
+ desc->status |= IRQ_INPROGRESS; /* cleared
during hvm eoi */
+ }
+ }
+ else if ( send_guest_pirq(d, irq) &&
+ (action->ack_type == ACKTYPE_NONE) )
+ {
+ already_pending++;
+ }
+ }
+
+ if ( already_pending == action->nr_guests )
+ {
+ desc->handler->disable(irq);
+ stop_timer(&irq_guest_eoi_timer[irq]);
+ init_timer(&irq_guest_eoi_timer[irq],
+ irq_guest_eoi_timer_fn, desc,
smp_processor_id());
+ set_timer(&irq_guest_eoi_timer[irq], NOW() + MILLISECS(1));
+ }
}
int pirq_acktype(int irq)
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/xen/mm.c Fri Oct 24 13:49:58 2008 +0900
@@ -1435,6 +1435,8 @@ zap_domain_page_one(struct domain *d, un
if (mfn == INVALID_MFN) {
// clear pte
old_pte = ptep_get_and_clear(mm, mpaddr, pte);
+ if(!pte_mem(old_pte))
+ return;
mfn = pte_pfn(old_pte);
} else {
unsigned long old_arflags;
@@ -1471,6 +1473,13 @@ zap_domain_page_one(struct domain *d, un
perfc_incr(zap_domain_page_one);
if(!mfn_valid(mfn))
return;
+
+ if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
+ int i, j;
+ j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K);
+ for(i = 0 ; i < j; i++)
+ iommu_unmap_page(d, (mpaddr>>PAGE_SHIFT)*j + i);
+ }
page = mfn_to_page(mfn);
BUG_ON((page->count_info & PGC_count_mask) == 0);
@@ -2856,6 +2865,12 @@ __guest_physmap_add_page(struct domain *
smp_mb();
assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn,
ASSIGN_writable | ASSIGN_pgc_allocated);
+ if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
+ int i, j;
+ j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K);
+ for(i = 0 ; i < j; i++)
+ iommu_map_page(d, gpfn*j + i, mfn*j + i);
+ }
}
int
diff -r c19871b66cea -r b0426fc080f3 xen/include/asm-ia64/linux-xen/asm/acpi.h
--- a/xen/include/asm-ia64/linux-xen/asm/acpi.h Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/include/asm-ia64/linux-xen/asm/acpi.h Fri Oct 24 13:49:58 2008 +0900
@@ -38,6 +38,7 @@
#include <asm/numa.h>
#ifdef XEN
#include <xen/nodemask.h>
+extern int acpi_dmar_init(void);
#endif
#define COMPILER_DEPENDENT_INT64 long
diff -r c19871b66cea -r b0426fc080f3
xen/include/asm-ia64/linux-xen/asm/iosapic.h
--- a/xen/include/asm-ia64/linux-xen/asm/iosapic.h Fri Oct 24 11:47:29
2008 +0900
+++ b/xen/include/asm-ia64/linux-xen/asm/iosapic.h Fri Oct 24 13:49:58
2008 +0900
@@ -83,12 +83,25 @@ static inline int find_iosapic_by_addr(u
static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int
reg)
{
+#ifdef XEN
+ if(iommu_enabled && (reg >= 10)){
+ int apic = find_iosapic_by_addr((unsigned long)iosapic);
+ return io_apic_read_remap_rte(apic, reg);
+ }
+#endif
writel(reg, iosapic + IOSAPIC_REG_SELECT);
return readl(iosapic + IOSAPIC_WINDOW);
}
static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32
val)
{
+#ifdef XEN
+ if (iommu_enabled && (reg >= 10)){
+ int apic = find_iosapic_by_addr((unsigned long)iosapic);
+ iommu_update_ire_from_apic(apic, reg, val);
+ return;
+ }
+#endif
writel(reg, iosapic + IOSAPIC_REG_SELECT);
writel(val, iosapic + IOSAPIC_WINDOW);
}
diff -r c19871b66cea -r b0426fc080f3 xen/include/asm-ia64/viosapic.h
--- a/xen/include/asm-ia64/viosapic.h Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/include/asm-ia64/viosapic.h Fri Oct 24 13:49:58 2008 +0900
@@ -70,5 +70,7 @@ void viosapic_write(struct vcpu *v, unsi
unsigned long viosapic_read(struct vcpu *v, unsigned long addr,
unsigned long length);
+void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
+ union vioapic_redir_entry *ent);
#endif /* __ASM_IA64_VMX_VIOSAPIC_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|