Stefano Stabellini
2010-Oct-12 16:41 UTC
[Xen-devel] [PATCH v3 00/10] xen: initial domain support
Hi all, this series implements the basic support needed to boot Linux as initial domain on Xen: the target is not to add full featured dom0 support in the kernel but to be able to boot Linux on Xen on native. We tried to minimize the impact to generic x86 code and interfaces and since v2 of the series we were able to eliminate all the modifications to non-Xen specific code. New changes in v2: - remove the last three patches that added Xen mtrr support; - add a new patch to mask the cpu mtrr feature from the cpuid on Xen. New changes in v3: - compile all the initial domain functions in arch/x86/pci/xen.c only if CONFIG_XEN_DOM0 is defined; - compile the msi functions in drivers/xen/events.c only if CONFIG_PCI_MSI is defined; - move the xen_setup_pirqs declaration to arch/x86/include/asm/xen/pci.h. This series depends on two other patch series not yet applied but already sent to the list for comments a little while back: Konrad''s "Xen PCI frontend driver" series http://lkml.org/lkml/2010/10/12/207 my "PV on HVM: receive interrupts as xen events" series http://lkml.org/lkml/2010/10/12/246 The list of patches with a diffstat follows: Ian Campbell (1): xen: use host E820 map for dom0 Jeremy Fitzhardinge (3): xen: remap GSIs as pirqs when running as initial domain xen: map a dummy page for local apic and ioapic in xen_set_fixmap xen: make hvc_xen console work for dom0. Juan Quintela (2): xen: Initialize xenbus for dom0. xen: add the direct mapping area for ISA bus access Qing He (1): xen: remap MSIs into pirqs when running as initial domain Stefano Stabellini (3): xen: introduce XEN_DOM0 as a silent option xen: use vcpu_ops to setup cpu masks xen: mask the MTRR feature from the cpuid arch/x86/include/asm/xen/pci.h | 7 ++ arch/x86/pci/xen.c | 187 +++++++++++++++++++++++++++++++++---- arch/x86/xen/Kconfig | 5 + arch/x86/xen/enlighten.c | 2 + arch/x86/xen/mmu.c | 47 +++++++++- arch/x86/xen/setup.c | 46 +++++++++- arch/x86/xen/smp.c | 8 ++- drivers/char/hvc_xen.c | 98 +++++++++++++------- drivers/xen/events.c | 75 +++++++++++++++- drivers/xen/xenbus/xenbus_probe.c | 29 ++++++- include/xen/events.h | 5 + include/xen/interface/memory.h | 28 ++++++ include/xen/interface/physdev.h | 10 ++ 13 files changed, 487 insertions(+), 60 deletions(-) A git tree with this and the other two series on top of Linux 2.6.36-rc6 is available here: git://xenbits.xen.org/people/sstabellini/linux-pvhvm.git 2.6.36-rc6-initial-domain-v3 Cheers, Stefano Stabellini _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 01/10] xen: introduce XEN_DOM0 as a silent option
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Add XEN_DOM0 to arch/x86/xen/Kconfig as a silent compile time option that gets enabled when xen and basic x86, acpi and pci support are selected. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- arch/x86/xen/Kconfig | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 68128a1..9bbb06b 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig @@ -13,6 +13,11 @@ config XEN kernel to boot in a paravirtualized environment under the Xen hypervisor. +config XEN_DOM0 + def_bool y + depends on XEN && PCI_XEN && SWIOTLB_XEN + depends on X86_LOCAL_APIC && X86_IO_APIC && ACPI && PCI + config XEN_PVHVM def_bool y depends on XEN -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 02/10] xen: remap GSIs as pirqs when running as initial domain
From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Implement xen_register_gsi to setup the correct triggering and polarity properties of a gsi. Implement xen_register_pirq to register a particular gsi as pirq and receive interrupts as events. Call xen_setup_pirqs to register all the legacy ISA irqs as pirqs. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- arch/x86/include/asm/xen/pci.h | 7 ++ arch/x86/pci/xen.c | 132 +++++++++++++++++++++++++++++++++++++++ drivers/xen/events.c | 13 ++++ include/xen/interface/physdev.h | 10 +++ 4 files changed, 162 insertions(+), 0 deletions(-) diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h index f89a42a..2329b3e 100644 --- a/arch/x86/include/asm/xen/pci.h +++ b/arch/x86/include/asm/xen/pci.h @@ -13,6 +13,13 @@ static inline int pci_xen_hvm_init(void) return -1; } #endif +#if defined(CONFIG_XEN_DOM0) +void __init xen_setup_pirqs(void); +#else +static inline void __init xen_setup_pirqs(void) +{ +} +#endif #if defined(CONFIG_PCI_MSI) #if defined(CONFIG_PCI_XEN) diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index fb20d05..5d87774 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -262,3 +262,135 @@ int __init pci_xen_hvm_init(void) #endif return 0; } + +#ifdef CONFIG_XEN_DOM0 +static int xen_register_pirq(u32 gsi, int triggering) +{ + int rc, irq; + struct physdev_map_pirq map_irq; + int shareable = 0; + char *name; + + if (!xen_pv_domain()) + return -1; + + if (triggering == ACPI_EDGE_SENSITIVE) { + shareable = 0; + name = "ioapic-edge"; + } else { + shareable = 1; + name = "ioapic-level"; + } + + irq = xen_allocate_pirq(gsi, shareable, name); + + printk(KERN_DEBUG "xen: --> irq=%d\n", irq); + + if (irq < 0) + goto out; + + map_irq.domid = DOMID_SELF; + map_irq.type = MAP_PIRQ_TYPE_GSI; + map_irq.index = gsi; + map_irq.pirq = irq; + + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); + if (rc) { + printk(KERN_WARNING "xen map irq failed %d\n", rc); + return -1; + } + +out: + return irq; +} + +static int xen_register_gsi(u32 gsi, int triggering, int polarity) +{ + int rc, irq; + struct physdev_setup_gsi setup_gsi; + + if (!xen_pv_domain()) + return -1; + + printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", + gsi, triggering, polarity); + + irq = xen_register_pirq(gsi, triggering); + + setup_gsi.gsi = gsi; + setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); + setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1); + + rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi); + if (rc == -EEXIST) + printk(KERN_INFO "Already setup the GSI :%d\n", gsi); + else if (rc) { + printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n", + gsi, rc); + } + + return irq; +} + +static __init void xen_setup_acpi_sci(void) +{ + int rc; + int trigger, polarity; + int gsi = acpi_sci_override_gsi; + + if (!gsi) + return; + + rc = acpi_get_override_irq(gsi, &trigger, &polarity); + if (rc) + return; + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; + + printk("xen: sci override: global_irq=%d trigger=%d polarity=%d\n", + gsi, trigger, polarity); + + gsi = xen_register_gsi(gsi, trigger, polarity); + printk("xen: acpi sci %d\n", gsi); + + return; +} + +static int acpi_register_gsi_xen(struct device *dev, u32 gsi, + int trigger, int polarity) +{ + return xen_register_gsi(gsi, trigger, polarity); +} + +static int __init pci_xen_initial_domain(void) +{ + xen_setup_acpi_sci(); + __acpi_register_gsi = acpi_register_gsi_xen; + + return 0; +} + +void __init xen_setup_pirqs(void) +{ + int irq; + + pci_xen_initial_domain(); + + if (0 == nr_ioapics) { + for (irq = 0; irq < NR_IRQS_LEGACY; irq++) + xen_allocate_pirq(irq, 0, "xt-pic"); + return; + } + + /* Pre-allocate legacy irqs */ + for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { + int trigger, polarity; + + if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) + continue; + + xen_register_pirq(irq, + trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); + } +} +#endif diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 2edbf7c..4138def 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -683,6 +683,8 @@ out: int xen_destroy_irq(int irq) { struct irq_desc *desc; + struct physdev_unmap_pirq unmap_irq; + struct irq_info *info = info_for_irq(irq); int rc = -ENOENT; spin_lock(&irq_mapping_update_lock); @@ -691,6 +693,15 @@ int xen_destroy_irq(int irq) if (!desc) goto out; + if (xen_initial_domain()) { + unmap_irq.pirq = info->u.pirq.gsi; + unmap_irq.domid = DOMID_SELF; + rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq); + if (rc) { + printk(KERN_WARNING "unmap irq failed %d\n", rc); + goto out; + } + } irq_info[irq] = mk_unbound_info(); dynamic_irq_cleanup(irq); @@ -1427,5 +1438,7 @@ void __init xen_init_IRQ(void) pci_xen_hvm_init(); } else { irq_ctx_init(smp_processor_id()); + if (xen_initial_domain()) + xen_setup_pirqs(); } } diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h index 69a72b9..a85d76c 100644 --- a/include/xen/interface/physdev.h +++ b/include/xen/interface/physdev.h @@ -151,6 +151,16 @@ struct physdev_op { } u; }; +#define PHYSDEVOP_setup_gsi 21 +struct physdev_setup_gsi { + int gsi; + /* IN */ + uint8_t triggering; + /* IN */ + uint8_t polarity; + /* IN */ +}; + #define PHYSDEVOP_get_nr_pirqs 22 struct physdev_nr_pirqs { /* OUT */ -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 03/10] xen: remap MSIs into pirqs when running as initial domain
From: Qing He <qing.he@intel.com> Implement xen_create_msi_irq to create an msi and remap it as pirq. Use xen_create_msi_irq to implement an initial domain specific version of setup_msi_irqs. Signed-off-by: Qing He <qing.he@intel.com> Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- arch/x86/pci/xen.c | 55 ++++++++++++++++++++++++++++++--------------- drivers/xen/events.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/xen/events.h | 4 +++ 3 files changed, 101 insertions(+), 18 deletions(-) diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 5d87774..6253668 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -135,14 +135,12 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (!v) return -ENOMEM; - if (!xen_initial_domain()) { - if (type == PCI_CAP_ID_MSIX) - ret = xen_pci_frontend_enable_msix(dev, &v, nvec); - else - ret = xen_pci_frontend_enable_msi(dev, &v); - if (ret) - goto error; - } + if (type == PCI_CAP_ID_MSIX) + ret = xen_pci_frontend_enable_msix(dev, &v, nvec); + else + ret = xen_pci_frontend_enable_msi(dev, &v); + if (ret) + goto error; i = 0; list_for_each_entry(msidesc, &dev->msi_list, list) { irq = xen_allocate_pirq(v[i], 0, /* not sharable */ @@ -172,23 +170,40 @@ error: static void xen_teardown_msi_irqs(struct pci_dev *dev) { - /* Only do this when were are in non-privileged mode.*/ - if (!xen_initial_domain()) { - struct msi_desc *msidesc; - - msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); - if (msidesc->msi_attrib.is_msix) - xen_pci_frontend_disable_msix(dev); - else - xen_pci_frontend_disable_msi(dev); - } + struct msi_desc *msidesc; + msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); + if (msidesc->msi_attrib.is_msix) + xen_pci_frontend_disable_msix(dev); + else + xen_pci_frontend_disable_msi(dev); } static void xen_teardown_msi_irq(unsigned int irq) { xen_destroy_irq(irq); } + +static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +{ + int irq, ret; + struct msi_desc *msidesc; + + list_for_each_entry(msidesc, &dev->msi_list, list) { + irq = xen_create_msi_irq(dev, msidesc, type); + if (irq < 0) + return -1; + + ret = set_irq_msi(irq, msidesc); + if (ret) + goto error; + } + return 0; + +error: + xen_destroy_irq(irq); + return ret; +} #endif static int xen_pcifront_enable_irq(struct pci_dev *dev) @@ -364,6 +379,10 @@ static int acpi_register_gsi_xen(struct device *dev, u32 gsi, static int __init pci_xen_initial_domain(void) { +#ifdef CONFIG_PCI_MSI + x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; + x86_msi.teardown_msi_irq = xen_teardown_msi_irq; +#endif xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 4138def..9cdc5df 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -29,6 +29,7 @@ #include <linux/bootmem.h> #include <linux/slab.h> #include <linux/irqnr.h> +#include <linux/pci.h> #include <asm/desc.h> #include <asm/ptrace.h> @@ -658,6 +659,10 @@ out: return irq; } +#ifdef CONFIG_PCI_MSI +#include <linux/msi.h> +#include "../pci/msi.h" + void xen_allocate_pirq_msi(char *name, int *irq, int *pirq) { spin_lock(&irq_mapping_update_lock); @@ -680,6 +685,61 @@ out: spin_unlock(&irq_mapping_update_lock); } +int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) +{ + int irq = 0; + struct physdev_map_pirq map_irq; + int rc; + int pos; + u32 table_offset, bir; + + memset(&map_irq, 0, sizeof(map_irq)); + map_irq.domid = DOMID_SELF; + map_irq.type = MAP_PIRQ_TYPE_MSI; + map_irq.index = -1; + map_irq.pirq = -1; + map_irq.bus = dev->bus->number; + map_irq.devfn = dev->devfn; + + if (type == PCI_CAP_ID_MSIX) { + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + + pci_read_config_dword(dev, msix_table_offset_reg(pos), + &table_offset); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); + + map_irq.table_base = pci_resource_start(dev, bir); + map_irq.entry_nr = msidesc->msi_attrib.entry_nr; + } + + spin_lock(&irq_mapping_update_lock); + + irq = find_unbound_irq(); + + if (irq == -1) + goto out; + + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); + if (rc) { + printk(KERN_WARNING "xen map irq failed %d\n", rc); + + dynamic_irq_cleanup(irq); + + irq = -1; + goto out; + } + irq_info[irq] = mk_pirq_info(0, map_irq.pirq, 0, map_irq.index); + + set_irq_chip_and_handler_name(irq, &xen_pirq_chip, + handle_level_irq, + (type == PCI_CAP_ID_MSIX) ? "msi-x":"msi"); + +out: + spin_unlock(&irq_mapping_update_lock); + return irq; +} +#endif + int xen_destroy_irq(int irq) { struct irq_desc *desc; diff --git a/include/xen/events.h b/include/xen/events.h index 0c58db6..8fa27dc 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -72,8 +72,12 @@ void xen_hvm_evtchn_do_upcall(void); * usual. */ int xen_allocate_pirq(unsigned gsi, int shareable, char *name); int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); + +#ifdef CONFIG_PCI_MSI /* Allocate an irq and a pirq to be used with MSIs. */ void xen_allocate_pirq_msi(char *name, int *irq, int *pirq); +int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); +#endif /* De-allocates the above mentioned physical interrupt. */ int xen_destroy_irq(int irq); -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 04/10] xen: map a dummy page for local apic and ioapic in xen_set_fixmap
From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- arch/x86/xen/mmu.c | 23 ++++++++++++++++++++--- 1 files changed, 20 insertions(+), 3 deletions(-) diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 42086ac..ffc5e24 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1861,6 +1861,8 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, } #endif /* CONFIG_X86_64 */ +static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss; + static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) { pte_t pte; @@ -1881,15 +1883,28 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) #else case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE: #endif -#ifdef CONFIG_X86_LOCAL_APIC - case FIX_APIC_BASE: /* maps dummy local APIC */ -#endif case FIX_TEXT_POKE0: case FIX_TEXT_POKE1: /* All local page mappings */ pte = pfn_pte(phys, prot); break; +#ifdef CONFIG_X86_LOCAL_APIC + case FIX_APIC_BASE: /* maps dummy local APIC */ + pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL); + break; +#endif + +#ifdef CONFIG_X86_IO_APIC + case FIX_IO_APIC_BASE_0 ... FIX_IO_APIC_BASE_END: + /* + * We just don''t map the IO APIC - all access is via + * hypercalls. Keep the address in the pte for reference. + */ + pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL); + break; +#endif + case FIX_PARAVIRT_BOOTMAP: /* This is an MFN, but it isn''t an IO mapping from the IO domain */ @@ -2027,6 +2042,8 @@ void __init xen_init_mmu_ops(void) pv_mmu_ops = xen_mmu_ops; vmap_lazy_unmap = false; + + memset(dummy_mapping, 0xff, PAGE_SIZE); } /* Protected by xen_reservation_lock. */ -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 05/10] xen: use vcpu_ops to setup cpu masks
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- arch/x86/xen/smp.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 25f232b..1386767 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -156,11 +156,16 @@ static void __init xen_fill_possible_map(void) { int i, rc; + num_processors = 0; + disabled_cpus = 0; for (i = 0; i < nr_cpu_ids; i++) { rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); if (rc >= 0) { num_processors++; set_cpu_possible(i, true); + } else { + set_cpu_possible(i, false); + set_cpu_present(i, false); } } } @@ -190,6 +195,8 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus) if (xen_smp_intr_init(0)) BUG(); + xen_fill_possible_map(); + if (!alloc_cpumask_var(&xen_cpu_initialized_map, GFP_KERNEL)) panic("could not allocate xen_cpu_initialized_map\n"); @@ -480,6 +487,5 @@ static const struct smp_ops xen_smp_ops __initdata = { void __init xen_smp_init(void) { smp_ops = xen_smp_ops; - xen_fill_possible_map(); xen_init_spinlocks(); } -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 06/10] xen: Initialize xenbus for dom0.
From: Juan Quintela <quintela@redhat.com> Do initial xenbus/xenstore setup in dom0. In dom0 we need to actually allocate the xenstore resources, rather than being given them from outside. [ Impact: initialize Xenbus ] Signed-off-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- drivers/xen/xenbus/xenbus_probe.c | 29 ++++++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletions(-) diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 29bac51..df0049e 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -798,6 +798,7 @@ device_initcall(xenbus_probe_initcall); static int __init xenbus_init(void) { int err = 0; + unsigned long page = 0; DPRINTK(""); @@ -818,7 +819,31 @@ static int __init xenbus_init(void) * Domain0 doesn''t have a store_evtchn or store_mfn yet. */ if (xen_initial_domain()) { - /* dom0 not yet supported */ + struct evtchn_alloc_unbound alloc_unbound; + + /* Allocate Xenstore page */ + page = get_zeroed_page(GFP_KERNEL); + if (!page) + goto out_error; + + xen_store_mfn = xen_start_info->store_mfn + pfn_to_mfn(virt_to_phys((void *)page) >> + PAGE_SHIFT); + + /* Next allocate a local port which xenstored can bind to */ + alloc_unbound.dom = DOMID_SELF; + alloc_unbound.remote_dom = 0; + + err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, + &alloc_unbound); + if (err == -ENOSYS) + goto out_error; + + BUG_ON(err); + xen_store_evtchn = xen_start_info->store_evtchn + alloc_unbound.port; + + xen_store_interface = mfn_to_virt(xen_store_mfn); } else { if (xen_hvm_domain()) { uint64_t v = 0; @@ -864,6 +889,8 @@ static int __init xenbus_init(void) bus_unregister(&xenbus_frontend.bus); out_error: + if (page != 0) + free_page(page); return err; } -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 07/10] xen: add the direct mapping area for ISA bus access
From: Juan Quintela <quintela@redhat.com> add the direct mapping area for ISA bus access when running as initial domain Signed-off-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- arch/x86/xen/enlighten.c | 1 + arch/x86/xen/mmu.c | 24 ++++++++++++++++++++++++ arch/x86/xen/setup.c | 3 +++ 3 files changed, 28 insertions(+), 0 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 1ccfa1b..9efb004 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1186,6 +1186,7 @@ asmlinkage void __init xen_start_kernel(void) xen_raw_console_write("mapping kernel into physical memory\n"); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); + xen_ident_map_ISA(); init_mm.pgd = pgd; diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index ffc5e24..eed9c7c 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1682,6 +1682,7 @@ static void *m2v(phys_addr_t maddr) return __ka(m2p(maddr)); } +/* Set the page permissions on an identity-mapped pages */ static void set_page_prot(void *addr, pgprot_t prot) { unsigned long pfn = __pa(addr) >> PAGE_SHIFT; @@ -1929,6 +1930,29 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) #endif } +__init void xen_ident_map_ISA(void) +{ + unsigned long pa; + + /* + * If we''re dom0, then linear map the ISA machine addresses into + * the kernel''s address space. + */ + if (!xen_initial_domain()) + return; + + xen_raw_printk("Xen: setup ISA identity maps\n"); + + for (pa = ISA_START_ADDRESS; pa < ISA_END_ADDRESS; pa += PAGE_SIZE) { + pte_t pte = mfn_pte(PFN_DOWN(pa), PAGE_KERNEL_IO); + + if (HYPERVISOR_update_va_mapping(PAGE_OFFSET + pa, pte, 0)) + BUG(); + } + + xen_flush_tlb(); +} + static __init void xen_post_allocator_init(void) { pv_mmu_ops.set_pte = xen_set_pte; diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index c413132..62ceb78 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -119,6 +119,9 @@ char * __init xen_memory_setup(void) * Even though this is normal, usable memory under Xen, reserve * ISA memory anyway because too many things think they can poke * about in there. + * + * In a dom0 kernel, this region is identity mapped with the + * hardware ISA area, so it really is out of bounds. */ e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_RESERVED); -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 08/10] xen: use host E820 map for dom0
From: Ian Campbell <ian.campbell@citrix.com> When running as initial domain, get the real physical memory map from xen using the XENMEM_machine_memory_map hypercall and use it to setup the e820 regions. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- arch/x86/xen/setup.c | 43 +++++++++++++++++++++++++++++++++++++-- include/xen/interface/memory.h | 28 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 62ceb78..b08aac2 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -107,14 +107,51 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, char * __init xen_memory_setup(void) { + static __initdata struct e820entry map[E820MAX]; + unsigned long max_pfn = xen_start_info->nr_pages; + struct xen_memory_map memmap; + unsigned long long mem_end; + int op; + int rc; + int i; max_pfn = min(MAX_DOMAIN_PAGES, max_pfn); + mem_end = PFN_PHYS((u64)max_pfn); + + memmap.nr_entries = E820MAX; + set_xen_guest_handle(memmap.buffer, map); + + op = xen_initial_domain() ? + XENMEM_machine_memory_map : + XENMEM_memory_map; + rc = HYPERVISOR_memory_op(op, &memmap); + if (rc == -ENOSYS) { + memmap.nr_entries = 1; + map[0].addr = 0ULL; + map[0].size = mem_end; + /* 8MB slack (to balance backend allocations). */ + map[0].size += 8ULL << 20; + map[0].type = E820_RAM; + rc = 0; + } + BUG_ON(rc); e820.nr_map = 0; - - e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM); - + for (i = 0; i < memmap.nr_entries; i++) { + unsigned long long end = map[i].addr + map[i].size; + if (map[i].type == E820_RAM) { + if (map[i].addr > mem_end) + continue; + if (end > mem_end) { + /* Truncate region to max_mem. */ + map[i].size -= end - mem_end; + } + } + if (map[i].size > 0) + e820_add_region(map[i].addr, map[i].size, map[i].type); + } + /* * Even though this is normal, usable memory under Xen, reserve * ISA memory anyway because too many things think they can poke diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h index d3938d3..4c4b817 100644 --- a/include/xen/interface/memory.h +++ b/include/xen/interface/memory.h @@ -186,6 +186,34 @@ struct xen_translate_gpfn_list { }; DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list); +/* + * Returns the pseudo-physical memory map as it was when the domain + * was started (specified by XENMEM_set_memory_map). + * arg == addr of struct xen_memory_map. + */ +#define XENMEM_memory_map 9 +struct xen_memory_map { + /* + * On call the number of entries which can be stored in buffer. On + * return the number of entries which have been stored in + * buffer. + */ + unsigned int nr_entries; + + /* + * Entries in the buffer are in the same format as returned by the + * BIOS INT 0x15 EAX=0xE820 call. + */ + GUEST_HANDLE(void) buffer; +}; +DEFINE_GUEST_HANDLE_STRUCT(xen_memory_map); + +/* + * Returns the real physical memory map. Passes the same structure as + * XENMEM_memory_map. + * arg == addr of struct xen_memory_map. + */ +#define XENMEM_machine_memory_map 10 /* * Prevent the balloon driver from changing the memory reservation -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 09/10] xen: make hvc_xen console work for dom0.
From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Use the console hypercalls for dom0 console. [ Impact: Add Xen dom0 console ] Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- drivers/char/hvc_xen.c | 98 ++++++++++++++++++++++++++++++++---------------- drivers/xen/events.c | 2 +- include/xen/events.h | 1 + 3 files changed, 67 insertions(+), 34 deletions(-) diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index 60446f8..1f7e13a 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c @@ -78,7 +78,7 @@ static int __write_console(const char *data, int len) return sent; } -static int write_console(uint32_t vtermno, const char *data, int len) +static int domU_write_console(uint32_t vtermno, const char *data, int len) { int ret = len; @@ -101,7 +101,7 @@ static int write_console(uint32_t vtermno, const char *data, int len) return ret; } -static int read_console(uint32_t vtermno, char *buf, int len) +static int domU_read_console(uint32_t vtermno, char *buf, int len) { struct xencons_interface *intf = xencons_interface(); XENCONS_RING_IDX cons, prod; @@ -122,28 +122,62 @@ static int read_console(uint32_t vtermno, char *buf, int len) return recv; } -static const struct hv_ops hvc_ops = { - .get_chars = read_console, - .put_chars = write_console, +static struct hv_ops domU_hvc_ops = { + .get_chars = domU_read_console, + .put_chars = domU_write_console, .notifier_add = notifier_add_irq, .notifier_del = notifier_del_irq, .notifier_hangup = notifier_hangup_irq, }; -static int __init xen_init(void) +static int dom0_read_console(uint32_t vtermno, char *buf, int len) +{ + return HYPERVISOR_console_io(CONSOLEIO_read, len, buf); +} + +/* + * Either for a dom0 to write to the system console, or a domU with a + * debug version of Xen + */ +static int dom0_write_console(uint32_t vtermno, const char *str, int len) +{ + int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str); + if (rc < 0) + return 0; + + return len; +} + +static struct hv_ops dom0_hvc_ops = { + .get_chars = dom0_read_console, + .put_chars = dom0_write_console, + .notifier_add = notifier_add_irq, + .notifier_del = notifier_del_irq, + .notifier_hangup = notifier_hangup_irq, +}; + +static int __init xen_hvc_init(void) { struct hvc_struct *hp; + struct hv_ops *ops; - if (!xen_pv_domain() || - xen_initial_domain() || - !xen_start_info->console.domU.evtchn) + if (!xen_pv_domain()) return -ENODEV; - xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); + if (xen_initial_domain()) { + ops = &dom0_hvc_ops; + xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); + } else { + if (!xen_start_info->console.domU.evtchn) + return -ENODEV; + + ops = &domU_hvc_ops; + xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); + } if (xencons_irq < 0) xencons_irq = 0; /* NO_IRQ */ - hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256); + hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256); if (IS_ERR(hp)) return PTR_ERR(hp); @@ -160,7 +194,7 @@ void xen_console_resume(void) rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq); } -static void __exit xen_fini(void) +static void __exit xen_hvc_fini(void) { if (hvc) hvc_remove(hvc); @@ -168,29 +202,24 @@ static void __exit xen_fini(void) static int xen_cons_init(void) { + struct hv_ops *ops; + if (!xen_pv_domain()) return 0; - hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); + if (xen_initial_domain()) + ops = &dom0_hvc_ops; + else + ops = &domU_hvc_ops; + + hvc_instantiate(HVC_COOKIE, 0, ops); return 0; } -module_init(xen_init); -module_exit(xen_fini); +module_init(xen_hvc_init); +module_exit(xen_hvc_fini); console_initcall(xen_cons_init); -static void raw_console_write(const char *str, int len) -{ - while(len > 0) { - int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str); - if (rc <= 0) - break; - - str += rc; - len -= rc; - } -} - #ifdef CONFIG_EARLY_PRINTK static void xenboot_write_console(struct console *console, const char *string, unsigned len) @@ -198,19 +227,22 @@ static void xenboot_write_console(struct console *console, const char *string, unsigned int linelen, off = 0; const char *pos; - raw_console_write(string, len); + dom0_write_console(0, string, len); + + if (xen_initial_domain()) + return; - write_console(0, "(early) ", 8); + domU_write_console(0, "(early) ", 8); while (off < len && NULL != (pos = strchr(string+off, ''\n''))) { linelen = pos-string+off; if (off + linelen > len) break; - write_console(0, string+off, linelen); - write_console(0, "\r\n", 2); + domU_write_console(0, string+off, linelen); + domU_write_console(0, "\r\n", 2); off += linelen + 1; } if (off < len) - write_console(0, string+off, len-off); + domU_write_console(0, string+off, len-off); } struct console xenboot_console = { @@ -222,7 +254,7 @@ struct console xenboot_console = { void xen_raw_console_write(const char *str) { - raw_console_write(str, strlen(str)); + dom0_write_console(0, str, strlen(str)); } void xen_raw_printk(const char *fmt, ...) diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 9cdc5df..1cfc3a6 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -841,7 +841,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) } -static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) +int bind_virq_to_irq(unsigned int virq, unsigned int cpu) { struct evtchn_bind_virq bind_virq; int evtchn, irq; diff --git a/include/xen/events.h b/include/xen/events.h index 8fa27dc..646dd17 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -12,6 +12,7 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id); +int bind_virq_to_irq(unsigned int virq, unsigned int cpu); int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, irq_handler_t handler, unsigned long irqflags, const char *devname, -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-12 16:42 UTC
[Xen-devel] [PATCH v3 10/10] xen: mask the MTRR feature from the cpuid
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> We don''t want Linux to think that the cpu supports MTRRs when running under Xen because MTRR operations could only be performed through hypercalls. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- arch/x86/xen/enlighten.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 9efb004..d48a32b 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -243,6 +243,7 @@ static __init void xen_init_cpuid_mask(void) cpuid_leaf1_edx_mask ~((1 << X86_FEATURE_MCE) | /* disable MCE */ (1 << X86_FEATURE_MCA) | /* disable MCA */ + (1 << X86_FEATURE_MTRR) | /* disable MTRR */ (1 << X86_FEATURE_ACC)); /* thermal monitoring */ if (!xen_initial_domain()) -- 1.5.6.5 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Konrad Rzeszutek Wilk
2010-Oct-18 15:41 UTC
[Xen-devel] Re: [PATCH v3 02/10] xen: remap GSIs as pirqs when running as initial domain
On Tue, Oct 12, 2010 at 05:42:42PM +0100, Stefano Stabellini wrote:> From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > > Implement xen_register_gsi to setup the correct triggering and polarity > properties of a gsi. > Implement xen_register_pirq to register a particular gsi as pirq and > receive interrupts as events. > Call xen_setup_pirqs to register all the legacy ISA irqs as pirqs. > > Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > --- > arch/x86/include/asm/xen/pci.h | 7 ++ > arch/x86/pci/xen.c | 132 +++++++++++++++++++++++++++++++++++++++ > drivers/xen/events.c | 13 ++++ > include/xen/interface/physdev.h | 10 +++ > 4 files changed, 162 insertions(+), 0 deletions(-) > > diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h > index f89a42a..2329b3e 100644 > --- a/arch/x86/include/asm/xen/pci.h > +++ b/arch/x86/include/asm/xen/pci.h > @@ -13,6 +13,13 @@ static inline int pci_xen_hvm_init(void) > return -1; > } > #endif > +#if defined(CONFIG_XEN_DOM0) > +void __init xen_setup_pirqs(void); > +#else > +static inline void __init xen_setup_pirqs(void) > +{ > +} > +#endif > > #if defined(CONFIG_PCI_MSI) > #if defined(CONFIG_PCI_XEN) > diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c > index fb20d05..5d87774 100644 > --- a/arch/x86/pci/xen.c > +++ b/arch/x86/pci/xen.c > @@ -262,3 +262,135 @@ int __init pci_xen_hvm_init(void) > #endif > return 0; > } > + > +#ifdef CONFIG_XEN_DOM0 > +static int xen_register_pirq(u32 gsi, int triggering) > +{ > + int rc, irq; > + struct physdev_map_pirq map_irq; > + int shareable = 0; > + char *name; > + > + if (!xen_pv_domain()) > + return -1; > + > + if (triggering == ACPI_EDGE_SENSITIVE) { > + shareable = 0; > + name = "ioapic-edge"; > + } else { > + shareable = 1; > + name = "ioapic-level"; > + } > + > + irq = xen_allocate_pirq(gsi, shareable, name); > + > + printk(KERN_DEBUG "xen: --> irq=%d\n", irq); > + > + if (irq < 0) > + goto out; > + > + map_irq.domid = DOMID_SELF; > + map_irq.type = MAP_PIRQ_TYPE_GSI; > + map_irq.index = gsi; > + map_irq.pirq = irq; > + > + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); > + if (rc) { > + printk(KERN_WARNING "xen map irq failed %d\n", rc); > + return -1; > + } > + > +out: > + return irq; > +} > + > +static int xen_register_gsi(u32 gsi, int triggering, int polarity) > +{ > + int rc, irq; > + struct physdev_setup_gsi setup_gsi; > + > + if (!xen_pv_domain()) > + return -1; > + > + printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", > + gsi, triggering, polarity); > + > + irq = xen_register_pirq(gsi, triggering); > + > + setup_gsi.gsi = gsi; > + setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); > + setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1); > + > + rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi); > + if (rc == -EEXIST) > + printk(KERN_INFO "Already setup the GSI :%d\n", gsi); > + else if (rc) { > + printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n", > + gsi, rc); > + } > + > + return irq; > +} > + > +static __init void xen_setup_acpi_sci(void) > +{ > + int rc; > + int trigger, polarity; > + int gsi = acpi_sci_override_gsi; > + > + if (!gsi) > + return;Should this be ''if (gsi >= 0)'' ? I haven''t seen any machine with the GSI at IRQ 0, but perhaps it would be possible?> + > + rc = acpi_get_override_irq(gsi, &trigger, &polarity); > + if (rc) > + return;We don''t want to report the error? Say a printk?> + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; > + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; > + > + printk("xen: sci override: global_irq=%d trigger=%d polarity=%d\n", > + gsi, trigger, polarity); > + > + gsi = xen_register_gsi(gsi, trigger, polarity); > + printk("xen: acpi sci %d\n", gsi);KERN_INFO ?> + > + return; > +} > + > +static int acpi_register_gsi_xen(struct device *dev, u32 gsi, > + int trigger, int polarity) > +{ > + return xen_register_gsi(gsi, trigger, polarity); > +} > + > +static int __init pci_xen_initial_domain(void) > +{ > + xen_setup_acpi_sci(); > + __acpi_register_gsi = acpi_register_gsi_xen; > + > + return 0; > +} > + > +void __init xen_setup_pirqs(void) > +{ > + int irq; > + > + pci_xen_initial_domain(); > + > + if (0 == nr_ioapics) {This function is only called for the Dom0 case, so under what conditions would we have a machine with zero IO APICs? And do we actually support machines with no IO APICs? (would Xen run under such ancient hardware?)> + for (irq = 0; irq < NR_IRQS_LEGACY; irq++) > + xen_allocate_pirq(irq, 0, "xt-pic"); > + return; > + } > +_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Konrad Rzeszutek Wilk
2010-Oct-18 15:46 UTC
[Xen-devel] Re: [PATCH v3 03/10] xen: remap MSIs into pirqs when running as initial domain
> +int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) > +{ > + int irq = 0;Lets make the default one -1, as that is the value we are checking for errors later on.> + struct physdev_map_pirq map_irq; > + int rc; > + int pos; > + u32 table_offset, bir; > + > + memset(&map_irq, 0, sizeof(map_irq)); > + map_irq.domid = DOMID_SELF; > + map_irq.type = MAP_PIRQ_TYPE_MSI; > + map_irq.index = -1; > + map_irq.pirq = -1; > + map_irq.bus = dev->bus->number; > + map_irq.devfn = dev->devfn; > + > + if (type == PCI_CAP_ID_MSIX) { > + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); > + > + pci_read_config_dword(dev, msix_table_offset_reg(pos), > + &table_offset); > + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); > + > + map_irq.table_base = pci_resource_start(dev, bir); > + map_irq.entry_nr = msidesc->msi_attrib.entry_nr; > + } > + > + spin_lock(&irq_mapping_update_lock); > + > + irq = find_unbound_irq(); > + > + if (irq == -1) > + goto out; > + > + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); > + if (rc) { > + printk(KERN_WARNING "xen map irq failed %d\n", rc); > + > + dynamic_irq_cleanup(irq); > + > + irq = -1; > + goto out; > + } > + irq_info[irq] = mk_pirq_info(0, map_irq.pirq, 0, map_irq.index); > + > + set_irq_chip_and_handler_name(irq, &xen_pirq_chip, > + handle_level_irq, > + (type == PCI_CAP_ID_MSIX) ? "msi-x":"msi"); > + > +out: > + spin_unlock(&irq_mapping_update_lock); > + return irq; > +} > +#endif > + > int xen_destroy_irq(int irq) > { > struct irq_desc *desc; > diff --git a/include/xen/events.h b/include/xen/events.h > index 0c58db6..8fa27dc 100644 > --- a/include/xen/events.h > +++ b/include/xen/events.h > @@ -72,8 +72,12 @@ void xen_hvm_evtchn_do_upcall(void); > * usual. */ > int xen_allocate_pirq(unsigned gsi, int shareable, char *name); > int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); > + > +#ifdef CONFIG_PCI_MSI > /* Allocate an irq and a pirq to be used with MSIs. */ > void xen_allocate_pirq_msi(char *name, int *irq, int *pirq); > +int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); > +#endif > > /* De-allocates the above mentioned physical interrupt. */ > int xen_destroy_irq(int irq); > -- > 1.5.6.5_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Konrad Rzeszutek Wilk
2010-Oct-18 15:54 UTC
[Xen-devel] Re: [PATCH v3 08/10] xen: use host E820 map for dom0
On Tue, Oct 12, 2010 at 05:42:48PM +0100, Stefano Stabellini wrote:> From: Ian Campbell <ian.campbell@citrix.com> > > When running as initial domain, get the real physical memory map from > xen using the XENMEM_machine_memory_map hypercall and use it to setup > the e820 regions. > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com> > Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > --- > arch/x86/xen/setup.c | 43 +++++++++++++++++++++++++++++++++++++-- > include/xen/interface/memory.h | 28 ++++++++++++++++++++++++++ > 2 files changed, 68 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c > index 62ceb78..b08aac2 100644 > --- a/arch/x86/xen/setup.c > +++ b/arch/x86/xen/setup.c > @@ -107,14 +107,51 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, > > char * __init xen_memory_setup(void) > { > + static __initdata struct e820entry map[E820MAX]; > + > unsigned long max_pfn = xen_start_info->nr_pages; > + struct xen_memory_map memmap; > + unsigned long long mem_end; > + int op; > + int rc; > + int i; > > max_pfn = min(MAX_DOMAIN_PAGES, max_pfn); > + mem_end = PFN_PHYS((u64)max_pfn); > + > + memmap.nr_entries = E820MAX; > + set_xen_guest_handle(memmap.buffer, map); > + > + op = xen_initial_domain() ? > + XENMEM_machine_memory_map : > + XENMEM_memory_map; > + rc = HYPERVISOR_memory_op(op, &memmap); > + if (rc == -ENOSYS) { > + memmap.nr_entries = 1; > + map[0].addr = 0ULL; > + map[0].size = mem_end; > + /* 8MB slack (to balance backend allocations). */ > + map[0].size += 8ULL << 20; > + map[0].type = E820_RAM; > + rc = 0; > + } > + BUG_ON(rc); > > e820.nr_map = 0; > - > - e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM); > - > + for (i = 0; i < memmap.nr_entries; i++) { > + unsigned long long end = map[i].addr + map[i].size; > + if (map[i].type == E820_RAM) { > + if (map[i].addr > mem_end) > + continue;Would it make sense to print out a message saying something to the effect of: "You need to increase the CONFIG_XEN_MAX_DOMAIN_MEMORY value to take advantage of the extra %d gobs of memory!\n", map[i].size Or will this be unneccessary with the later changes that Jeremy has for the balloon work?> + if (end > mem_end) { > + /* Truncate region to max_mem. */ > + map[i].size -= end - mem_end; > + } > + } > + if (map[i].size > 0) > + e820_add_region(map[i].addr, map[i].size, map[i].type); > + } > + > /* > * Even though this is normal, usable memory under Xen, reserve > * ISA memory anyway because too many things think they can poke > diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h > index d3938d3..4c4b817 100644 > --- a/include/xen/interface/memory.h > +++ b/include/xen/interface/memory.h > @@ -186,6 +186,34 @@ struct xen_translate_gpfn_list { > }; > DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list); > > +/* > + * Returns the pseudo-physical memory map as it was when the domain > + * was started (specified by XENMEM_set_memory_map). > + * arg == addr of struct xen_memory_map. > + */ > +#define XENMEM_memory_map 9 > +struct xen_memory_map { > + /* > + * On call the number of entries which can be stored in buffer. On > + * return the number of entries which have been stored in > + * buffer. > + */ > + unsigned int nr_entries; > + > + /* > + * Entries in the buffer are in the same format as returned by the > + * BIOS INT 0x15 EAX=0xE820 call. > + */ > + GUEST_HANDLE(void) buffer; > +}; > +DEFINE_GUEST_HANDLE_STRUCT(xen_memory_map); > + > +/* > + * Returns the real physical memory map. Passes the same structure as > + * XENMEM_memory_map. > + * arg == addr of struct xen_memory_map. > + */ > +#define XENMEM_machine_memory_map 10 > > /* > * Prevent the balloon driver from changing the memory reservation > -- > 1.5.6.5_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-19 10:41 UTC
[Xen-devel] Re: [PATCH v3 02/10] xen: remap GSIs as pirqs when running as initial domain
On Mon, 18 Oct 2010, Konrad Rzeszutek Wilk wrote:> On Tue, Oct 12, 2010 at 05:42:42PM +0100, Stefano Stabellini wrote: > > From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > > > > Implement xen_register_gsi to setup the correct triggering and polarity > > properties of a gsi. > > Implement xen_register_pirq to register a particular gsi as pirq and > > receive interrupts as events. > > Call xen_setup_pirqs to register all the legacy ISA irqs as pirqs. > > > > Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > > --- > > arch/x86/include/asm/xen/pci.h | 7 ++ > > arch/x86/pci/xen.c | 132 +++++++++++++++++++++++++++++++++++++++ > > drivers/xen/events.c | 13 ++++ > > include/xen/interface/physdev.h | 10 +++ > > 4 files changed, 162 insertions(+), 0 deletions(-) > > > > diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h > > index f89a42a..2329b3e 100644 > > --- a/arch/x86/include/asm/xen/pci.h > > +++ b/arch/x86/include/asm/xen/pci.h > > @@ -13,6 +13,13 @@ static inline int pci_xen_hvm_init(void) > > return -1; > > } > > #endif > > +#if defined(CONFIG_XEN_DOM0) > > +void __init xen_setup_pirqs(void); > > +#else > > +static inline void __init xen_setup_pirqs(void) > > +{ > > +} > > +#endif > > > > #if defined(CONFIG_PCI_MSI) > > #if defined(CONFIG_PCI_XEN) > > diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c > > index fb20d05..5d87774 100644 > > --- a/arch/x86/pci/xen.c > > +++ b/arch/x86/pci/xen.c > > @@ -262,3 +262,135 @@ int __init pci_xen_hvm_init(void) > > #endif > > return 0; > > } > > + > > +#ifdef CONFIG_XEN_DOM0 > > +static int xen_register_pirq(u32 gsi, int triggering) > > +{ > > + int rc, irq; > > + struct physdev_map_pirq map_irq; > > + int shareable = 0; > > + char *name; > > + > > + if (!xen_pv_domain()) > > + return -1; > > + > > + if (triggering == ACPI_EDGE_SENSITIVE) { > > + shareable = 0; > > + name = "ioapic-edge"; > > + } else { > > + shareable = 1; > > + name = "ioapic-level"; > > + } > > + > > + irq = xen_allocate_pirq(gsi, shareable, name); > > + > > + printk(KERN_DEBUG "xen: --> irq=%d\n", irq); > > + > > + if (irq < 0) > > + goto out; > > + > > + map_irq.domid = DOMID_SELF; > > + map_irq.type = MAP_PIRQ_TYPE_GSI; > > + map_irq.index = gsi; > > + map_irq.pirq = irq; > > + > > + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); > > + if (rc) { > > + printk(KERN_WARNING "xen map irq failed %d\n", rc); > > + return -1; > > + } > > + > > +out: > > + return irq; > > +} > > + > > +static int xen_register_gsi(u32 gsi, int triggering, int polarity) > > +{ > > + int rc, irq; > > + struct physdev_setup_gsi setup_gsi; > > + > > + if (!xen_pv_domain()) > > + return -1; > > + > > + printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", > > + gsi, triggering, polarity); > > + > > + irq = xen_register_pirq(gsi, triggering); > > + > > + setup_gsi.gsi = gsi; > > + setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); > > + setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1); > > + > > + rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi); > > + if (rc == -EEXIST) > > + printk(KERN_INFO "Already setup the GSI :%d\n", gsi); > > + else if (rc) { > > + printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n", > > + gsi, rc); > > + } > > + > > + return irq; > > +} > > + > > +static __init void xen_setup_acpi_sci(void) > > +{ > > + int rc; > > + int trigger, polarity; > > + int gsi = acpi_sci_override_gsi; > > + > > + if (!gsi) > > + return; > > Should this be ''if (gsi >= 0)'' ? I haven''t seen any machine > with the GSI at IRQ 0, but perhaps it would be possible? >The test is correct as it is because it is meant to check if the acpi_sci_override_gsi has been set correctly and by default is 0. A similar test is done in arch/x86/kernel/acpi/boot.c:acpi_parse_madt_ioapic_entries.> > + > > + rc = acpi_get_override_irq(gsi, &trigger, &polarity); > > + if (rc) > > + return; > > We don''t want to report the error? Say a printk? >good idea, I''ll add one.> > + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; > > + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; > > + > > + printk("xen: sci override: global_irq=%d trigger=%d polarity=%d\n", > > + gsi, trigger, polarity); > > + > > + gsi = xen_register_gsi(gsi, trigger, polarity); > > + printk("xen: acpi sci %d\n", gsi); > > KERN_INFO ?ok> > + > > + return; > > +} > > + > > +static int acpi_register_gsi_xen(struct device *dev, u32 gsi, > > + int trigger, int polarity) > > +{ > > + return xen_register_gsi(gsi, trigger, polarity); > > +} > > + > > +static int __init pci_xen_initial_domain(void) > > +{ > > + xen_setup_acpi_sci(); > > + __acpi_register_gsi = acpi_register_gsi_xen; > > + > > + return 0; > > +} > > + > > +void __init xen_setup_pirqs(void) > > +{ > > + int irq; > > + > > + pci_xen_initial_domain(); > > + > > + if (0 == nr_ioapics) { > > This function is only called for the Dom0 case, so under > what conditions would we have a machine with zero IO APICs? > > And do we actually support machines with no IO APICs? > (would Xen run under such ancient hardware?)I don''t know about real hardware but during the development of the PV on HVM series I was able to boot a PV on HVM guest using the nr_ioapics==0 code path successfully several times. And you never know what the future may bring :) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-19 10:43 UTC
[Xen-devel] Re: [PATCH v3 03/10] xen: remap MSIs into pirqs when running as initial domain
On Mon, 18 Oct 2010, Konrad Rzeszutek Wilk wrote:> > +int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) > > +{ > > + int irq = 0; > > Lets make the default one -1, as that is the value we > are checking for errors later on.good idea _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2010-Oct-19 10:49 UTC
[Xen-devel] Re: [PATCH v3 08/10] xen: use host E820 map for dom0
On Mon, 18 Oct 2010, Konrad Rzeszutek Wilk wrote:> On Tue, Oct 12, 2010 at 05:42:48PM +0100, Stefano Stabellini wrote: > > From: Ian Campbell <ian.campbell@citrix.com> > > > > When running as initial domain, get the real physical memory map from > > xen using the XENMEM_machine_memory_map hypercall and use it to setup > > the e820 regions. > > > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com> > > Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > > --- > > arch/x86/xen/setup.c | 43 +++++++++++++++++++++++++++++++++++++-- > > include/xen/interface/memory.h | 28 ++++++++++++++++++++++++++ > > 2 files changed, 68 insertions(+), 3 deletions(-) > > > > diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c > > index 62ceb78..b08aac2 100644 > > --- a/arch/x86/xen/setup.c > > +++ b/arch/x86/xen/setup.c > > @@ -107,14 +107,51 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, > > > > char * __init xen_memory_setup(void) > > { > > + static __initdata struct e820entry map[E820MAX]; > > + > > unsigned long max_pfn = xen_start_info->nr_pages; > > + struct xen_memory_map memmap; > > + unsigned long long mem_end; > > + int op; > > + int rc; > > + int i; > > > > max_pfn = min(MAX_DOMAIN_PAGES, max_pfn); > > + mem_end = PFN_PHYS((u64)max_pfn); > > + > > + memmap.nr_entries = E820MAX; > > + set_xen_guest_handle(memmap.buffer, map); > > + > > + op = xen_initial_domain() ? > > + XENMEM_machine_memory_map : > > + XENMEM_memory_map; > > + rc = HYPERVISOR_memory_op(op, &memmap); > > + if (rc == -ENOSYS) { > > + memmap.nr_entries = 1; > > + map[0].addr = 0ULL; > > + map[0].size = mem_end; > > + /* 8MB slack (to balance backend allocations). */ > > + map[0].size += 8ULL << 20; > > + map[0].type = E820_RAM; > > + rc = 0; > > + } > > + BUG_ON(rc); > > > > e820.nr_map = 0; > > - > > - e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM); > > - > > + for (i = 0; i < memmap.nr_entries; i++) { > > + unsigned long long end = map[i].addr + map[i].size; > > + if (map[i].type == E820_RAM) { > > + if (map[i].addr > mem_end) > > + continue; > > Would it make sense to print out a message saying something to the > effect of: "You need to increase the CONFIG_XEN_MAX_DOMAIN_MEMORY value to > take advantage of the extra %d gobs of memory!\n", map[i].size > > Or will this be unneccessary with the later changes that Jeremy has > for the balloon work? >I think it still makes a lot of sense to print that message because ballooning might be disabled. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Konrad Rzeszutek Wilk
2010-Oct-19 15:48 UTC
Re: [Xen-devel] Re: [PATCH v3 02/10] xen: remap GSIs as pirqs when running as initial domain
On Tue, Oct 19, 2010 at 11:41:36AM +0100, Stefano Stabellini wrote:> On Mon, 18 Oct 2010, Konrad Rzeszutek Wilk wrote: > > On Tue, Oct 12, 2010 at 05:42:42PM +0100, Stefano Stabellini wrote: > > > From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > > > > > > Implement xen_register_gsi to setup the correct triggering and polarity > > > properties of a gsi. > > > Implement xen_register_pirq to register a particular gsi as pirq and > > > receive interrupts as events. > > > Call xen_setup_pirqs to register all the legacy ISA irqs as pirqs. > > > > > > Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > > > --- > > > arch/x86/include/asm/xen/pci.h | 7 ++ > > > arch/x86/pci/xen.c | 132 +++++++++++++++++++++++++++++++++++++++ > > > drivers/xen/events.c | 13 ++++ > > > include/xen/interface/physdev.h | 10 +++ > > > 4 files changed, 162 insertions(+), 0 deletions(-) > > > > > > diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h > > > index f89a42a..2329b3e 100644 > > > --- a/arch/x86/include/asm/xen/pci.h > > > +++ b/arch/x86/include/asm/xen/pci.h > > > @@ -13,6 +13,13 @@ static inline int pci_xen_hvm_init(void) > > > return -1; > > > } > > > #endif > > > +#if defined(CONFIG_XEN_DOM0) > > > +void __init xen_setup_pirqs(void); > > > +#else > > > +static inline void __init xen_setup_pirqs(void) > > > +{ > > > +} > > > +#endif > > > > > > #if defined(CONFIG_PCI_MSI) > > > #if defined(CONFIG_PCI_XEN) > > > diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c > > > index fb20d05..5d87774 100644 > > > --- a/arch/x86/pci/xen.c > > > +++ b/arch/x86/pci/xen.c > > > @@ -262,3 +262,135 @@ int __init pci_xen_hvm_init(void) > > > #endif > > > return 0; > > > } > > > + > > > +#ifdef CONFIG_XEN_DOM0 > > > +static int xen_register_pirq(u32 gsi, int triggering) > > > +{ > > > + int rc, irq; > > > + struct physdev_map_pirq map_irq; > > > + int shareable = 0; > > > + char *name; > > > + > > > + if (!xen_pv_domain()) > > > + return -1; > > > + > > > + if (triggering == ACPI_EDGE_SENSITIVE) { > > > + shareable = 0; > > > + name = "ioapic-edge"; > > > + } else { > > > + shareable = 1; > > > + name = "ioapic-level"; > > > + } > > > + > > > + irq = xen_allocate_pirq(gsi, shareable, name); > > > + > > > + printk(KERN_DEBUG "xen: --> irq=%d\n", irq); > > > + > > > + if (irq < 0) > > > + goto out; > > > + > > > + map_irq.domid = DOMID_SELF; > > > + map_irq.type = MAP_PIRQ_TYPE_GSI; > > > + map_irq.index = gsi; > > > + map_irq.pirq = irq; > > > + > > > + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); > > > + if (rc) { > > > + printk(KERN_WARNING "xen map irq failed %d\n", rc); > > > + return -1; > > > + } > > > + > > > +out: > > > + return irq; > > > +} > > > + > > > +static int xen_register_gsi(u32 gsi, int triggering, int polarity) > > > +{ > > > + int rc, irq; > > > + struct physdev_setup_gsi setup_gsi; > > > + > > > + if (!xen_pv_domain()) > > > + return -1; > > > + > > > + printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", > > > + gsi, triggering, polarity); > > > + > > > + irq = xen_register_pirq(gsi, triggering); > > > + > > > + setup_gsi.gsi = gsi; > > > + setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); > > > + setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1); > > > + > > > + rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi); > > > + if (rc == -EEXIST) > > > + printk(KERN_INFO "Already setup the GSI :%d\n", gsi); > > > + else if (rc) { > > > + printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n", > > > + gsi, rc); > > > + } > > > + > > > + return irq; > > > +} > > > + > > > +static __init void xen_setup_acpi_sci(void) > > > +{ > > > + int rc; > > > + int trigger, polarity; > > > + int gsi = acpi_sci_override_gsi; > > > + > > > + if (!gsi) > > > + return; > > > > Should this be ''if (gsi >= 0)'' ? I haven''t seen any machine > > with the GSI at IRQ 0, but perhaps it would be possible? > > > > The test is correct as it is because it is meant to check if the > acpi_sci_override_gsi has been set correctly and by default is 0. > A similar test is done in > arch/x86/kernel/acpi/boot.c:acpi_parse_madt_ioapic_entries.ok.> > > > > + > > > + rc = acpi_get_override_irq(gsi, &trigger, &polarity); > > > + if (rc) > > > + return; > > > > We don''t want to report the error? Say a printk? > > > > good idea, I''ll add one.Thank you.> > > > + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; > > > + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; > > > + > > > + printk("xen: sci override: global_irq=%d trigger=%d polarity=%d\n", > > > + gsi, trigger, polarity); > > > + > > > + gsi = xen_register_gsi(gsi, trigger, polarity); > > > + printk("xen: acpi sci %d\n", gsi); > > > > KERN_INFO ? > > okDanke.> > > > + > > > + return; > > > +} > > > + > > > +static int acpi_register_gsi_xen(struct device *dev, u32 gsi, > > > + int trigger, int polarity) > > > +{ > > > + return xen_register_gsi(gsi, trigger, polarity); > > > +} > > > + > > > +static int __init pci_xen_initial_domain(void) > > > +{ > > > + xen_setup_acpi_sci(); > > > + __acpi_register_gsi = acpi_register_gsi_xen; > > > + > > > + return 0; > > > +} > > > + > > > +void __init xen_setup_pirqs(void) > > > +{ > > > + int irq; > > > + > > > + pci_xen_initial_domain(); > > > + > > > + if (0 == nr_ioapics) { > > > > This function is only called for the Dom0 case, so under > > what conditions would we have a machine with zero IO APICs? > > > > And do we actually support machines with no IO APICs? > > (would Xen run under such ancient hardware?) > > I don''t know about real hardware but during the development of the PV on > HVM series I was able to boot a PV on HVM guest using the nr_ioapics==0 > code path successfully several times. > And you never know what the future may bring :)True. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2010-Oct-20 17:05 UTC
Re: [Xen-devel] Re: [PATCH v3 08/10] xen: use host E820 map for dom0
On 10/19/2010 03:49 AM, Stefano Stabellini wrote:>>> - e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM); >>> - >>> + for (i = 0; i < memmap.nr_entries; i++) { >>> + unsigned long long end = map[i].addr + map[i].size; >>> + if (map[i].type == E820_RAM) { >>> + if (map[i].addr > mem_end) >>> + continue; >> Would it make sense to print out a message saying something to the >> effect of: "You need to increase the CONFIG_XEN_MAX_DOMAIN_MEMORY value to >> take advantage of the extra %d gobs of memory!\n", map[i].size >> >> Or will this be unneccessary with the later changes that Jeremy has >> for the balloon work? >> > I think it still makes a lot of sense to print that message because > ballooning might be disabled.CONFIG_XEN_MAX_DOMAIN_MEMORY scales the max pfn in the p2m table, and it independent of whether ballooning is enabled. The presence or absence of ballooning will only affect whether memory between memory and maxmem can be made available. And it defaults 128G now anyway, so its very unlikely people will hit it by accident. Aside from that, I''m thinking of making ballooning mandatory (perhaps just a config option on the usermode-visible parts), since it seems so core (its mandatory for all the dom0/passthrough stuff anyway). J _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel