From starox at free.fr Tue Feb 1 00:11:44 2005 From: starox at free.fr (Frederic Leroy) Date: Mon, 31 Jan 2005 14:11:44 +0100 (CET) Subject: [minor] Apple Pmac G5 - ATA performance problem Message-ID: <20050131141146.69a0a9e5@miss> Hello, I put a harddrive and 'superdrive' on ATA bus on a PowerMac G5. It's works very fine but I notice the harddrive is going half speed. The harddrive and the optical drive are both in UltraDMA2. The Ata driver don't accept UltraDMA mode above 2. Here is results of Bonnie with a 2G test file on Linux and MacOSX : -------Sequential Output-------- ---Sequential Input-- --Random-- -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks--- Machine MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU /sec %CPU G5-linux 2000 23867 99.3 42912 9.3 13562 3.4 16871 67.3 23292 3.7 316.6 0.7 G5-macos 0 31504 99.1 54656 18.0 22615 13.7 34970 98.6 54632 23.9 224.4 3.3 -- Frederic Leroy Lost in Germany From greg at kroah.com Tue Feb 1 06:15:46 2005 From: greg at kroah.com (Greg KH) Date: Mon, 31 Jan 2005 11:15:46 -0800 Subject: pci: Arch hook to determine config space size In-Reply-To: <41FE82B6.9060407@us.ibm.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050128185234.GB21760@infradead.org> <20050129040647.GA6261@kroah.com> <41FE82B6.9060407@us.ibm.com> Message-ID: <20050131191546.GA22428@kroah.com> On Mon, Jan 31, 2005 at 01:10:46PM -0600, Brian King wrote: > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > + Kernel functions traditionally return 0 for success and -ESOMETHING for error. Care to fix this up to match that convention? thanks, greg k-h From brking at us.ibm.com Tue Feb 1 06:10:46 2005 From: brking at us.ibm.com (Brian King) Date: Mon, 31 Jan 2005 13:10:46 -0600 Subject: pci: Arch hook to determine config space size In-Reply-To: <20050129040647.GA6261@kroah.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050128185234.GB21760@infradead.org> <20050129040647.GA6261@kroah.com> Message-ID: <41FE82B6.9060407@us.ibm.com> Greg KH wrote: > On Fri, Jan 28, 2005 at 06:52:34PM +0000, Christoph Hellwig wrote: > >>>+int __attribute__ ((weak)) pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } >> >> - prototypes belong to headers >> - weak linkage is the perfect way for total obsfucation >> >>please make this a regular arch hook > > > I agree. Also, when sending PCI related patches, please cc the > linux-pci mailing list. How about this? -- Brian King eServer Storage I/O IBM Linux Technology Center -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: pci_get_cfg_size_all.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050131/374a0f61/attachment.txt From matthew at wil.cx Tue Feb 1 06:29:55 2005 From: matthew at wil.cx (Matthew Wilcox) Date: Mon, 31 Jan 2005 19:29:55 +0000 Subject: pci: Arch hook to determine config space size In-Reply-To: <41FE82B6.9060407@us.ibm.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050128185234.GB21760@infradead.org> <20050129040647.GA6261@kroah.com> <41FE82B6.9060407@us.ibm.com> Message-ID: <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> On Mon, Jan 31, 2005 at 01:10:46PM -0600, Brian King wrote: > Greg KH wrote: > >On Fri, Jan 28, 2005 at 06:52:34PM +0000, Christoph Hellwig wrote: > > > >>>+int __attribute__ ((weak)) pcibios_exp_cfg_space(struct pci_dev *dev) { > >>>return 1; } > >> > >>- prototypes belong to headers > >>- weak linkage is the perfect way for total obsfucation > >> > >>please make this a regular arch hook > > > > > >I agree. Also, when sending PCI related patches, please cc the > >linux-pci mailing list. > > How about this? Thanks for copying linux-pci. I hate this patch. Basically, ppc64's config ops are broken and need to check the offset being read. Here's i386: static int pci_conf1_write (int seg, int bus, int devfn, int reg, int len, u32 v alue) { unsigned long flags; if ((bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; I think all the config ops in ppc64 are broken and need to check for these limits. Also, it does some checks that are already performed by upper layers: if (where & (size - 1)) return PCIBIOS_BAD_REGISTER_NUMBER; is checked for in drivers/pci/access.c -- "Next the statesmen will invent cheap lies, putting the blame upon the nation that is attacked, and every man will be glad of those conscience-soothing falsities, and will diligently study them, and refuse to examine any refutations of them; and thus he will by and by convince himself that the war is just, and will thank God for the better sleep he enjoys after this process of grotesque self-deception." -- Mark Twain From brking at us.ibm.com Tue Feb 1 06:40:04 2005 From: brking at us.ibm.com (Brian King) Date: Mon, 31 Jan 2005 13:40:04 -0600 Subject: pci: Arch hook to determine config space size In-Reply-To: <41FE82B6.9060407@us.ibm.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050128185234.GB21760@infradead.org> <20050129040647.GA6261@kroah.com> <41FE82B6.9060407@us.ibm.com> Message-ID: <41FE8994.4040802@us.ibm.com> Brian King wrote: > Greg KH wrote: > >> On Fri, Jan 28, 2005 at 06:52:34PM +0000, Christoph Hellwig wrote: >> >>>> +int __attribute__ ((weak)) pcibios_exp_cfg_space(struct pci_dev >>>> *dev) { return 1; } >>> >>> >>> - prototypes belong to headers >>> - weak linkage is the perfect way for total obsfucation >>> >>> please make this a regular arch hook >> >> >> >> I agree. Also, when sending PCI related patches, please cc the >> linux-pci mailing list. CC'ing the linux-pci mailing list... -brian > How about this? > > > ------------------------------------------------------------------------ > > > When working with a PCI-X Mode 2 adapter on a PCI-X Mode 1 PPC64 > system, the current code used to determine the config space size > of a device results in a PCI Master abort and an EEH error, resulting > in the device being taken offline. This patch adds an arch hook so > that individual archs can indicate if the underlying system supports > expanded config space accesses or not. > > Signed-off-by: Brian King > --- > > linux-2.6.11-rc2-bk9-bjking1/arch/alpha/kernel/pci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/arm/kernel/bios32.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/frv/mb93090-mb00/pci-frv.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/i386/pci/common.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/ia64/pci/pci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/m68knommu/kernel/comempci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/mips/pci/pci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/mips/pmc-sierra/yosemite/ht.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/parisc/kernel/pci.c | 1 > linux-2.6.11-rc2-bk9-bjking1/arch/ppc/kernel/pci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/ppc64/kernel/iSeries_pci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/ppc64/kernel/pci.c | 18 ++++++++++ > linux-2.6.11-rc2-bk9-bjking1/arch/sh/boards/mpc1211/pci.c | 1 > linux-2.6.11-rc2-bk9-bjking1/arch/sh/boards/overdrive/galileo.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/sh/drivers/pci/pci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/sh64/kernel/pcibios.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/sparc/kernel/pcic.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/sparc64/kernel/pci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/arch/v850/kernel/rte_mb_a_pci.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/drivers/pci/probe.c | 2 + > linux-2.6.11-rc2-bk9-bjking1/include/linux/pci.h | 1 > 21 files changed, 55 insertions(+) > > diff -puN drivers/pci/probe.c~pci_get_cfg_size_all drivers/pci/probe.c > --- linux-2.6.11-rc2-bk9/drivers/pci/probe.c~pci_get_cfg_size_all 2005-01-31 11:16:22.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/drivers/pci/probe.c 2005-01-31 11:22:07.000000000 -0600 > @@ -653,6 +653,8 @@ static int pci_cfg_space_size(struct pci > goto fail; > } > > + if (!pcibios_exp_cfg_space(dev)) > + goto fail; > if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) > goto fail; > if (status == 0xffffffff) > diff -puN arch/alpha/kernel/pci.c~pci_get_cfg_size_all arch/alpha/kernel/pci.c > --- linux-2.6.11-rc2-bk9/arch/alpha/kernel/pci.c~pci_get_cfg_size_all 2005-01-31 11:16:33.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/alpha/kernel/pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -202,6 +202,8 @@ pcibios_setup(char *str) > return str; > } > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > + > #ifdef ALPHA_RESTORE_SRM_SETUP > static struct pdev_srm_saved_conf *srm_saved_configs; > > diff -puN arch/arm/kernel/bios32.c~pci_get_cfg_size_all arch/arm/kernel/bios32.c > --- linux-2.6.11-rc2-bk9/arch/arm/kernel/bios32.c~pci_get_cfg_size_all 2005-01-31 11:16:43.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/arm/kernel/bios32.c 2005-01-31 11:22:27.000000000 -0600 > @@ -67,6 +67,8 @@ void pcibios_report_status(u_int status_ > } > } > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > + > /* > * We don't use this to fix the device, but initialisation of it. > * It's not the correct use for this, but it works. > diff -puN arch/frv/mb93090-mb00/pci-frv.c~pci_get_cfg_size_all arch/frv/mb93090-mb00/pci-frv.c > --- linux-2.6.11-rc2-bk9/arch/frv/mb93090-mb00/pci-frv.c~pci_get_cfg_size_all 2005-01-31 11:16:55.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/frv/mb93090-mb00/pci-frv.c 2005-01-31 11:22:27.000000000 -0600 > @@ -286,3 +286,5 @@ void pcibios_set_master(struct pci_dev * > printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); > pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); > } > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/i386/pci/common.c~pci_get_cfg_size_all arch/i386/pci/common.c > --- linux-2.6.11-rc2-bk9/arch/i386/pci/common.c~pci_get_cfg_size_all 2005-01-31 11:17:01.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/i386/pci/common.c 2005-01-31 11:22:27.000000000 -0600 > @@ -249,3 +249,5 @@ int pcibios_enable_device(struct pci_dev > > return pcibios_enable_irq(dev); > } > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/ia64/pci/pci.c~pci_get_cfg_size_all arch/ia64/pci/pci.c > --- linux-2.6.11-rc2-bk9/arch/ia64/pci/pci.c~pci_get_cfg_size_all 2005-01-31 11:17:09.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/ia64/pci/pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -744,3 +744,5 @@ int pci_vector_resources(int last, int n > > return count; > } > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/m68knommu/kernel/comempci.c~pci_get_cfg_size_all arch/m68knommu/kernel/comempci.c > --- linux-2.6.11-rc2-bk9/arch/m68knommu/kernel/comempci.c~pci_get_cfg_size_all 2005-01-31 11:17:23.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/m68knommu/kernel/comempci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -987,3 +987,5 @@ void pci_free_consistent(struct pci_dev > } > > /*****************************************************************************/ > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/mips/pci/pci.c~pci_get_cfg_size_all arch/mips/pci/pci.c > --- linux-2.6.11-rc2-bk9/arch/mips/pci/pci.c~pci_get_cfg_size_all 2005-01-31 11:17:33.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/mips/pci/pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -300,3 +300,5 @@ char *pcibios_setup(char *str) > { > return str; > } > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/mips/pmc-sierra/yosemite/ht.c~pci_get_cfg_size_all arch/mips/pmc-sierra/yosemite/ht.c > --- linux-2.6.11-rc2-bk9/arch/mips/pmc-sierra/yosemite/ht.c~pci_get_cfg_size_all 2005-01-31 11:17:44.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/mips/pmc-sierra/yosemite/ht.c 2005-01-31 11:22:27.000000000 -0600 > @@ -451,4 +451,6 @@ unsigned __init int pcibios_assign_all_b > return 0; > } > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > + > #endif /* CONFIG_HYPERTRANSPORT */ > diff -puN arch/parisc/kernel/pci.c~pci_get_cfg_size_all arch/parisc/kernel/pci.c > --- linux-2.6.11-rc2-bk9/arch/parisc/kernel/pci.c~pci_get_cfg_size_all 2005-01-31 11:17:50.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/parisc/kernel/pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -330,6 +330,7 @@ int pcibios_enable_device(struct pci_dev > return 0; > } > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > > /* PA-RISC specific */ > void pcibios_register_hba(struct pci_hba_data *hba) > diff -puN arch/ppc/kernel/pci.c~pci_get_cfg_size_all arch/ppc/kernel/pci.c > --- linux-2.6.11-rc2-bk9/arch/ppc/kernel/pci.c~pci_get_cfg_size_all 2005-01-31 11:18:02.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/ppc/kernel/pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -1728,6 +1728,8 @@ void pci_iounmap(struct pci_dev *dev, vo > EXPORT_SYMBOL(pci_iomap); > EXPORT_SYMBOL(pci_iounmap); > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > + > /* > * Null PCI config access functions, for the case when we can't > * find a hose. > diff -puN arch/ppc64/kernel/iSeries_pci.c~pci_get_cfg_size_all arch/ppc64/kernel/iSeries_pci.c > --- linux-2.6.11-rc2-bk9/arch/ppc64/kernel/iSeries_pci.c~pci_get_cfg_size_all 2005-01-31 11:18:09.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/ppc64/kernel/iSeries_pci.c 2005-01-31 11:22:20.000000000 -0600 > @@ -348,6 +348,8 @@ void pcibios_fixup_resources(struct pci_ > PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev); > } > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 0; } > + > /* > * Loop through each node function to find usable EADs bridges. > */ > diff -puN arch/ppc64/kernel/pci.c~pci_get_cfg_size_all arch/ppc64/kernel/pci.c > --- linux-2.6.11-rc2-bk9/arch/ppc64/kernel/pci.c~pci_get_cfg_size_all 2005-01-31 11:18:13.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/ppc64/kernel/pci.c 2005-01-31 11:22:20.000000000 -0600 > @@ -467,6 +467,24 @@ void pcibios_add_platform_entries(struct > > #ifdef CONFIG_PPC_MULTIPLATFORM > > +int pcibios_exp_cfg_space(struct pci_dev *dev) > +{ > + int *type; > + struct device_node *dn; > + struct pci_controller *hose = pci_bus_to_host(dev->bus); > + > + if (!hose) > + return 0; > + > + dn = (struct device_node *) hose->arch_data; > + type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); > + > + if (type && *type == 1) > + return 1; > + > + return 0; > +} > + > #define ISA_SPACE_MASK 0x1 > #define ISA_SPACE_IO 0x1 > > diff -puN arch/sh/boards/mpc1211/pci.c~pci_get_cfg_size_all arch/sh/boards/mpc1211/pci.c > --- linux-2.6.11-rc2-bk9/arch/sh/boards/mpc1211/pci.c~pci_get_cfg_size_all 2005-01-31 11:18:24.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/sh/boards/mpc1211/pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -294,3 +294,4 @@ void pcibios_align_resource(void *data, > } > } > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/sh/boards/overdrive/galileo.c~pci_get_cfg_size_all arch/sh/boards/overdrive/galileo.c > --- linux-2.6.11-rc2-bk9/arch/sh/boards/overdrive/galileo.c~pci_get_cfg_size_all 2005-01-31 11:18:33.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/sh/boards/overdrive/galileo.c 2005-01-31 11:22:27.000000000 -0600 > @@ -586,3 +586,5 @@ void pcibios_set_master(struct pci_dev * > printk("PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); > pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); > } > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/sh/drivers/pci/pci.c~pci_get_cfg_size_all arch/sh/drivers/pci/pci.c > --- linux-2.6.11-rc2-bk9/arch/sh/drivers/pci/pci.c~pci_get_cfg_size_all 2005-01-31 11:18:49.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/sh/drivers/pci/pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -153,3 +153,5 @@ void __init pcibios_update_irq(struct pc > { > pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); > } > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/sh64/kernel/pcibios.c~pci_get_cfg_size_all arch/sh64/kernel/pcibios.c > --- linux-2.6.11-rc2-bk9/arch/sh64/kernel/pcibios.c~pci_get_cfg_size_all 2005-01-31 11:19:47.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/sh64/kernel/pcibios.c 2005-01-31 11:22:27.000000000 -0600 > @@ -166,3 +166,5 @@ void __init pcibios_update_irq(struct pc > { > pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); > } > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/sparc/kernel/pcic.c~pci_get_cfg_size_all arch/sparc/kernel/pcic.c > --- linux-2.6.11-rc2-bk9/arch/sparc/kernel/pcic.c~pci_get_cfg_size_all 2005-01-31 11:19:52.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/sparc/kernel/pcic.c 2005-01-31 11:22:27.000000000 -0600 > @@ -1033,3 +1033,5 @@ void insl(void * __iomem addr, void *dst > } > > subsys_initcall(pcic_init); > + > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > diff -puN arch/sparc64/kernel/pci.c~pci_get_cfg_size_all arch/sparc64/kernel/pci.c > --- linux-2.6.11-rc2-bk9/arch/sparc64/kernel/pci.c~pci_get_cfg_size_all 2005-01-31 11:20:02.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/sparc64/kernel/pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -809,4 +809,6 @@ int pcibios_prep_mwi(struct pci_dev *dev > return 0; > } > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > + > #endif /* !(CONFIG_PCI) */ > diff -puN arch/v850/kernel/rte_mb_a_pci.c~pci_get_cfg_size_all arch/v850/kernel/rte_mb_a_pci.c > --- linux-2.6.11-rc2-bk9/arch/v850/kernel/rte_mb_a_pci.c~pci_get_cfg_size_all 2005-01-31 11:20:15.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/arch/v850/kernel/rte_mb_a_pci.c 2005-01-31 11:22:27.000000000 -0600 > @@ -337,6 +337,8 @@ void pcibios_set_master (struct pci_dev > { > } > > +int pcibios_exp_cfg_space(struct pci_dev *dev) { return 1; } > + > > /* Mother-A SRAM memory allocation. This is a simple first-fit allocator. */ > > diff -puN include/linux/pci.h~pci_get_cfg_size_all include/linux/pci.h > --- linux-2.6.11-rc2-bk9/include/linux/pci.h~pci_get_cfg_size_all 2005-01-31 11:20:30.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/include/linux/pci.h 2005-01-31 11:22:07.000000000 -0600 > @@ -723,6 +723,7 @@ extern struct list_head pci_devices; /* > void pcibios_fixup_bus(struct pci_bus *); > int pcibios_enable_device(struct pci_dev *, int mask); > char *pcibios_setup (char *str); > +int pcibios_exp_cfg_space(struct pci_dev *dev); > > /* Used only when drivers/pci/setup.c is used */ > void pcibios_align_resource(void *, struct resource *, > _ -- Brian King eServer Storage I/O IBM Linux Technology Center From sam at ravnborg.org Tue Feb 1 06:27:13 2005 From: sam at ravnborg.org (Sam Ravnborg) Date: Mon, 31 Jan 2005 20:27:13 +0100 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline In-Reply-To: <1107151447.5712.81.camel@gaston> References: <1107151447.5712.81.camel@gaston> Message-ID: <20050131192713.GA16268@mars.ravnborg.org> > Index: linux-work/arch/ppc64/kernel/vdso32/Makefile > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ linux-work/arch/ppc64/kernel/vdso32/Makefile 2005-01-31 16:25:56.000000000 +1100 > @@ -0,0 +1,50 @@ > +# Choose compiler > +# > +# XXX FIXME: We probably want to enforce using a biarch compiler by default > +# and thus use (CC) with -m64, while letting the user pass a > +# CROSS32_COMPILE prefix if wanted. Same goes for the zImage > +# wrappers > +# > + > +CROSS32_COMPILE ?= > + > +CROSS32CC := $(CROSS32_COMPILE)gcc > +CROSS32AS := $(CROSS32_COMPILE)as This needs to go into arch/ppc64/Makefile > + > +# List of files in the vdso, has to be asm only for now > + > +src-vdso32 = sigtramp.S gettimeofday.S datapage.S cacheflush.S It is normal kbuild practice to list .o files. So it would be: obj-vdso32 := sigtramp.o gettimeofday.o datapage.o cacheflush.o targets := $(obj-vdso32) obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) One line saved compared to below (not counting the src-vdso32 assignment that is unused). Also notice that ':=' uses all over. No need to use late evaluation when no dynamic references are used ($ $@ etc.). > +# Build rules > + > +obj-vdso32 := $(addsuffix .o, $(basename $(src-vdso32))) > +targets := $(obj-vdso32) vdso32.so > +obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) > +src-vdso32 := $(addprefix $(src)/, $(src-vdso32)) Same comments to the vdso64/Makefile Sam From arnd at arndb.de Tue Feb 1 07:51:04 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Mon, 31 Jan 2005 21:51:04 +0100 Subject: pci: Arch hook to determine config space size In-Reply-To: <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <41FE82B6.9060407@us.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> Message-ID: <200501312151.05323.arnd@arndb.de> On Maandag 31 Januar 2005 20:29, Matthew Wilcox wrote: > Thanks for copying linux-pci. ?I hate this patch. > > Basically, ppc64's config ops are broken and need to check the offset > being read. To make things worse, simply allowing the larger config space will silently access the wrong device. The least that needs to be done is to pass the correct address to the firmware. This patch should do the right thing, though I don't have any PCIe card to test with. Note that at least for the rtas pci config access, the bus/devfn values come from the device tree, which makes it somewhat harder to screw them up, and rtas ought to check for obviously wrong addresses as well. Signed-off-by: Arnd Bergmann --- linux-mm.orig/arch/ppc64/kernel/pSeries_pci.c 2005-01-28 07:21:15.000000000 -0500 +++ linux-mm/arch/ppc64/kernel/pSeries_pci.c 2005-01-31 15:56:10.244983464 -0500 @@ -63,7 +63,8 @@ if (where & (size - 1)) return PCIBIOS_BAD_REGISTER_NUMBER; - addr = (dn->busno << 16) | (dn->devfn << 8) | where; + addr = ((where & 0xf00) << 20) | (dn->busno << 16) + | (dn->devfn << 8) | (where & 0x0ff); buid = dn->phb->buid; if (buid) { ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, @@ -111,7 +112,8 @@ if (where & (size - 1)) return PCIBIOS_BAD_REGISTER_NUMBER; - addr = (dn->busno << 16) | (dn->devfn << 8) | where; + addr = ((where & 0xf00) << 20) | (dn->busno << 16) + | (dn->devfn << 8) | (where & 0x0ff); buid = dn->phb->buid; if (buid) { ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050131/97d5360f/attachment.pgp From brking at us.ibm.com Tue Feb 1 08:35:38 2005 From: brking at us.ibm.com (Brian King) Date: Mon, 31 Jan 2005 15:35:38 -0600 Subject: pci: Arch hook to determine config space size In-Reply-To: <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050128185234.GB21760@infradead.org> <20050129040647.GA6261@kroah.com> <41FE82B6.9060407@us.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> Message-ID: <41FEA4AA.1080407@us.ibm.com> Matthew Wilcox wrote: > Basically, ppc64's config ops are broken and need to check the offset > being read. Here's i386: > > static int pci_conf1_write (int seg, int bus, int devfn, int reg, int len, u32 v > alue) > { > unsigned long flags; > > if ((bus > 255) || (devfn > 255) || (reg > 255)) > return -EINVAL; Here is a pure ppc64 implementation that does this. > > I think all the config ops in ppc64 are broken and need to check for these > limits. Also, it does some checks that are already performed by upper layers: > > if (where & (size - 1)) > return PCIBIOS_BAD_REGISTER_NUMBER; > > is checked for in drivers/pci/access.c I can submit a separate patch to clean that up. -- Brian King eServer Storage I/O IBM Linux Technology Center -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ppc64_pcix_mode2_cfg.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050131/6840b689/attachment.txt From arnd at arndb.de Tue Feb 1 08:56:44 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Mon, 31 Jan 2005 22:56:44 +0100 Subject: pci: Arch hook to determine config space size In-Reply-To: <41FEA4AA.1080407@us.ibm.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> <41FEA4AA.1080407@us.ibm.com> Message-ID: <200501312256.44692.arnd@arndb.de> On Maandag 31 Januar 2005 22:35, Brian King wrote: > Matthew Wilcox wrote: > > Basically, ppc64's config ops are broken and need to check the offset > > being read. ?Here's i386: > > > > static int pci_conf1_write (int seg, int bus, int devfn, int reg, int len, u32 v > > alue) > > { > > ? ? ? ? unsigned long flags; > > > > ? ? ? ? if ((bus > 255) || (devfn > 255) || (reg > 255)) > > ? ? ? ? ? ? ? ? return -EINVAL; > > Here is a pure ppc64 implementation that does this. Actually, it doesn't: > +static int config_access_valid(struct device_node *dn, int where) > +{ > +???????struct device_node *hose_dn = dn->phb->arch_data; > + > +???????if (where < 256 || hose_dn->pci_ext_config_space) > +???????????????return 1; This needs a check for (where < 4096) in case of PCIe or PCI-X. > @@ -62,6 +72,8 @@ static int rtas_read_config(struct devic > ????????????????return PCIBIOS_DEVICE_NOT_FOUND; > ????????if (where & (size - 1)) > ????????????????return PCIBIOS_BAD_REGISTER_NUMBER; > +???????if (!config_access_valid(dn, where)) > +???????????????return PCIBIOS_BAD_REGISTER_NUMBER; > ? > ????????addr = (dn->busno << 16) | (dn->devfn << 8) | where; addr is still wrong, see my previous mail. > @@ -110,6 +122,8 @@ static int rtas_write_config(struct devi > ????????????????return PCIBIOS_DEVICE_NOT_FOUND; > ????????if (where & (size - 1)) > ????????????????return PCIBIOS_BAD_REGISTER_NUMBER; > +???????if (!config_access_valid(dn, where)) > +???????????????return PCIBIOS_BAD_REGISTER_NUMBER; > ? > ????????addr = (dn->busno << 16) | (dn->devfn << 8) | where; same here > @@ -285,6 +309,7 @@ static int __devinit setup_phb(struct de > ????????phb->arch_data = dev; > ????????phb->ops = &rtas_pci_ops; > ????????phb->buid = get_phb_buid(dev); > +???????get_phb_config_space_type(dev); > ? > ????????return 0; > ?} Isn't the config space size a property of the PCI device instead of the host bridge? For a PCI device behind a PCIe host bridge, this could still lead to an incorrect config space accesses. Arnd <>< PS: I got a permanent fatal error from , does that list actually exist? -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050131/3bf6d47e/attachment.pgp From greg at kroah.com Tue Feb 1 09:13:46 2005 From: greg at kroah.com (Greg KH) Date: Mon, 31 Jan 2005 14:13:46 -0800 Subject: pci: Arch hook to determine config space size In-Reply-To: <200501312256.44692.arnd@arndb.de> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> <41FEA4AA.1080407@us.ibm.com> <200501312256.44692.arnd@arndb.de> Message-ID: <20050131221346.GA25180@kroah.com> On Mon, Jan 31, 2005 at 10:56:44PM +0100, Arnd Bergmann wrote: > PS: I got a permanent fatal error from , does > that list actually exist? No, that is not the email address for the linux-pci mailing list. I don't know who put that in this thread, but next time, someone might want to actually look the address up before blindly guessing... thanks, greg k-h From brking at us.ibm.com Tue Feb 1 09:43:30 2005 From: brking at us.ibm.com (Brian King) Date: Mon, 31 Jan 2005 16:43:30 -0600 Subject: pci: Arch hook to determine config space size In-Reply-To: <200501312256.44692.arnd@arndb.de> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> <41FEA4AA.1080407@us.ibm.com> <200501312256.44692.arnd@arndb.de> Message-ID: <41FEB492.2020002@us.ibm.com> Arnd Bergmann wrote: > On Maandag 31 Januar 2005 22:35, Brian King wrote: > >>Matthew Wilcox wrote: >> >>>Basically, ppc64's config ops are broken and need to check the offset >>>being read. Here's i386: >>> >>>static int pci_conf1_write (int seg, int bus, int devfn, int reg, int len, u32 v >>>alue) >>>{ >>> unsigned long flags; >>> >>> if ((bus > 255) || (devfn > 255) || (reg > 255)) >>> return -EINVAL; >> >>Here is a pure ppc64 implementation that does this. > > > Actually, it doesn't: > > >>+static int config_access_valid(struct device_node *dn, int where) >>+{ >>+ struct device_node *hose_dn = dn->phb->arch_data; >>+ >>+ if (where < 256 || hose_dn->pci_ext_config_space) >>+ return 1; > > > This needs a check for (where < 4096) in case of PCIe or PCI-X. Done. >>@@ -62,6 +72,8 @@ static int rtas_read_config(struct devic >> return PCIBIOS_DEVICE_NOT_FOUND; >> if (where & (size - 1)) >> return PCIBIOS_BAD_REGISTER_NUMBER; >>+ if (!config_access_valid(dn, where)) >>+ return PCIBIOS_BAD_REGISTER_NUMBER; >> >> addr = (dn->busno << 16) | (dn->devfn << 8) | where; > > > addr is still wrong, see my previous mail. Fixed. >>@@ -285,6 +309,7 @@ static int __devinit setup_phb(struct de >> phb->arch_data = dev; >> phb->ops = &rtas_pci_ops; >> phb->buid = get_phb_buid(dev); >>+ get_phb_config_space_type(dev); >> >> return 0; >> } > > > Isn't the config space size a property of the PCI device instead of the > host bridge? For a PCI device behind a PCIe host bridge, this could > still lead to an incorrect config space accesses. It is a property of both. Accessing config space beyond the first 256 bytes will only work if both the PCI device and the host bridge support it. The problem I ran into was generic pci code issuing a config read to offset 256 after checking that the device supports it when the host bridge did not support it. > PS: I got a permanent fatal error from , does > that list actually exist? Sorry about that... Should be fixed on this thread now. I checked the archives and saw a thread related to adding another L: line to the MAINTAINERS file for the linux-pci list. Greg - was some flavor of that patch going in? -- Brian King eServer Storage I/O IBM Linux Technology Center -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ppc64_pcix_mode2_cfg.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050131/0ff2e3ca/attachment.txt From benh at kernel.crashing.org Tue Feb 1 10:15:33 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 01 Feb 2005 10:15:33 +1100 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline In-Reply-To: <20050131192713.GA16268@mars.ravnborg.org> References: <1107151447.5712.81.camel@gaston> <20050131192713.GA16268@mars.ravnborg.org> Message-ID: <1107213333.5905.21.camel@gaston> On Mon, 2005-01-31 at 20:27 +0100, Sam Ravnborg wrote: > > Index: linux-work/arch/ppc64/kernel/vdso32/Makefile > > =================================================================== > > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > > +++ linux-work/arch/ppc64/kernel/vdso32/Makefile 2005-01-31 16:25:56.000000000 +1100 > > @@ -0,0 +1,50 @@ > > +# Choose compiler > > +# > > +# XXX FIXME: We probably want to enforce using a biarch compiler by default > > +# and thus use (CC) with -m64, while letting the user pass a > > +# CROSS32_COMPILE prefix if wanted. Same goes for the zImage > > +# wrappers > > +# > > + > > +CROSS32_COMPILE ?= > > + > > +CROSS32CC := $(CROSS32_COMPILE)gcc > > +CROSS32AS := $(CROSS32_COMPILE)as > This needs to go into arch/ppc64/Makefile Yes, we need to consolidate that with the CROSS32_COMPILE stuff using by the boot wrapper (arch/ppc64/boot). I haven't yet completely decided what to do there, I'll probably assume a biarch compiler by default instead of using the local gcc for 32 bits unless CROSS32_COMPILE is specified. > > + > > +# List of files in the vdso, has to be asm only for now > > + > > +src-vdso32 = sigtramp.S gettimeofday.S datapage.S cacheflush.S > > It is normal kbuild practice to list .o files. > So it would be: > > obj-vdso32 := sigtramp.o gettimeofday.o datapage.o cacheflush.o > targets := $(obj-vdso32) > obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) > > One line saved compared to below (not counting the src-vdso32 assignment > that is unused). > Also notice that ':=' uses all over. No need to use late evaluation when > no dynamic references are used ($ $@ etc.). > > > +# Build rules > > + > > +obj-vdso32 := $(addsuffix .o, $(basename $(src-vdso32))) > > +targets := $(obj-vdso32) vdso32.so > > +obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) > > +src-vdso32 := $(addprefix $(src)/, $(src-vdso32)) > > > Same comments to the vdso64/Makefile Hrm... I remember back then flip/flop'ing between using .S and .o in the file list and I had a reason to stick to .S but I can't remember why now :) It may be something I fixed in the meantime tho, I'll have a look . I'm not sure about the "late evaluation" thing, I'm no make expert (just learning as I write those makefiles), I'll have to dig in the doc here. Ben. From arndb at onlinehome.de Tue Feb 1 10:22:02 2005 From: arndb at onlinehome.de (arndb at onlinehome.de) Date: Tue, 1 Feb 2005 00:22:02 +0100 Subject: pci: Arch hook to determine config space size Message-ID: <26879984$110721275641feb9d4b0ac20.24786725@config18.schlund.de> Brian King schrieb am 31.01.2005, 23:43:30: > > Isn't the config space size a property of the PCI device instead of the > > host bridge? For a PCI device behind a PCIe host bridge, this could > > still lead to an incorrect config space accesses. > > It is a property of both. Accessing config space beyond the first 256 > bytes will only work if both the PCI device and the host bridge support > it. The problem I ran into was generic pci code issuing a config read to > offset 256 after checking that the device supports it when the host > bridge did not support it. If I interpret the spec correctly, the firmware should always store the value we need in the property for every device node, which means that you should look at the host bridge config-space-type attribute only when you want to look at the bridge itself. If the device claims to support a PCIe config space and the bridge doesn't, that sounds to me like a firmware bug. Arnd <>< From benh at kernel.crashing.org Tue Feb 1 11:38:02 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 01 Feb 2005 11:38:02 +1100 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline In-Reply-To: <20050131192713.GA16268@mars.ravnborg.org> References: <1107151447.5712.81.camel@gaston> <20050131192713.GA16268@mars.ravnborg.org> Message-ID: <1107218282.5906.33.camel@gaston> > Also notice that ':=' uses all over. No need to use late evaluation when > no dynamic references are used ($ $@ etc.). Hrm... Rusty tells me that you got it backward ;) Anyway, I'll stick to := for now, it's not really an issue. Ben. From benh at kernel.crashing.org Tue Feb 1 12:49:44 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 01 Feb 2005 12:49:44 +1100 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline #2 Message-ID: <1107222584.5906.43.camel@gaston> Here's an update of the patch addressing Sam's comments. I moved the definition of the 32 bits tools to the main Makefile, updated the boot wrapper code to use that as well, and made the makefile use your target compiler with -m32 when it is detected to be biarch instead of your local gcc (when CROSS32_COMPILE isn't specified). --- This is a rather large patch. See notes below for possible backward compatiblity issues. (Note: It depends on "ppc64: Move systemcfg out of head.S" beeing applied) This patch adds to the ppc64 kernel a virtual .so (vDSO) that is mapped into every process space, similar to the x86 vsyscall page. However, the implementation is very different (and doesn't use the gate area mecanism). Actually, it contains two implementations, a 32 bits and a 64 bits one. These vDSO's are currently mapped at 0x100000 (+1Mb) when possible (when a process load section isn't already there). In the future, we can randomize that address, or even imagine having a special phdr entry letting apps that wnat finer control over their address space to put it elsewhere (or not at all). The implementation adds a hook to binfmt_elf to let the architecture add a real VMA to the process space instead of using the gate area mecanism. This mecanism wasn't very suitable for ppc, we couldn't just "shove" PTE entries mapping kernel addresses into userland without expensive changes to our hash table management. Instead, I made the vDSO be a normal VMA which, additionally, means it supports copy-on-write semantics if made writable via ptrace/mprotect, thus allowing breakpoints in the vDSO code. The current implementation of the vDSOs contain the signal trampolines with appropriate DWARF informations, which enable us to use non-executable stacks (patches to come later) along with a few more functions that we hope glibc will soon make good use of (this is the "hard" part now :) Note that the symbols exposed by the vDSO aren't "normal" function symbols, apps can't be expected to link against them directly, the vDSO's are both seen as if they were linked at 0 and the symbols just contain offsets to the various functions. This is done on purpose to avoid a relocation step (ppc64 functions normally have descriptors with abs addresses in them). When glibc uses those functions, it's expected to use it's own trampolines that know how to reach them. In some cases, the vDSO contains several versions of a given function (for various CPUs), the kernel will "patch" the symbol table at boot to make it point to the appropriate one transparently. What is currently implemented is: - int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); This is a fully userland implementation of gettimeofday, with no barriers and no locks, and providing 100% equivalent results to the syscall version - void __kernel_sync_dicache(unsigned long start, unsigned long end) This function sync's the data and instruction caches (for making data executable), it is expected that userland loaders use this instead of doing it themselves, as the kernel will provide optimized versions for the current CPU. Currently, the vDSO procides a full one for all CPUs prior to POWER5 and a nop one for POWER5 which implements hardware snooping at the L1 level. In the future, an intermediate implementation may be done for the POWER4 and 970 which don't need the "dcbst" loop (the L1D cache is write-through on those). - void *__kernel_get_syscall_map(unsigned int *syscall_count) ; Returns a pointer to a map of implemented syscalls on the currently running kernel. The map is agnostic to the size of "long", unlike kernel bitops, it stores bits from top to bottom so that memory actually contains a linear bitmap check for syscall N by testing bit (0x80000000 >> (N & 0x1f)) of * 32 bits int at N >> 5. Note about backward compatibility issues: A bug in the ppc64 libgcc unwinder makes it unable to unwind stacks properly accross signals if the signal trampoline isn't on the stack. This has been fixed in CVS for gcc 4.0 and will be soon on the stable branch, but the problem exist will all currently used versions. That means that until glibc gets the patch to enable it's use of the vDSO symbols for the DWARF unwinder (rather trivial patch that will be pushed to glibc CVS soon hopefully), unwinding from a signal handler will not work for 64 bits applications. I consider this as a non-issue though as a patch is about to be produced, which can easily get pushed to "live" distros like debian, gentoo, fedora, etc... soon enough (it breaks compatilbity with kernels below 2.4.20 unfortunately as our signal stack layout changed, crap crap crap), as there are few 64 bits applications out there (expect gentoo), as it's only really an issue with C++ code relying on throwing exceptions out of signal handlers (extremely rare it seems), and as "release" distros like SLES or RHEL will probably have the vDSO enabled glibc _and_ the unwinder fix by the time they release a version with a 2.6.11 or 2.6.12 kernel anyway :) So far, I yet have to see an app failing because of that... Finally, many many many thanks to Alan Modra for writing the DWARF information of the signal handlers and debugging the libgcc issues ! Signed-off-by: Benjamin Herrenschmidt Index: linux-work/arch/ppc64/Makefile =================================================================== --- linux-work.orig/arch/ppc64/Makefile 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/Makefile 2005-02-01 12:23:40.000000000 +1100 @@ -15,17 +15,38 @@ KERNELLOAD := 0xc000000000000000 +# Set default 32 bits cross compilers for vdso and boot wrapper +CROSS32_COMPILE ?= + +CROSS32CC := $(CROSS32_COMPILE)gcc +CROSS32AS := $(CROSS32_COMPILE)as +CROSS32LD := $(CROSS32_COMPILE)ld +CROSS32OBJCOPY := $(CROSS32_COMPILE)objcopy + +# If we have a biarch compiler, use it for 32 bits cross compile if +# CROSS32_COMPILE wasn't explicitely defined, and add proper explicit +# target type to target compilers + HAS_BIARCH := $(call cc-option-yn, -m64) ifeq ($(HAS_BIARCH),y) +ifeq ($(CROSS32_COMPILE),) +CROSS32CC := $(CC) -m32 +CROSS32AS := $(AS) -a32 +CROSS32LD := $(LD) -m elf32ppc +CROSS32OBJCOPY := $(OBJCOPY) +endif AS := $(AS) -a64 LD := $(LD) -m elf64ppc CC := $(CC) -m64 endif +export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY + new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) ifeq ($(new_nm),y) NM := $(NM) --synthetic + endif CHECKFLAGS += -m64 -D__powerpc__ @@ -53,6 +74,8 @@ libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ +core-y += arch/ppc64/kernel/vdso32/ +core-y += arch/ppc64/kernel/vdso64/ core-y += arch/ppc64/mm/ core-$(CONFIG_XMON) += arch/ppc64/xmon/ drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/ Index: linux-work/arch/ppc64/kernel/asm-offsets.c =================================================================== --- linux-work.orig/arch/ppc64/kernel/asm-offsets.c 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/kernel/asm-offsets.c 2005-01-31 16:25:56.000000000 +1100 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,8 @@ #include #include #include +#include +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -167,5 +170,24 @@ DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + /* systemcfg offsets for use by vdso */ + DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp)); + DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec)); + DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs)); + DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec)); + DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count)); + DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest)); + DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime)); + DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32)); + DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64)); + + /* timeval/timezone offsets for use by vdso */ + DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec)); + DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec)); + DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec)); + DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); + DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); + DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime)); + return 0; } Index: linux-work/arch/ppc64/kernel/Makefile =================================================================== --- linux-work.orig/arch/ppc64/kernel/Makefile 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/kernel/Makefile 2005-01-31 16:25:56.000000000 +1100 @@ -11,7 +11,7 @@ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o init_task.o \ lmb.o cputable.o cpu_setup_power4.o idle_power4.o \ - iommu.o sysfs.o + iommu.o sysfs.o vdso.o obj-$(CONFIG_PPC_OF) += of_device.o Index: linux-work/arch/ppc64/kernel/signal32.c =================================================================== --- linux-work.orig/arch/ppc64/kernel/signal32.c 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/kernel/signal32.c 2005-01-31 16:25:56.000000000 +1100 @@ -31,6 +31,7 @@ #include #include #include +#include #define DEBUG_SIG 0 @@ -656,18 +657,24 @@ /* Save user registers on the stack */ frame = &rt_sf->uc.uc_mcontext; - if (save_user_regs(regs, frame, __NR_rt_sigreturn)) - goto badframe; - if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) goto badframe; + + if (vdso32_rt_sigtramp && current->thread.vdso_base) { + if (save_user_regs(regs, frame, 0)) + goto badframe; + regs->link = current->thread.vdso_base + vdso32_rt_sigtramp; + } else { + if (save_user_regs(regs, frame, __NR_rt_sigreturn)) + goto badframe; + regs->link = (unsigned long) frame->tramp; + } regs->gpr[1] = (unsigned long) newsp; regs->gpr[3] = sig; regs->gpr[4] = (unsigned long) &rt_sf->info; regs->gpr[5] = (unsigned long) &rt_sf->uc; regs->gpr[6] = (unsigned long) rt_sf; regs->nip = (unsigned long) ka->sa.sa_handler; - regs->link = (unsigned long) frame->tramp; regs->trap = 0; regs->result = 0; @@ -825,8 +832,15 @@ || __put_user(sig, &sc->signal)) goto badframe; - if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) - goto badframe; + if (vdso32_sigtramp && current->thread.vdso_base) { + if (save_user_regs(regs, &frame->mctx, 0)) + goto badframe; + regs->link = current->thread.vdso_base + vdso32_sigtramp; + } else { + if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) + goto badframe; + regs->link = (unsigned long) frame->mctx.tramp; + } if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) goto badframe; @@ -834,7 +848,6 @@ regs->gpr[3] = sig; regs->gpr[4] = (unsigned long) sc; regs->nip = (unsigned long) ka->sa.sa_handler; - regs->link = (unsigned long) frame->mctx.tramp; regs->trap = 0; regs->result = 0; Index: linux-work/arch/ppc64/kernel/setup.c =================================================================== --- linux-work.orig/arch/ppc64/kernel/setup.c 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/kernel/setup.c 2005-01-31 16:25:56.000000000 +1100 @@ -990,6 +990,34 @@ } /* + * Called from setup_arch to initialize the bitmap of available + * syscalls in the systemcfg page + */ +void __init setup_syscall_map(void) +{ + unsigned int i, count64 = 0, count32 = 0; + extern unsigned long *sys_call_table; + extern unsigned long *sys_call_table32; + extern unsigned long sys_ni_syscall; + + + for (i = 0; i < __NR_syscalls; i++) { + if (sys_call_table[i] == sys_ni_syscall) + continue; + count64++; + systemcfg->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f); + } + for (i = 0; i < __NR_syscalls; i++) { + if (sys_call_table32[i] == sys_ni_syscall) + continue; + count32++; + systemcfg->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f); + } + printk(KERN_INFO "Syscall map setup, %d 32 bits and %d 64 bits syscalls\n", + count32, count64); +} + +/* * Called into from start_kernel, after lock_kernel has been called. * Initializes bootmem, which is unsed to manage page allocation until * mem_init is called. @@ -1027,6 +1055,9 @@ /* set up the bootmem stuff with available memory */ do_init_bootmem(); + /* initialize the syscall map in systemcfg */ + setup_syscall_map(); + ppc_md.setup_arch(); /* Select the correct idle loop for the platform. */ Index: linux-work/arch/ppc64/kernel/signal.c =================================================================== --- linux-work.orig/arch/ppc64/kernel/signal.c 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/kernel/signal.c 2005-01-31 16:25:56.000000000 +1100 @@ -34,6 +34,7 @@ #include #include #include +#include #define DEBUG_SIG 0 @@ -426,10 +427,14 @@ goto badframe; /* Set up to return from userspace. */ - err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); - if (err) - goto badframe; - + if (vdso64_rt_sigtramp && current->thread.vdso_base) { + regs->link = current->thread.vdso_base + vdso64_rt_sigtramp; + } else { + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); + if (err) + goto badframe; + regs->link = (unsigned long) &frame->tramp[0]; + } funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler; /* Allocate a dummy caller frame for the signal handler. */ @@ -438,7 +443,6 @@ /* Set up "regs" so we "return" to the signal handler. */ err |= get_user(regs->nip, &funct_desc_ptr->entry); - regs->link = (unsigned long) &frame->tramp[0]; regs->gpr[1] = newsp; err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); regs->gpr[3] = signr; Index: linux-work/arch/ppc64/kernel/smp.c =================================================================== --- linux-work.orig/arch/ppc64/kernel/smp.c 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/kernel/smp.c 2005-01-31 16:25:56.000000000 +1100 @@ -383,7 +383,7 @@ * For now we leave it which means the time can be some * number of msecs off until someone does a settimeofday() */ - do_gtod.tb_orig_stamp = tb_last_stamp; + do_gtod.varp->tb_orig_stamp = tb_last_stamp; systemcfg->tb_orig_stamp = tb_last_stamp; #endif Index: linux-work/arch/ppc64/kernel/time.c =================================================================== --- linux-work.orig/arch/ppc64/kernel/time.c 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/kernel/time.c 2005-01-31 16:25:56.000000000 +1100 @@ -86,8 +86,6 @@ unsigned long tb_ticks_per_jiffy; unsigned long tb_ticks_per_usec = 100; /* sane default */ unsigned long tb_ticks_per_sec; -unsigned long next_xtime_sync_tb; -unsigned long xtime_sync_interval; unsigned long tb_to_xs; unsigned tb_to_us; unsigned long processor_freq; @@ -158,8 +156,8 @@ * The conversion to microseconds at the end is done * without a divide (and in fact, without a multiply) */ - tb_ticks = tb_val - do_gtod.tb_orig_stamp; temp_varp = do_gtod.varp; + tb_ticks = tb_val - temp_varp->tb_orig_stamp; temp_tb_to_xs = temp_varp->tb_to_xs; temp_stamp_xsec = temp_varp->stamp_xsec; tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs ); @@ -185,17 +183,55 @@ { struct timeval my_tv; - if (cur_tb > next_xtime_sync_tb) { - next_xtime_sync_tb = cur_tb + xtime_sync_interval; - __do_gettimeofday(&my_tv, cur_tb); - - if (xtime.tv_sec <= my_tv.tv_sec) { - xtime.tv_sec = my_tv.tv_sec; - xtime.tv_nsec = my_tv.tv_usec * 1000; - } + __do_gettimeofday(&my_tv, cur_tb); + + if (xtime.tv_sec <= my_tv.tv_sec) { + xtime.tv_sec = my_tv.tv_sec; + xtime.tv_nsec = my_tv.tv_usec * 1000; } } +/* + * When the timebase - tb_orig_stamp gets too big, we do a manipulation + * between tb_orig_stamp and stamp_xsec. The goal here is to keep the + * difference tb - tb_orig_stamp small enough to always fit inside a + * 32 bits number. This is a requirement of our fast 32 bits userland + * implementation in the vdso. If we "miss" a call to this function + * (interrupt latency, CPU locked in a spinlock, ...) and we end up + * with a too big difference, then the vdso will fallback to calling + * the syscall + */ +static __inline__ void timer_recalc_offset(unsigned long cur_tb) +{ + struct gettimeofday_vars * temp_varp; + unsigned temp_idx; + unsigned long offset, new_stamp_xsec, new_tb_orig_stamp; + + if (((cur_tb - do_gtod.varp->tb_orig_stamp) & 0x80000000u) == 0) + return; + + temp_idx = (do_gtod.var_idx == 0); + temp_varp = &do_gtod.vars[temp_idx]; + + new_tb_orig_stamp = cur_tb; + offset = new_tb_orig_stamp - do_gtod.varp->tb_orig_stamp; + new_stamp_xsec = do_gtod.varp->stamp_xsec + mulhdu(offset, do_gtod.varp->tb_to_xs); + + temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs; + temp_varp->tb_orig_stamp = new_tb_orig_stamp; + temp_varp->stamp_xsec = new_stamp_xsec; + mb(); + do_gtod.varp = temp_varp; + do_gtod.var_idx = temp_idx; + + ++(systemcfg->tb_update_count); + wmb(); + systemcfg->tb_orig_stamp = new_tb_orig_stamp; + systemcfg->stamp_xsec = new_stamp_xsec; + wmb(); + ++(systemcfg->tb_update_count); +} + #ifdef CONFIG_SMP unsigned long profile_pc(struct pt_regs *regs) { @@ -311,6 +347,7 @@ if (cpu == boot_cpuid) { write_seqlock(&xtime_lock); tb_last_stamp = lpaca->next_jiffy_update_tb; + timer_recalc_offset(lpaca->next_jiffy_update_tb); do_timer(regs); timer_sync_xtime(lpaca->next_jiffy_update_tb); timer_check_rtc(); @@ -398,7 +435,9 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - delta_xsec = mulhdu( (tb_last_stamp-do_gtod.tb_orig_stamp), do_gtod.varp->tb_to_xs ); + delta_xsec = mulhdu( (tb_last_stamp-do_gtod.varp->tb_orig_stamp), + do_gtod.varp->tb_to_xs ); + new_xsec = (new_nsec * XSEC_PER_SEC) / NSEC_PER_SEC; new_xsec += new_sec * XSEC_PER_SEC; if ( new_xsec > delta_xsec ) { @@ -411,7 +450,7 @@ * before 1970 ... eg. we booted ten days ago, and we are setting * the time to Jan 5, 1970 */ do_gtod.varp->stamp_xsec = new_xsec; - do_gtod.tb_orig_stamp = tb_last_stamp; + do_gtod.varp->tb_orig_stamp = tb_last_stamp; systemcfg->stamp_xsec = new_xsec; systemcfg->tb_orig_stamp = tb_last_stamp; } @@ -464,9 +503,9 @@ xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); tb_last_stamp = get_tb(); - do_gtod.tb_orig_stamp = tb_last_stamp; do_gtod.varp = &do_gtod.vars[0]; do_gtod.var_idx = 0; + do_gtod.varp->tb_orig_stamp = tb_last_stamp; do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; do_gtod.varp->tb_to_xs = tb_to_xs; @@ -477,9 +516,6 @@ systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; systemcfg->tb_to_xs = tb_to_xs; - xtime_sync_interval = tb_ticks_per_sec - (tb_ticks_per_sec/8); - next_xtime_sync_tb = tb_last_stamp + xtime_sync_interval; - time_freq = 0; xtime.tv_nsec = 0; @@ -584,12 +620,12 @@ stamp_xsec which is the time (in 1/2^20 second units) corresponding to tb_orig_stamp. This new value of stamp_xsec compensates for the change in frequency (implied by the new tb_to_xs) which guarantees that the current time remains the same */ - tb_ticks = get_tb() - do_gtod.tb_orig_stamp; + write_seqlock_irqsave( &xtime_lock, flags ); + tb_ticks = get_tb() - do_gtod.varp->tb_orig_stamp; div128_by_32( 1024*1024, 0, new_tb_ticks_per_sec, &divres ); new_tb_to_xs = divres.result_low; new_xsec = mulhdu( tb_ticks, new_tb_to_xs ); - write_seqlock_irqsave( &xtime_lock, flags ); old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs ); new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec; @@ -597,16 +633,12 @@ values in do_gettimeofday. We alternate the copies and as long as a reasonable time elapses between changes, there will never be inconsistent values. ntpd has a minimum of one minute between updates */ - if (do_gtod.var_idx == 0) { - temp_varp = &do_gtod.vars[1]; - temp_idx = 1; - } - else { - temp_varp = &do_gtod.vars[0]; - temp_idx = 0; - } + temp_idx = (do_gtod.var_idx == 0); + temp_varp = &do_gtod.vars[temp_idx]; + temp_varp->tb_to_xs = new_tb_to_xs; temp_varp->stamp_xsec = new_stamp_xsec; + temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp; mb(); do_gtod.varp = temp_varp; do_gtod.var_idx = temp_idx; Index: linux-work/arch/ppc64/kernel/vdso.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso.c 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,614 @@ +/* + * linux/arch/ppc64/kernel/vdso.c + * + * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(fmt...) printk(fmt) +#else +#define DBG(fmt...) +#endif + + +/* + * The vDSOs themselves are here + */ +extern char vdso64_start, vdso64_end; +extern char vdso32_start, vdso32_end; + +static void *vdso64_kbase = &vdso64_start; +static void *vdso32_kbase = &vdso32_start; + +unsigned int vdso64_pages; +unsigned int vdso32_pages; + +/* Signal trampolines user addresses */ + +unsigned long vdso64_rt_sigtramp; +unsigned long vdso32_sigtramp; +unsigned long vdso32_rt_sigtramp; + +/* Format of the patch table */ +struct vdso_patch_def +{ + u32 pvr_mask, pvr_value; + const char *gen_name; + const char *fix_name; +}; + +/* Table of functions to patch based on the CPU type/revision + * + * TODO: Improve by adding whole lists for each entry + */ +static struct vdso_patch_def vdso_patches[] = { + { + 0xffff0000, 0x003a0000, /* POWER5 */ + "__kernel_sync_dicache", "__kernel_sync_dicache_p5" + }, + { + 0xffff0000, 0x003b0000, /* POWER5 */ + "__kernel_sync_dicache", "__kernel_sync_dicache_p5" + }, +}; + +/* + * Some infos carried around for each of them during parsing at + * boot time. + */ +struct lib32_elfinfo +{ + Elf32_Ehdr *hdr; /* ptr to ELF */ + Elf32_Sym *dynsym; /* ptr to .dynsym section */ + unsigned long dynsymsize; /* size of .dynsym section */ + char *dynstr; /* ptr to .dynstr section */ + unsigned long text; /* offset of .text section in .so */ +}; + +struct lib64_elfinfo +{ + Elf64_Ehdr *hdr; + Elf64_Sym *dynsym; + unsigned long dynsymsize; + char *dynstr; + unsigned long text; +}; + + +#ifdef __DEBUG +static void dump_one_vdso_page(struct page *pg, struct page *upg) +{ + printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT), + page_count(pg), + pg->flags); + if (upg/* && pg != upg*/) { + printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg) << PAGE_SHIFT), + page_count(upg), + upg->flags); + } + printk("\n"); +} + +static void dump_vdso_pages(struct vm_area_struct * vma) +{ + int i; + + if (!vma || test_thread_flag(TIF_32BIT)) { + printk("vDSO32 @ %016lx:\n", (unsigned long)vdso32_kbase); + for (i=0; ivm_mm) ? + follow_page(vma->vm_mm, vma->vm_start + i*PAGE_SIZE, 0) + : NULL; + dump_one_vdso_page(pg, upg); + } + } + if (!vma || !test_thread_flag(TIF_32BIT)) { + printk("vDSO64 @ %016lx:\n", (unsigned long)vdso64_kbase); + for (i=0; ivm_mm) ? + follow_page(vma->vm_mm, vma->vm_start + i*PAGE_SIZE, 0) + : NULL; + dump_one_vdso_page(pg, upg); + } + } +} +#endif /* DEBUG */ + +/* + * Keep a dummy vma_close for now, it will prevent VMA merging. + */ +static void vdso_vma_close(struct vm_area_struct * vma) +{ +} + +/* + * Our nopage() function, maps in the actual vDSO kernel pages, they will + * be mapped read-only by do_no_page(), and eventually COW'ed, either + * right away for an initial write access, or by do_wp_page(). + */ +static struct page * vdso_vma_nopage(struct vm_area_struct * vma, + unsigned long address, int *type) +{ + unsigned long offset = address - vma->vm_start; + struct page *pg; + void *vbase = test_thread_flag(TIF_32BIT) ? vdso32_kbase : vdso64_kbase; + + DBG("vdso_vma_nopage(current: %s, address: %016lx, off: %lx)\n", + current->comm, address, offset); + + if (address < vma->vm_start || address > vma->vm_end) + return NOPAGE_SIGBUS; + + /* + * Last page is systemcfg, special handling here, no get_page() a + * this is a reserved page + */ + if ((vma->vm_end - address) <= PAGE_SIZE) + return virt_to_page(systemcfg); + + pg = virt_to_page(vbase + offset); + get_page(pg); + DBG(" ->page count: %d\n", page_count(pg)); + + return pg; +} + +static struct vm_operations_struct vdso_vmops = { + .close = vdso_vma_close, + .nopage = vdso_vma_nopage, +}; + +/* + * This is called from binfmt_elf, we create the special vma for the + * vDSO and insert it into the mm struct tree + */ +int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long vdso_pages; + unsigned long vdso_base; + + if (test_thread_flag(TIF_32BIT)) { + vdso_pages = vdso32_pages; + vdso_base = VDSO32_MBASE; + } else { + vdso_pages = vdso64_pages; + vdso_base = VDSO64_MBASE; + } + + /* vDSO has a problem and was disabled, just don't "enable" it for the + * process + */ + if (vdso_pages == 0) { + current->thread.vdso_base = 0; + return 0; + } + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + if (vma == NULL) + return -ENOMEM; + if (security_vm_enough_memory(vdso_pages)) { + kmem_cache_free(vm_area_cachep, vma); + return -ENOMEM; + } + memset(vma, 0, sizeof(*vma)); + + /* + * pick a base address for the vDSO in process space. We have a default + * base of 1Mb on which we had a random offset up to 1Mb. + * XXX: Add possibility for a program header to specify that location + */ + current->thread.vdso_base = vdso_base; + /* + ((unsigned long)vma & 0x000ff000); */ + + vma->vm_mm = mm; + vma->vm_start = current->thread.vdso_base; + + /* + * the VMA size is one page more than the vDSO since systemcfg + * is mapped in the last one + */ + vma->vm_end = vma->vm_start + ((vdso_pages + 1) << PAGE_SHIFT); + + /* + * our vma flags don't have VM_WRITE so by default, the process isn't allowed + * to write those pages. + * gdb can break that with ptrace interface, and thus trigger COW on those + * pages but it's then your responsibility to never do that on the "data" page + * of the vDSO or you'll stop getting kernel updates and your nice userland + * gettimeofday will be totally dead. It's fine to use that for setting + * breakpoints in the vDSO code pages though + */ + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; + vma->vm_flags |= mm->def_flags; + vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; + vma->vm_ops = &vdso_vmops; + + down_write(&mm->mmap_sem); + insert_vm_struct(mm, vma); + mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + up_write(&mm->mmap_sem); + + return 0; +} + +static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname, + unsigned long *size) +{ + Elf32_Shdr *sechdrs; + unsigned int i; + char *secnames; + + /* Grab section headers and strings so we can tell who is who */ + sechdrs = (void *)ehdr + ehdr->e_shoff; + secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset; + + /* Find the section they want */ + for (i = 1; i < ehdr->e_shnum; i++) { + if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) { + if (size) + *size = sechdrs[i].sh_size; + return (void *)ehdr + sechdrs[i].sh_offset; + } + } + *size = 0; + return NULL; +} + +static void * __init find_section64(Elf64_Ehdr *ehdr, const char *secname, + unsigned long *size) +{ + Elf64_Shdr *sechdrs; + unsigned int i; + char *secnames; + + /* Grab section headers and strings so we can tell who is who */ + sechdrs = (void *)ehdr + ehdr->e_shoff; + secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset; + + /* Find the section they want */ + for (i = 1; i < ehdr->e_shnum; i++) { + if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) { + if (size) + *size = sechdrs[i].sh_size; + return (void *)ehdr + sechdrs[i].sh_offset; + } + } + if (size) + *size = 0; + return NULL; +} + +static Elf32_Sym * __init find_symbol32(struct lib32_elfinfo *lib, const char *symname) +{ + unsigned int i; + char name[32], *c; + + for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) { + if (lib->dynsym[i].st_name == 0) + continue; + strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, 32); + c = strchr(name, '@'); + if (c) + *c = 0; + if (strcmp(symname, name) == 0) + return &lib->dynsym[i]; + } + return NULL; +} + +static Elf64_Sym * __init find_symbol64(struct lib64_elfinfo *lib, const char *symname) +{ + unsigned int i; + char name[32], *c; + + for (i = 0; i < (lib->dynsymsize / sizeof(Elf64_Sym)); i++) { + if (lib->dynsym[i].st_name == 0) + continue; + strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, 32); + c = strchr(name, '@'); + if (c) + *c = 0; + if (strcmp(symname, name) == 0) + return &lib->dynsym[i]; + } + return NULL; +} + +/* Note that we assume the section is .text and the symbol is relative to + * the library base + */ +static unsigned long __init find_function32(struct lib32_elfinfo *lib, const char *symname) +{ + Elf32_Sym *sym = find_symbol32(lib, symname); + + if (sym == NULL) { + printk(KERN_WARNING "vDSO32: function %s not found !\n", symname); + return 0; + } + return sym->st_value - VDSO32_LBASE; +} + +/* Note that we assume the section is .text and the symbol is relative to + * the library base + */ +static unsigned long __init find_function64(struct lib64_elfinfo *lib, const char *symname) +{ + Elf64_Sym *sym = find_symbol64(lib, symname); + + if (sym == NULL) { + printk(KERN_WARNING "vDSO64: function %s not found !\n", symname); + return 0; + } +#ifdef VDS64_HAS_DESCRIPTORS + return *((u64 *)(vdso64_kbase + sym->st_value - VDSO64_LBASE)) - VDSO64_LBASE; +#else + return sym->st_value - VDSO64_LBASE; +#endif +} + + +static __init int vdso_do_find_sections(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64) +{ + void *sect; + + /* + * Locate symbol tables & text section + */ + + v32->dynsym = find_section32(v32->hdr, ".dynsym", &v32->dynsymsize); + v32->dynstr = find_section32(v32->hdr, ".dynstr", NULL); + if (v32->dynsym == NULL || v32->dynstr == NULL) { + printk(KERN_ERR "vDSO32: a required symbol section was not found\n"); + return -1; + } + sect = find_section32(v32->hdr, ".text", NULL); + if (sect == NULL) { + printk(KERN_ERR "vDSO32: the .text section was not found\n"); + return -1; + } + v32->text = sect - vdso32_kbase; + + v64->dynsym = find_section64(v64->hdr, ".dynsym", &v64->dynsymsize); + v64->dynstr = find_section64(v64->hdr, ".dynstr", NULL); + if (v64->dynsym == NULL || v64->dynstr == NULL) { + printk(KERN_ERR "vDSO64: a required symbol section was not found\n"); + return -1; + } + sect = find_section64(v64->hdr, ".text", NULL); + if (sect == NULL) { + printk(KERN_ERR "vDSO64: the .text section was not found\n"); + return -1; + } + v64->text = sect - vdso64_kbase; + + return 0; +} + +static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64) +{ + /* + * Find signal trampolines + */ + + vdso64_rt_sigtramp = find_function64(v64, "__kernel_sigtramp_rt64"); + vdso32_sigtramp = find_function32(v32, "__kernel_sigtramp32"); + vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32"); +} + +static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64) +{ + Elf32_Sym *sym32; + Elf64_Sym *sym64; + + sym32 = find_symbol32(v32, "__kernel_datapage_offset"); + if (sym32 == NULL) { + printk(KERN_ERR "vDSO32: Can't find symbol __kernel_datapage_offset !\n"); + return -1; + } + *((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) = + (vdso32_pages << PAGE_SHIFT) - (sym32->st_value - VDSO32_LBASE); + + sym64 = find_symbol64(v64, "__kernel_datapage_offset"); + if (sym64 == NULL) { + printk(KERN_ERR "vDSO64: Can't find symbol __kernel_datapage_offset !\n"); + return -1; + } + *((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) = + (vdso64_pages << PAGE_SHIFT) - (sym64->st_value - VDSO64_LBASE); + + return 0; +} + +static int vdso_do_func_patch32(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64, + const char *orig, const char *fix) +{ + Elf32_Sym *sym32_gen, *sym32_fix; + + sym32_gen = find_symbol32(v32, orig); + if (sym32_gen == NULL) { + printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", orig); + return -1; + } + sym32_fix = find_symbol32(v32, fix); + if (sym32_fix == NULL) { + printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", fix); + return -1; + } + sym32_gen->st_value = sym32_fix->st_value; + sym32_gen->st_size = sym32_fix->st_size; + sym32_gen->st_info = sym32_fix->st_info; + sym32_gen->st_other = sym32_fix->st_other; + sym32_gen->st_shndx = sym32_fix->st_shndx; + + return 0; +} + +static int vdso_do_func_patch64(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64, + const char *orig, const char *fix) +{ + Elf64_Sym *sym64_gen, *sym64_fix; + + sym64_gen = find_symbol64(v64, orig); + if (sym64_gen == NULL) { + printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", orig); + return -1; + } + sym64_fix = find_symbol64(v64, fix); + if (sym64_fix == NULL) { + printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", fix); + return -1; + } + sym64_gen->st_value = sym64_fix->st_value; + sym64_gen->st_size = sym64_fix->st_size; + sym64_gen->st_info = sym64_fix->st_info; + sym64_gen->st_other = sym64_fix->st_other; + sym64_gen->st_shndx = sym64_fix->st_shndx; + + return 0; +} + +static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64) +{ + u32 pvr; + int i; + + pvr = mfspr(SPRN_PVR); + for (i = 0; i < ARRAY_SIZE(vdso_patches); i++) { + struct vdso_patch_def *patch = &vdso_patches[i]; + int match = (pvr & patch->pvr_mask) == patch->pvr_value; + + DBG("patch %d (mask: %x, pvr: %x) : %s\n", + i, patch->pvr_mask, patch->pvr_value, match ? "match" : "skip"); + + if (!match) + continue; + + DBG("replacing %s with %s...\n", patch->gen_name, patch->fix_name); + + /* + * Patch the 32 bits and 64 bits symbols. Note that we do not patch + * the "." symbol on 64 bits. It would be easy to do, but doesn't + * seem to be necessary, patching the OPD symbol is enough. + */ + vdso_do_func_patch32(v32, v64, patch->gen_name, patch->fix_name); + vdso_do_func_patch64(v32, v64, patch->gen_name, patch->fix_name); + } + + return 0; +} + + +static __init int vdso_setup(void) +{ + struct lib32_elfinfo v32; + struct lib64_elfinfo v64; + + v32.hdr = vdso32_kbase; + v64.hdr = vdso64_kbase; + + if (vdso_do_find_sections(&v32, &v64)) + return -1; + + if (vdso_fixup_datapage(&v32, &v64)) + return -1; + + if (vdso_fixup_alt_funcs(&v32, &v64)) + return -1; + + vdso_setup_trampolines(&v32, &v64); + + return 0; +} + +void __init vdso_init(void) +{ + int i; + + vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT; + vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT; + + DBG("vdso64_kbase: %p, 0x%x pages, vdso32_kbase: %p, 0x%x pages\n", + vdso64_kbase, vdso64_pages, vdso32_kbase, vdso32_pages); + + /* + * Initialize the vDSO images in memory, that is do necessary + * fixups of vDSO symbols, locate trampolines, etc... + */ + if (vdso_setup()) { + printk(KERN_ERR "vDSO setup failure, not enabled !\n"); + /* XXX should free pages here ? */ + vdso64_pages = vdso32_pages = 0; + return; + } + + /* Make sure pages are in the correct state */ + for (i = 0; i < vdso64_pages; i++) { + struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE); + ClearPageReserved(pg); + get_page(pg); + } + for (i = 0; i < vdso32_pages; i++) { + struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE); + ClearPageReserved(pg); + get_page(pg); + } +} + +int in_gate_area_no_task(unsigned long addr) +{ + return 0; +} + +int in_gate_area(struct task_struct *task, unsigned long addr) +{ + return 0; +} + +struct vm_area_struct *get_gate_vma(struct task_struct *tsk) +{ + return NULL; +} + Index: linux-work/include/asm-ppc64/processor.h =================================================================== --- linux-work.orig/include/asm-ppc64/processor.h 2005-01-31 14:18:44.000000000 +1100 +++ linux-work/include/asm-ppc64/processor.h 2005-01-31 16:25:56.000000000 +1100 @@ -544,8 +544,8 @@ /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(STACK_TOP_USER32 / 4)) -#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(STACK_TOP_USER64 / 4)) +#define TASK_UNMAPPED_BASE_USER32 (PAGE_ALIGN(TASK_SIZE_USER32 / 4)) +#define TASK_UNMAPPED_BASE_USER64 (PAGE_ALIGN(TASK_SIZE_USER64 / 4)) #define TASK_UNMAPPED_BASE ((test_thread_flag(TIF_32BIT)||(ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \ TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 ) @@ -562,7 +562,8 @@ double fpr[32]; /* Complete floating point set */ unsigned long fpscr; /* Floating point status (plus pad) */ unsigned long fpexc_mode; /* Floating-point exception mode */ - unsigned long pad[3]; /* was saved_msr, saved_softe */ + unsigned long pad[2]; /* was saved_msr, saved_softe */ + unsigned long vdso_base; /* base of the vDSO library */ #ifdef CONFIG_ALTIVEC /* Complete AltiVec register set */ vector128 vr[32] __attribute((aligned(16))); Index: linux-work/include/asm-ppc64/systemcfg.h =================================================================== --- linux-work.orig/include/asm-ppc64/systemcfg.h 2005-01-31 15:56:55.000000000 +1100 +++ linux-work/include/asm-ppc64/systemcfg.h 2005-01-31 16:25:56.000000000 +1100 @@ -20,10 +20,14 @@ * Minor version changes are a hint. */ #define SYSTEMCFG_MAJOR 1 -#define SYSTEMCFG_MINOR 0 +#define SYSTEMCFG_MINOR 1 #ifndef __ASSEMBLY__ +#include + +#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32) + struct systemcfg { __u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */ struct { /* Systemcfg version numbers */ @@ -47,6 +51,8 @@ __u32 dcache_line_size; /* L1 d-cache line size 0x64 */ __u32 icache_size; /* L1 i-cache size 0x68 */ __u32 icache_line_size; /* L1 i-cache line size 0x6C */ + __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of available syscalls 0x70 */ + __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of available syscalls */ }; #ifdef __KERNEL__ Index: linux-work/include/asm-ppc64/a.out.h =================================================================== --- linux-work.orig/include/asm-ppc64/a.out.h 2005-01-31 14:18:44.000000000 +1100 +++ linux-work/include/asm-ppc64/a.out.h 2005-01-31 16:25:56.000000000 +1100 @@ -30,14 +30,11 @@ #ifdef __KERNEL__ -#define STACK_TOP_USER64 (TASK_SIZE_USER64) +#define STACK_TOP_USER64 TASK_SIZE_USER64 +#define STACK_TOP_USER32 TASK_SIZE_USER32 -/* Give 32-bit user space a full 4G address space to live in. */ -#define STACK_TOP_USER32 (TASK_SIZE_USER32) - -#define STACK_TOP ((test_thread_flag(TIF_32BIT) || \ - (ppcdebugset(PPCDBG_BINFMT_32ADDR))) ? \ - STACK_TOP_USER32 : STACK_TOP_USER64) +#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ + STACK_TOP_USER32 : STACK_TOP_USER64) #endif /* __KERNEL__ */ Index: linux-work/include/asm-ppc64/elf.h =================================================================== --- linux-work.orig/include/asm-ppc64/elf.h 2005-01-31 14:18:44.000000000 +1100 +++ linux-work/include/asm-ppc64/elf.h 2005-01-31 16:25:56.000000000 +1100 @@ -238,10 +238,20 @@ /* A special ignored type value for PPC, for glibc compatibility. */ #define AT_IGNOREPPC 22 +/* The vDSO location. We have to use the same value as x86 for glibc's + * sake :-) + */ +#define AT_SYSINFO_EHDR 33 + extern int dcache_bsize; extern int icache_bsize; extern int ucache_bsize; +/* We do have an arch_setup_additional_pages for vDSO matters */ +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES +struct linux_binprm; +extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); + /* * The requirements here are: * - keep the final alignment of sp (sp & 0xf) @@ -260,6 +270,8 @@ NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \ NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \ NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \ + /* vDSO base */ \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base); \ } while (0) /* PowerPC64 relocations defined by the ABIs */ Index: linux-work/include/asm-ppc64/time.h =================================================================== --- linux-work.orig/include/asm-ppc64/time.h 2005-01-31 14:18:44.000000000 +1100 +++ linux-work/include/asm-ppc64/time.h 2005-01-31 16:25:56.000000000 +1100 @@ -43,10 +43,10 @@ struct gettimeofday_vars { unsigned long tb_to_xs; unsigned long stamp_xsec; + unsigned long tb_orig_stamp; }; struct gettimeofday_struct { - unsigned long tb_orig_stamp; unsigned long tb_ticks_per_sec; struct gettimeofday_vars vars[2]; struct gettimeofday_vars * volatile varp; Index: linux-work/fs/binfmt_elf.c =================================================================== --- linux-work.orig/fs/binfmt_elf.c 2005-01-31 14:18:24.000000000 +1100 +++ linux-work/fs/binfmt_elf.c 2005-01-31 16:25:56.000000000 +1100 @@ -772,6 +772,14 @@ goto out_free_dentry; } +#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES + retval = arch_setup_additional_pages(bprm, executable_stack); + if (retval < 0) { + send_sig(SIGKILL, current, 0); + goto out_free_dentry; + } +#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ + current->mm->start_stack = bprm->p; /* Now we do a little grungy work by mmaping the ELF image into Index: linux-work/include/asm-ppc64/page.h =================================================================== --- linux-work.orig/include/asm-ppc64/page.h 2005-01-31 14:18:44.000000000 +1100 +++ linux-work/include/asm-ppc64/page.h 2005-01-31 16:25:56.000000000 +1100 @@ -185,6 +185,9 @@ extern u64 ppc64_pft_size; /* Log 2 of page table size */ +/* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */ +#define __HAVE_ARCH_GATE_AREA 1 + #endif /* __ASSEMBLY__ */ #ifdef MODULE Index: linux-work/include/asm-ppc64/vdso.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/include/asm-ppc64/vdso.h 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,83 @@ +#ifndef __PPC64_VDSO_H__ +#define __PPC64_VDSO_H__ + +#ifdef __KERNEL__ + +/* Default link addresses for the vDSOs */ +#define VDSO32_LBASE 0 +#define VDSO64_LBASE 0 + +/* Default map addresses */ +#define VDSO32_MBASE 0x100000 +#define VDSO64_MBASE 0x100000 + +#define VDSO_VERSION_STRING LINUX_2.6.11 + +/* Define if 64 bits VDSO has procedure descriptors */ +#undef VDS64_HAS_DESCRIPTORS + +#ifndef __ASSEMBLY__ + +extern unsigned int vdso64_pages; +extern unsigned int vdso32_pages; + +/* Offsets relative to thread->vdso_base */ +extern unsigned long vdso64_rt_sigtramp; +extern unsigned long vdso32_sigtramp; +extern unsigned long vdso32_rt_sigtramp; + +extern void vdso_init(void); + +#else /* __ASSEMBLY__ */ + +#ifdef __VDSO64__ +#ifdef VDS64_HAS_DESCRIPTORS +#define V_FUNCTION_BEGIN(name) \ + .globl name; \ + .section ".opd","a"; \ + .align 3; \ + name: \ + .quad .name,.TOC. at tocbase,0; \ + .previous; \ + .globl .name; \ + .type .name, at function; \ + .name: \ + +#define V_FUNCTION_END(name) \ + .size .name,.-.name; + +#define V_LOCAL_FUNC(name) (.name) + +#else /* VDS64_HAS_DESCRIPTORS */ + +#define V_FUNCTION_BEGIN(name) \ + .globl name; \ + name: \ + +#define V_FUNCTION_END(name) \ + .size name,.-name; + +#define V_LOCAL_FUNC(name) (name) + +#endif /* VDS64_HAS_DESCRIPTORS */ +#endif /* __VDSO64__ */ + +#ifdef __VDSO32__ + +#define V_FUNCTION_BEGIN(name) \ + .globl name; \ + .type name, at function; \ + name: \ + +#define V_FUNCTION_END(name) \ + .size name,.-name; + +#define V_LOCAL_FUNC(name) (name) + +#endif /* __VDSO32__ */ + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* __PPC64_VDSO_H__ */ Index: linux-work/arch/ppc64/mm/init.c =================================================================== --- linux-work.orig/arch/ppc64/mm/init.c 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/mm/init.c 2005-01-31 16:25:56.000000000 +1100 @@ -62,6 +62,7 @@ #include #include #include +#include int mem_init_done; unsigned long ioremap_bot = IMALLOC_BASE; @@ -743,6 +744,8 @@ #ifdef CONFIG_PPC_ISERIES iommu_vio_init(); #endif + /* Initialize the vDSO */ + vdso_init(); } /* Index: linux-work/arch/ppc64/kernel/vdso32/gettimeofday.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso32/gettimeofday.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,139 @@ +/* + * Userland implementation of gettimeofday() for 32 bits processes in a + * ppc64 kernel for use in the vDSO + * + * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org), IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include + + .text +/* + * Exact prototype of gettimeofday + * + * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); + * + */ +V_FUNCTION_BEGIN(__kernel_gettimeofday) + .cfi_startproc + mflr r12 + .cfi_register lr,r12 + + mr r10,r3 /* r10 saves tv */ + mr r11,r4 /* r11 saves tz */ + bl __get_datapage at local /* get data page */ + mr r9, r3 /* datapage ptr in r9 */ + bl __do_get_xsec at local /* get xsec from tb & kernel */ + bne- 2f /* out of line -> do syscall */ + + /* seconds are xsec >> 20 */ + rlwinm r5,r4,12,20,31 + rlwimi r5,r3,12,0,19 + stw r5,TVAL32_TV_SEC(r10) + + /* get remaining xsec and convert to usec. we scale + * up remaining xsec by 12 bits and get the top 32 bits + * of the multiplication + */ + rlwinm r5,r4,12,0,19 + lis r6,1000000 at h + ori r6,r6,1000000 at l + mulhwu r5,r5,r6 + stw r5,TVAL32_TV_USEC(r10) + + cmpli cr0,r11,0 /* check if tz is NULL */ + beq 1f + lwz r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */ + lwz r5,CFG_TZ_DSTTIME(r9) + stw r4,TZONE_TZ_MINWEST(r11) + stw r5,TZONE_TZ_DSTTIME(r11) + +1: mtlr r12 + blr + +2: mr r3,r10 + mr r4,r11 + li r0,__NR_gettimeofday + sc + b 1b + .cfi_endproc +V_FUNCTION_END(__kernel_gettimeofday) + +/* + * This is the core of gettimeofday(), it returns the xsec + * value in r3 & r4 and expects the datapage ptr (non clobbered) + * in r9. clobbers r0,r4,r5,r6,r7,r8 +*/ +__do_get_xsec: + .cfi_startproc + /* Check for update count & load values. We use the low + * order 32 bits of the update count + */ +1: lwz r8,(CFG_TB_UPDATE_COUNT+4)(r9) + andi. r0,r8,1 /* pending update ? loop */ + bne- 1b + xor r0,r8,r8 /* create dependency */ + add r9,r9,r0 + + /* Load orig stamp (offset to TB) */ + lwz r5,CFG_TB_ORIG_STAMP(r9) + lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) + + /* Get a stable TB value */ +2: mftbu r3 + mftbl r4 + mftbu r0 + cmpl cr0,r3,r0 + bne- 2b + + /* Substract tb orig stamp. If the high part is non-zero, we jump to the + * slow path which call the syscall. If it's ok, then we have our 32 bits + * tb_ticks value in r7 + */ + subfc r7,r6,r4 + subfe. r0,r5,r3 + bne- 3f + + /* Load scale factor & do multiplication */ + lwz r5,CFG_TB_TO_XS(r9) /* load values */ + lwz r6,(CFG_TB_TO_XS+4)(r9) + mulhwu r4,r7,r5 + mulhwu r6,r7,r6 + mullw r6,r7,r5 + addc r6,r6,r0 + + /* At this point, we have the scaled xsec value in r4 + XER:CA + * we load & add the stamp since epoch + */ + lwz r5,CFG_STAMP_XSEC(r9) + lwz r6,(CFG_STAMP_XSEC+4)(r9) + adde r4,r4,r6 + addze r3,r5 + + /* We now have our result in r3,r4. We create a fake dependency + * on that result and re-check the counter + */ + xor r0,r4,r4 + add r9,r9,r0 + lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9) + cmpl cr0,r8,r0 /* check if updated */ + bne- 1b + + /* Warning ! The caller expects CR:EQ to be set to indicate a + * successful calculation (so it won't fallback to the syscall + * method). We have overriden that CR bit in the counter check, + * but fortunately, the loop exit condition _is_ CR:EQ set, so + * we can exit safely here. If you change this code, be careful + * of that side effect. + */ +3: blr + .cfi_endproc Index: linux-work/arch/ppc64/kernel/vdso32/sigtramp.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso32/sigtramp.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,300 @@ +/* + * Signal trampolines for 32 bits processes in a ppc64 kernel for + * use in the vDSO + * + * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org), IBM Corp. + * Copyright (C) 2004 Alan Modra (amodra at au.ibm.com)), IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include + + .text + +/* The nop here is a hack. The dwarf2 unwind routines subtract 1 from + the return address to get an address in the middle of the presumed + call instruction. Since we don't have a call here, we artifically + extend the range covered by the unwind info by adding a nop before + the real start. */ + nop +V_FUNCTION_BEGIN(__kernel_sigtramp32) +.Lsig_start = . - 4 + li r0,__NR_sigreturn + sc +.Lsig_end: +V_FUNCTION_END(__kernel_sigtramp32) + +.Lsigrt_start: + nop +V_FUNCTION_BEGIN(__kernel_sigtramp_rt32) + li r0,__NR_rt_sigreturn + sc +.Lsigrt_end: +V_FUNCTION_END(__kernel_sigtramp_rt32) + + .section .eh_frame,"a", at progbits + +/* Register r1 can be found at offset 4 of a pt_regs structure. + A pointer to the pt_regs is stored in memory at the old sp plus PTREGS. */ +#define cfa_save \ + .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x71; .sleb128 PTREGS; /* DW_OP_breg1 */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x23; .uleb128 RSIZE; /* DW_OP_plus_uconst */ \ + .byte 0x06; /* DW_OP_deref */ \ +9: + +/* Register REGNO can be found at offset OFS of a pt_regs structure. + A pointer to the pt_regs is stored in memory at the old sp plus PTREGS. */ +#define rsave(regno, ofs) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x71; .sleb128 PTREGS; /* DW_OP_breg1 */ \ + .byte 0x06; /* DW_OP_deref */ \ + .ifne ofs; \ + .byte 0x23; .uleb128 ofs; /* DW_OP_plus_uconst */ \ + .endif; \ +9: + +/* If msr bit 1<<25 is set, then VMX register REGNO is at offset REGNO*16 + of the VMX reg struct. The VMX reg struct is at offset VREGS of + the pt_regs struct. This macro is for REGNO == 0, and contains + 'subroutines' that the other macros jump to. */ +#define vsave_msr0(regno) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno + 77; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x30 + regno; /* DW_OP_lit0 */ \ +2: \ + .byte 0x40; /* DW_OP_lit16 */ \ + .byte 0x1e; /* DW_OP_mul */ \ +3: \ + .byte 0x71; .sleb128 PTREGS; /* DW_OP_breg1 */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x12; /* DW_OP_dup */ \ + .byte 0x23; /* DW_OP_plus_uconst */ \ + .uleb128 33*RSIZE; /* msr offset */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x0c; .long 1 << 25; /* DW_OP_const4u */ \ + .byte 0x1a; /* DW_OP_and */ \ + .byte 0x12; /* DW_OP_dup, ret 0 if bra taken */ \ + .byte 0x30; /* DW_OP_lit0 */ \ + .byte 0x29; /* DW_OP_eq */ \ + .byte 0x28; .short 0x7fff; /* DW_OP_bra to end */ \ + .byte 0x13; /* DW_OP_drop, pop the 0 */ \ + .byte 0x23; .uleb128 VREGS; /* DW_OP_plus_uconst */ \ + .byte 0x22; /* DW_OP_plus */ \ + .byte 0x2f; .short 0x7fff; /* DW_OP_skip to end */ \ +9: + +/* If msr bit 1<<25 is set, then VMX register REGNO is at offset REGNO*16 + of the VMX reg struct. REGNO is 1 thru 31. */ +#define vsave_msr1(regno) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno + 77; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x30 + regno; /* DW_OP_lit n */ \ + .byte 0x2f; .short 2b - 9f; /* DW_OP_skip */ \ +9: + +/* If msr bit 1<<25 is set, then VMX register REGNO is at offset OFS of + the VMX save block. */ +#define vsave_msr2(regno, ofs) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno + 77; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x0a; .short ofs; /* DW_OP_const2u */ \ + .byte 0x2f; .short 3b - 9f; /* DW_OP_skip */ \ +9: + +/* VMX register REGNO is at offset OFS of the VMX save area. */ +#define vsave(regno, ofs) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno + 77; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x71; .sleb128 PTREGS; /* DW_OP_breg1 */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x23; .uleb128 VREGS; /* DW_OP_plus_uconst */ \ + .byte 0x23; .uleb128 ofs; /* DW_OP_plus_uconst */ \ +9: + +/* This is where the pt_regs pointer can be found on the stack. */ +#define PTREGS 64+28 + +/* Size of regs. */ +#define RSIZE 4 + +/* This is the offset of the VMX regs. */ +#define VREGS 48*RSIZE+34*8 + +/* Describe where general purpose regs are saved. */ +#define EH_FRAME_GEN \ + cfa_save; \ + rsave ( 0, 0*RSIZE); \ + rsave ( 2, 2*RSIZE); \ + rsave ( 3, 3*RSIZE); \ + rsave ( 4, 4*RSIZE); \ + rsave ( 5, 5*RSIZE); \ + rsave ( 6, 6*RSIZE); \ + rsave ( 7, 7*RSIZE); \ + rsave ( 8, 8*RSIZE); \ + rsave ( 9, 9*RSIZE); \ + rsave (10, 10*RSIZE); \ + rsave (11, 11*RSIZE); \ + rsave (12, 12*RSIZE); \ + rsave (13, 13*RSIZE); \ + rsave (14, 14*RSIZE); \ + rsave (15, 15*RSIZE); \ + rsave (16, 16*RSIZE); \ + rsave (17, 17*RSIZE); \ + rsave (18, 18*RSIZE); \ + rsave (19, 19*RSIZE); \ + rsave (20, 20*RSIZE); \ + rsave (21, 21*RSIZE); \ + rsave (22, 22*RSIZE); \ + rsave (23, 23*RSIZE); \ + rsave (24, 24*RSIZE); \ + rsave (25, 25*RSIZE); \ + rsave (26, 26*RSIZE); \ + rsave (27, 27*RSIZE); \ + rsave (28, 28*RSIZE); \ + rsave (29, 29*RSIZE); \ + rsave (30, 30*RSIZE); \ + rsave (31, 31*RSIZE); \ + rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \ + rsave (65, 36*RSIZE); /* lr */ \ + rsave (70, 38*RSIZE) /* cr */ + +/* Describe where the FP regs are saved. */ +#define EH_FRAME_FP \ + rsave (32, 48*RSIZE + 0*8); \ + rsave (33, 48*RSIZE + 1*8); \ + rsave (34, 48*RSIZE + 2*8); \ + rsave (35, 48*RSIZE + 3*8); \ + rsave (36, 48*RSIZE + 4*8); \ + rsave (37, 48*RSIZE + 5*8); \ + rsave (38, 48*RSIZE + 6*8); \ + rsave (39, 48*RSIZE + 7*8); \ + rsave (40, 48*RSIZE + 8*8); \ + rsave (41, 48*RSIZE + 9*8); \ + rsave (42, 48*RSIZE + 10*8); \ + rsave (43, 48*RSIZE + 11*8); \ + rsave (44, 48*RSIZE + 12*8); \ + rsave (45, 48*RSIZE + 13*8); \ + rsave (46, 48*RSIZE + 14*8); \ + rsave (47, 48*RSIZE + 15*8); \ + rsave (48, 48*RSIZE + 16*8); \ + rsave (49, 48*RSIZE + 17*8); \ + rsave (50, 48*RSIZE + 18*8); \ + rsave (51, 48*RSIZE + 19*8); \ + rsave (52, 48*RSIZE + 20*8); \ + rsave (53, 48*RSIZE + 21*8); \ + rsave (54, 48*RSIZE + 22*8); \ + rsave (55, 48*RSIZE + 23*8); \ + rsave (56, 48*RSIZE + 24*8); \ + rsave (57, 48*RSIZE + 25*8); \ + rsave (58, 48*RSIZE + 26*8); \ + rsave (59, 48*RSIZE + 27*8); \ + rsave (60, 48*RSIZE + 28*8); \ + rsave (61, 48*RSIZE + 29*8); \ + rsave (62, 48*RSIZE + 30*8); \ + rsave (63, 48*RSIZE + 31*8) + +/* Describe where the VMX regs are saved. */ +#ifdef CONFIG_ALTIVEC +#define EH_FRAME_VMX \ + vsave_msr0 ( 0); \ + vsave_msr1 ( 1); \ + vsave_msr1 ( 2); \ + vsave_msr1 ( 3); \ + vsave_msr1 ( 4); \ + vsave_msr1 ( 5); \ + vsave_msr1 ( 6); \ + vsave_msr1 ( 7); \ + vsave_msr1 ( 8); \ + vsave_msr1 ( 9); \ + vsave_msr1 (10); \ + vsave_msr1 (11); \ + vsave_msr1 (12); \ + vsave_msr1 (13); \ + vsave_msr1 (14); \ + vsave_msr1 (15); \ + vsave_msr1 (16); \ + vsave_msr1 (17); \ + vsave_msr1 (18); \ + vsave_msr1 (19); \ + vsave_msr1 (20); \ + vsave_msr1 (21); \ + vsave_msr1 (22); \ + vsave_msr1 (23); \ + vsave_msr1 (24); \ + vsave_msr1 (25); \ + vsave_msr1 (26); \ + vsave_msr1 (27); \ + vsave_msr1 (28); \ + vsave_msr1 (29); \ + vsave_msr1 (30); \ + vsave_msr1 (31); \ + vsave_msr2 (33, 32*16+12); \ + vsave (32, 32*16) +#else +#define EH_FRAME_VMX +#endif + +.Lcie: + .long .Lcie_end - .Lcie_start +.Lcie_start: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zR" /* NUL-terminated augmentation string */ + .uleb128 4 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 67 /* Return address register column, ap */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */ + .byte 0x0c,1,0 /* DW_CFA_def_cfa: r1 ofs 0 */ + .balign 4 +.Lcie_end: + + .long .Lfde0_end - .Lfde0_start +.Lfde0_start: + .long .Lfde0_start - .Lcie /* CIE pointer. */ + .long .Lsig_start - . /* PC start, length */ + .long .Lsig_end - .Lsig_start + .uleb128 0 /* Augmentation */ + EH_FRAME_GEN + EH_FRAME_FP + EH_FRAME_VMX + .balign 4 +.Lfde0_end: + +/* We have a different stack layout for rt_sigreturn. */ +#undef PTREGS +#define PTREGS 64+16+128+20+28 + + .long .Lfde1_end - .Lfde1_start +.Lfde1_start: + .long .Lfde1_start - .Lcie /* CIE pointer. */ + .long .Lsigrt_start - . /* PC start, length */ + .long .Lsigrt_end - .Lsigrt_start + .uleb128 0 /* Augmentation */ + EH_FRAME_GEN + EH_FRAME_FP + EH_FRAME_VMX + .balign 4 +.Lfde1_end: Index: linux-work/arch/ppc64/kernel/vdso32/vdso32_wrapper.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso32/vdso32_wrapper.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,12 @@ +#include + + .section ".data" + + .globl vdso32_start, vdso32_end + .balign 4096 +vdso32_start: + .incbin "arch/ppc64/kernel/vdso32/vdso32.so" + .balign 4096 +vdso32_end: + + .previous Index: linux-work/arch/ppc64/kernel/vdso64/vdso64.lds.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso64/vdso64.lds.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,110 @@ +/* + * This is the infamous ld script for the 64 bits vdso + * library + */ +#include + +OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc") +OUTPUT_ARCH(powerpc:common64) +ENTRY(_start) + +SECTIONS +{ + . = VDSO64_LBASE + SIZEOF_HEADERS; + .hash : { *(.hash) } :text + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + . = ALIGN (16); + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + *(.sfpr .glink) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + /* Other stuff is appended to the text segment: */ + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + .gcc_except_table : { *(.gcc_except_table) } + + .opd ALIGN(8) : { KEEP (*(.opd)) } + .got ALIGN(8) : { *(.got .toc) } + .rela.dyn ALIGN(8) : { *(.rela.dyn) } + + .dynamic : { *(.dynamic) } :text :dynamic + + _end = .; + PROVIDE (end = .); + + /* Stabs debugging sections are here too + */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sectio/ns. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + /DISCARD/ : { *(.note.GNU-stack) } + /DISCARD/ : { *(.branch_lt) } + /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.*) } + /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) } +} + +PHDRS +{ + text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ +} + +/* + * This controls what symbols we export from the DSO. + */ +VERSION +{ + VDSO_VERSION_STRING { + global: + __kernel_datapage_offset; /* Has to be there for the kernel to find it */ + __kernel_get_syscall_map; + __kernel_gettimeofday; + __kernel_sync_dicache; + __kernel_sync_dicache_p5; + __kernel_sigtramp_rt64; + local: *; + }; +} Index: linux-work/arch/ppc64/kernel/vdso64/vdso64_wrapper.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso64/vdso64_wrapper.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,12 @@ +#include + + .section ".data" + + .globl vdso64_start, vdso64_end + .balign 4096 +vdso64_start: + .incbin "arch/ppc64/kernel/vdso64/vdso64.so" + .balign 4096 +vdso64_end: + + .previous Index: linux-work/arch/ppc64/kernel/vdso32/datapage.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso32/datapage.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,68 @@ +/* + * Access to the shared data page by the vDSO & syscall map + * + * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org), IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + + .text +V_FUNCTION_BEGIN(__get_datapage) + .cfi_startproc + /* We don't want that exposed or overridable as we want other objects + * to be able to bl directly to here + */ + .protected __get_datapage + .hidden __get_datapage + + mflr r0 + .cfi_register lr,r0 + + bcl 20,31,1f + .global __kernel_datapage_offset; +__kernel_datapage_offset: + .long 0 +1: + mflr r3 + mtlr r0 + lwz r0,0(r3) + add r3,r0,r3 + blr + .cfi_endproc +V_FUNCTION_END(__get_datapage) + +/* + * void *__kernel_get_syscall_map(unsigned int *syscall_count) ; + * + * returns a pointer to the syscall map. the map is agnostic to the + * size of "long", unlike kernel bitops, it stores bits from top to + * bottom so that memory actually contains a linear bitmap + * check for syscall N by testing bit (0x80000000 >> (N & 0x1f)) of + * 32 bits int at N >> 5. + */ +V_FUNCTION_BEGIN(__kernel_get_syscall_map) + .cfi_startproc + mflr r12 + .cfi_register lr,r12 + + mr r4,r3 + bl __get_datapage at local + mtlr r12 + addi r3,r3,CFG_SYSCALL_MAP32 + cmpli cr0,r4,0 + beqlr + li r0,__NR_syscalls + stw r0,0(r4) + blr + .cfi_endproc +V_FUNCTION_END(__kernel_get_syscall_map) Index: linux-work/arch/ppc64/kernel/vdso32/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso32/Makefile 2005-02-01 12:04:11.000000000 +1100 @@ -0,0 +1,36 @@ + +# List of files in the vdso, has to be asm only for now + +obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o + +# Build rules + +targets := $(obj-vdso32) vdso32.so +obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) + + +EXTRA_CFLAGS := -shared -s -fno-common -fno-builtin +EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 +EXTRA_AFLAGS := -D__VDSO32__ -s + +obj-y += vdso32_wrapper.o +extra-y += vdso32.lds +CPPFLAGS_vdso32.lds += -P -C -U$(ARCH) + +# Force dependency (incbin is bad) +$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so + +# link rule for the .so file, .lds has to be first +$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) + $(call if_changed,vdso32ld) + +# assembly rules for the .S files +$(obj-vdso32): %.o: %.S + $(call if_changed_dep,vdso32as) + +# actual build commands +quiet_cmd_vdso32ld = VDSO32L $@ + cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $^ -o $@ +quiet_cmd_vdso32as = VDSO32A $@ + cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $< + Index: linux-work/arch/ppc64/kernel/vdso64/gettimeofday.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso64/gettimeofday.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,91 @@ +/* + * Userland implementation of gettimeofday() for 64 bits processes in a + * ppc64 kernel for use in the vDSO + * + * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org), + * IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include + + .text +/* + * Exact prototype of gettimeofday + * + * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); + * + */ +V_FUNCTION_BEGIN(__kernel_gettimeofday) + .cfi_startproc + mflr r12 + .cfi_register lr,r12 + + mr r11,r3 /* r11 holds tv */ + mr r10,r4 /* r10 holds tz */ + bl V_LOCAL_FUNC(__get_datapage) /* get data page */ + bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ + lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ + ori r7,r7,16960 + rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ + rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ + std r5,TVAL64_TV_SEC(r11) /* store sec in tv */ + subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ + mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / XSEC_PER_SEC */ + rldicl r0,r0,44,20 + cmpldi cr0,r10,0 /* check if tz is NULL */ + std r0,TVAL64_TV_USEC(r11) /* store usec in tv */ + beq 1f + lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */ + lwz r5,CFG_TZ_DSTTIME(r3) + stw r4,TZONE_TZ_MINWEST(r10) + stw r5,TZONE_TZ_DSTTIME(r10) +1: mtlr r12 + li r3,0 /* always success */ + blr + .cfi_endproc +V_FUNCTION_END(__kernel_gettimeofday) + + +/* + * This is the core of gettimeofday(), it returns the xsec + * value in r4 and expects the datapage ptr (non clobbered) + * in r3. clobbers r0,r4,r5,r6,r7,r8 +*/ +V_FUNCTION_BEGIN(__do_get_xsec) + .cfi_startproc + /* check for update count & load values */ +1: ld r7,CFG_TB_UPDATE_COUNT(r3) + andi. r0,r4,1 /* pending update ? loop */ + bne- 1b + xor r0,r4,r4 /* create dependency */ + add r3,r3,r0 + + /* Get TB & offset it */ + mftb r8 + ld r9,CFG_TB_ORIG_STAMP(r3) + subf r8,r9,r8 + + /* Scale result */ + ld r5,CFG_TB_TO_XS(r3) + mulhdu r8,r8,r5 + + /* Add stamp since epoch */ + ld r6,CFG_STAMP_XSEC(r3) + add r4,r6,r8 + + xor r0,r4,r4 + add r3,r3,r0 + ld r0,CFG_TB_UPDATE_COUNT(r3) + cmpld cr0,r0,r7 /* check if updated */ + bne- 1b + blr + .cfi_endproc +V_FUNCTION_END(__do_get_xsec) Index: linux-work/arch/ppc64/kernel/vdso64/datapage.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso64/datapage.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,68 @@ +/* + * Access to the shared data page by the vDSO & syscall map + * + * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org), IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + + .text +V_FUNCTION_BEGIN(__get_datapage) + .cfi_startproc + /* We don't want that exposed or overridable as we want other objects + * to be able to bl directly to here + */ + .protected __get_datapage + .hidden __get_datapage + + mflr r0 + .cfi_register lr,r0 + + bcl 20,31,1f + .global __kernel_datapage_offset; +__kernel_datapage_offset: + .long 0 +1: + mflr r3 + mtlr r0 + lwz r0,0(r3) + add r3,r0,r3 + blr + .cfi_endproc +V_FUNCTION_END(__get_datapage) + +/* + * void *__kernel_get_syscall_map(unsigned int *syscall_count) ; + * + * returns a pointer to the syscall map. the map is agnostic to the + * size of "long", unlike kernel bitops, it stores bits from top to + * bottom so that memory actually contains a linear bitmap + * check for syscall N by testing bit (0x80000000 >> (N & 0x1f)) of + * 32 bits int at N >> 5. + */ +V_FUNCTION_BEGIN(__kernel_get_syscall_map) + .cfi_startproc + mflr r12 + .cfi_register lr,r12 + + mr r4,r3 + bl V_LOCAL_FUNC(__get_datapage) + mtlr r12 + addi r3,r3,CFG_SYSCALL_MAP64 + cmpli cr0,r4,0 + beqlr + li r0,__NR_syscalls + stw r0,0(r4) + blr + .cfi_endproc +V_FUNCTION_END(__kernel_get_syscall_map) Index: linux-work/arch/ppc64/kernel/vdso64/sigtramp.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso64/sigtramp.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,294 @@ +/* + * Signal trampoline for 64 bits processes in a ppc64 kernel for + * use in the vDSO + * + * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org), IBM Corp. + * Copyright (C) 2004 Alan Modra (amodra at au.ibm.com)), IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include + + .text + +/* The nop here is a hack. The dwarf2 unwind routines subtract 1 from + the return address to get an address in the middle of the presumed + call instruction. Since we don't have a call here, we artifically + extend the range covered by the unwind info by padding before the + real start. */ + nop + .balign 8 +V_FUNCTION_BEGIN(__kernel_sigtramp_rt64) +.Lsigrt_start = . - 4 + addi r1, r1, __SIGNAL_FRAMESIZE + li r0,__NR_rt_sigreturn + sc +.Lsigrt_end: +V_FUNCTION_END(__kernel_sigtramp_rt64) +/* The ".balign 8" above and the following zeros mimic the old stack + trampoline layout. The last magic value is the ucontext pointer, + chosen in such a way that older libgcc unwind code returns a zero + for a sigcontext pointer. */ + .long 0,0,0 + .quad 0,-21*8 + +/* Register r1 can be found at offset 8 of a pt_regs structure. + A pointer to the pt_regs is stored in memory at the old sp plus PTREGS. */ +#define cfa_save \ + .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x71; .sleb128 PTREGS; /* DW_OP_breg1 */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x23; .uleb128 RSIZE; /* DW_OP_plus_uconst */ \ + .byte 0x06; /* DW_OP_deref */ \ +9: + +/* Register REGNO can be found at offset OFS of a pt_regs structure. + A pointer to the pt_regs is stored in memory at the old sp plus PTREGS. */ +#define rsave(regno, ofs) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x71; .sleb128 PTREGS; /* DW_OP_breg1 */ \ + .byte 0x06; /* DW_OP_deref */ \ + .ifne ofs; \ + .byte 0x23; .uleb128 ofs; /* DW_OP_plus_uconst */ \ + .endif; \ +9: + +/* If msr bit 1<<25 is set, then VMX register REGNO is at offset REGNO*16 + of the VMX reg struct. A pointer to the VMX reg struct is at VREGS in + the pt_regs struct. This macro is for REGNO == 0, and contains + 'subroutines' that the other macros jump to. */ +#define vsave_msr0(regno) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno + 77; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x30 + regno; /* DW_OP_lit0 */ \ +2: \ + .byte 0x40; /* DW_OP_lit16 */ \ + .byte 0x1e; /* DW_OP_mul */ \ +3: \ + .byte 0x71; .sleb128 PTREGS; /* DW_OP_breg1 */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x12; /* DW_OP_dup */ \ + .byte 0x23; /* DW_OP_plus_uconst */ \ + .uleb128 33*RSIZE; /* msr offset */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x0c; .long 1 << 25; /* DW_OP_const4u */ \ + .byte 0x1a; /* DW_OP_and */ \ + .byte 0x12; /* DW_OP_dup, ret 0 if bra taken */ \ + .byte 0x30; /* DW_OP_lit0 */ \ + .byte 0x29; /* DW_OP_eq */ \ + .byte 0x28; .short 0x7fff; /* DW_OP_bra to end */ \ + .byte 0x13; /* DW_OP_drop, pop the 0 */ \ + .byte 0x23; .uleb128 VREGS; /* DW_OP_plus_uconst */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x22; /* DW_OP_plus */ \ + .byte 0x2f; .short 0x7fff; /* DW_OP_skip to end */ \ +9: + +/* If msr bit 1<<25 is set, then VMX register REGNO is at offset REGNO*16 + of the VMX reg struct. REGNO is 1 thru 31. */ +#define vsave_msr1(regno) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno + 77; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x30 + regno; /* DW_OP_lit n */ \ + .byte 0x2f; .short 2b - 9f; /* DW_OP_skip */ \ +9: + +/* If msr bit 1<<25 is set, then VMX register REGNO is at offset OFS of + the VMX save block. */ +#define vsave_msr2(regno, ofs) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno + 77; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x0a; .short ofs; /* DW_OP_const2u */ \ + .byte 0x2f; .short 3b - 9f; /* DW_OP_skip */ \ +9: + +/* VMX register REGNO is at offset OFS of the VMX save area. */ +#define vsave(regno, ofs) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno + 77; /* regno */ \ + .uleb128 9f - 1f; /* length */ \ +1: \ + .byte 0x71; .sleb128 PTREGS; /* DW_OP_breg1 */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x23; .uleb128 VREGS; /* DW_OP_plus_uconst */ \ + .byte 0x06; /* DW_OP_deref */ \ + .byte 0x23; .uleb128 ofs; /* DW_OP_plus_uconst */ \ +9: + +/* This is where the pt_regs pointer can be found on the stack. */ +#define PTREGS 128+168+56 + +/* Size of regs. */ +#define RSIZE 8 + +/* This is the offset of the VMX reg pointer. */ +#define VREGS 48*RSIZE+33*8 + +/* Describe where general purpose regs are saved. */ +#define EH_FRAME_GEN \ + cfa_save; \ + rsave ( 0, 0*RSIZE); \ + rsave ( 2, 2*RSIZE); \ + rsave ( 3, 3*RSIZE); \ + rsave ( 4, 4*RSIZE); \ + rsave ( 5, 5*RSIZE); \ + rsave ( 6, 6*RSIZE); \ + rsave ( 7, 7*RSIZE); \ + rsave ( 8, 8*RSIZE); \ + rsave ( 9, 9*RSIZE); \ + rsave (10, 10*RSIZE); \ + rsave (11, 11*RSIZE); \ + rsave (12, 12*RSIZE); \ + rsave (13, 13*RSIZE); \ + rsave (14, 14*RSIZE); \ + rsave (15, 15*RSIZE); \ + rsave (16, 16*RSIZE); \ + rsave (17, 17*RSIZE); \ + rsave (18, 18*RSIZE); \ + rsave (19, 19*RSIZE); \ + rsave (20, 20*RSIZE); \ + rsave (21, 21*RSIZE); \ + rsave (22, 22*RSIZE); \ + rsave (23, 23*RSIZE); \ + rsave (24, 24*RSIZE); \ + rsave (25, 25*RSIZE); \ + rsave (26, 26*RSIZE); \ + rsave (27, 27*RSIZE); \ + rsave (28, 28*RSIZE); \ + rsave (29, 29*RSIZE); \ + rsave (30, 30*RSIZE); \ + rsave (31, 31*RSIZE); \ + rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \ + rsave (65, 36*RSIZE); /* lr */ \ + rsave (70, 38*RSIZE) /* cr */ + +/* Describe where the FP regs are saved. */ +#define EH_FRAME_FP \ + rsave (32, 48*RSIZE + 0*8); \ + rsave (33, 48*RSIZE + 1*8); \ + rsave (34, 48*RSIZE + 2*8); \ + rsave (35, 48*RSIZE + 3*8); \ + rsave (36, 48*RSIZE + 4*8); \ + rsave (37, 48*RSIZE + 5*8); \ + rsave (38, 48*RSIZE + 6*8); \ + rsave (39, 48*RSIZE + 7*8); \ + rsave (40, 48*RSIZE + 8*8); \ + rsave (41, 48*RSIZE + 9*8); \ + rsave (42, 48*RSIZE + 10*8); \ + rsave (43, 48*RSIZE + 11*8); \ + rsave (44, 48*RSIZE + 12*8); \ + rsave (45, 48*RSIZE + 13*8); \ + rsave (46, 48*RSIZE + 14*8); \ + rsave (47, 48*RSIZE + 15*8); \ + rsave (48, 48*RSIZE + 16*8); \ + rsave (49, 48*RSIZE + 17*8); \ + rsave (50, 48*RSIZE + 18*8); \ + rsave (51, 48*RSIZE + 19*8); \ + rsave (52, 48*RSIZE + 20*8); \ + rsave (53, 48*RSIZE + 21*8); \ + rsave (54, 48*RSIZE + 22*8); \ + rsave (55, 48*RSIZE + 23*8); \ + rsave (56, 48*RSIZE + 24*8); \ + rsave (57, 48*RSIZE + 25*8); \ + rsave (58, 48*RSIZE + 26*8); \ + rsave (59, 48*RSIZE + 27*8); \ + rsave (60, 48*RSIZE + 28*8); \ + rsave (61, 48*RSIZE + 29*8); \ + rsave (62, 48*RSIZE + 30*8); \ + rsave (63, 48*RSIZE + 31*8) + +/* Describe where the VMX regs are saved. */ +#ifdef CONFIG_ALTIVEC +#define EH_FRAME_VMX \ + vsave_msr0 ( 0); \ + vsave_msr1 ( 1); \ + vsave_msr1 ( 2); \ + vsave_msr1 ( 3); \ + vsave_msr1 ( 4); \ + vsave_msr1 ( 5); \ + vsave_msr1 ( 6); \ + vsave_msr1 ( 7); \ + vsave_msr1 ( 8); \ + vsave_msr1 ( 9); \ + vsave_msr1 (10); \ + vsave_msr1 (11); \ + vsave_msr1 (12); \ + vsave_msr1 (13); \ + vsave_msr1 (14); \ + vsave_msr1 (15); \ + vsave_msr1 (16); \ + vsave_msr1 (17); \ + vsave_msr1 (18); \ + vsave_msr1 (19); \ + vsave_msr1 (20); \ + vsave_msr1 (21); \ + vsave_msr1 (22); \ + vsave_msr1 (23); \ + vsave_msr1 (24); \ + vsave_msr1 (25); \ + vsave_msr1 (26); \ + vsave_msr1 (27); \ + vsave_msr1 (28); \ + vsave_msr1 (29); \ + vsave_msr1 (30); \ + vsave_msr1 (31); \ + vsave_msr2 (33, 32*16+12); \ + vsave (32, 33*16) +#else +#define EH_FRAME_VMX +#endif + + .section .eh_frame,"a", at progbits +.Lcie: + .long .Lcie_end - .Lcie_start +.Lcie_start: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zR" /* NUL-terminated augmentation string */ + .uleb128 4 /* Code alignment factor */ + .sleb128 -8 /* Data alignment factor */ + .byte 67 /* Return address register column, ap */ + .uleb128 1 /* Augmentation value length */ + .byte 0x14 /* DW_EH_PE_pcrel | DW_EH_PE_udata8. */ + .byte 0x0c,1,0 /* DW_CFA_def_cfa: r1 ofs 0 */ + .balign 8 +.Lcie_end: + + .long .Lfde0_end - .Lfde0_start +.Lfde0_start: + .long .Lfde0_start - .Lcie /* CIE pointer. */ + .quad .Lsigrt_start - . /* PC start, length */ + .quad .Lsigrt_end - .Lsigrt_start + .uleb128 0 /* Augmentation */ + EH_FRAME_GEN + EH_FRAME_FP + EH_FRAME_VMX +# Do we really need to describe the frame at this point? ie. will +# we ever have some call chain that returns somewhere past the addi? +# I don't think so, since gcc doesn't support async signals. +# .byte 0x41 /* DW_CFA_advance_loc 1*4 */ +#undef PTREGS +#define PTREGS 168+56 +# EH_FRAME_GEN +# EH_FRAME_FP +# EH_FRAME_VMX + .balign 8 +.Lfde0_end: Index: linux-work/arch/ppc64/kernel/vdso64/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso64/Makefile 2005-02-01 11:51:25.000000000 +1100 @@ -0,0 +1,35 @@ +# List of files in the vdso, has to be asm only for now + +obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o + +# Build rules + +targets := $(obj-vdso64) vdso64.so +obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) + +EXTRA_CFLAGS := -shared -s -fno-common -fno-builtin +EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 +EXTRA_AFLAGS := -D__VDSO64__ -s + +obj-y += vdso64_wrapper.o +extra-y += vdso64.lds +CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) + +# Force dependency (incbin is bad) +$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so + +# link rule for the .so file, .lds has to be first +$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) + $(call if_changed,vdso64ld) + +# assembly rules for the .S files +$(obj-vdso64): %.o: %.S + $(call if_changed_dep,vdso64as) + +# actual build commands +quiet_cmd_vdso64ld = VDSO64L $@ + cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@ +quiet_cmd_vdso64as = VDSO64A $@ + cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $< + + Index: linux-work/arch/ppc64/kernel/vdso32/vdso32.lds.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso32/vdso32.lds.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,111 @@ + +/* + * This is the infamous ld script for the 32 bits vdso + * library + */ +#include + +/* Default link addresses for the vDSOs */ +OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") +OUTPUT_ARCH(powerpc:common) +ENTRY(_start) + +SECTIONS +{ + . = VDSO32_LBASE + SIZEOF_HEADERS; + .hash : { *(.hash) } :text + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + + . = ALIGN (16); + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + /* Other stuff is appended to the text segment: */ + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + .gcc_except_table : { *(.gcc_except_table) } + .fixup : { *(.fixup) } + + .got ALIGN(4) : { *(.got.plt) *(.got) } + + .dynamic : { *(.dynamic) } :text :dynamic + + _end = .; + __end = .; + PROVIDE (end = .); + + + /* Stabs debugging sections are here too + */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + /DISCARD/ : { *(.note.GNU-stack) } + /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.* .sdata*) } + /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) } +} + + +PHDRS +{ + text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ + eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ +} + + +/* + * This controls what symbols we export from the DSO. + */ +VERSION +{ + VDSO_VERSION_STRING { + global: + __kernel_datapage_offset; /* Has to be there for the kernel to find it */ + __kernel_get_syscall_map; + __kernel_gettimeofday; + __kernel_sync_dicache; + __kernel_sync_dicache_p5; + __kernel_sigtramp32; + __kernel_sigtramp_rt32; + local: *; + }; +} Index: linux-work/arch/ppc64/kernel/vdso32/cacheflush.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso32/cacheflush.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,65 @@ +/* + * vDSO provided cache flush routines + * + * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org), + * IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include + + .text + +/* + * Default "generic" version of __kernel_sync_dicache. + * + * void __kernel_sync_dicache(unsigned long start, unsigned long end) + * + * Flushes the data cache & invalidate the instruction cache for the + * provided range [start, end[ + * + * Note: all CPUs supported by this kernel have a 128 bytes cache + * line size so we don't have to peek that info from the datapage + */ +V_FUNCTION_BEGIN(__kernel_sync_dicache) + .cfi_startproc + li r5,127 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + srwi. r8,r8,7 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 + mr r3,r6 +1: dcbst 0,r3 + addi r3,r3,128 + bdnz 1b + sync + mtctr r8 +1: icbi 0,r6 + addi r6,r6,128 + bdnz 1b + isync + blr + .cfi_endproc +V_FUNCTION_END(__kernel_sync_dicache) + + +/* + * POWER5 version of __kernel_sync_dicache + */ +V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) + .cfi_startproc + sync + isync + blr + .cfi_endproc +V_FUNCTION_END(__kernel_sync_dicache_p5) + Index: linux-work/arch/ppc64/kernel/vdso64/cacheflush.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-work/arch/ppc64/kernel/vdso64/cacheflush.S 2005-01-31 16:25:56.000000000 +1100 @@ -0,0 +1,64 @@ +/* + * vDSO provided cache flush routines + * + * Copyright (C) 2004 Benjamin Herrenschmuidt (benh at kernel.crashing.org), + * IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include + + .text + +/* + * Default "generic" version of __kernel_sync_dicache. + * + * void __kernel_sync_dicache(unsigned long start, unsigned long end) + * + * Flushes the data cache & invalidate the instruction cache for the + * provided range [start, end[ + * + * Note: all CPUs supported by this kernel have a 128 bytes cache + * line size so we don't have to peek that info from the datapage + */ +V_FUNCTION_BEGIN(__kernel_sync_dicache) + .cfi_startproc + li r5,127 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + srwi. r8,r8,7 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 + mr r3,r6 +1: dcbst 0,r3 + addi r3,r3,128 + bdnz 1b + sync + mtctr r8 +1: icbi 0,r6 + addi r6,r6,128 + bdnz 1b + isync + blr + .cfi_endproc +V_FUNCTION_END(__kernel_sync_dicache) + + +/* + * POWER5 version of __kernel_sync_dicache + */ +V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) + .cfi_startproc + sync + isync + blr + .cfi_endproc +V_FUNCTION_END(__kernel_sync_dicache_p5) Index: linux-work/arch/ppc64/kernel/head.S =================================================================== --- linux-work.orig/arch/ppc64/kernel/head.S 2005-01-31 16:19:44.000000000 +1100 +++ linux-work/arch/ppc64/kernel/head.S 2005-01-31 16:25:56.000000000 +1100 @@ -54,7 +54,6 @@ * 0x0100 - 0x2fff : pSeries Interrupt prologs * 0x3000 - 0x3fff : Interrupt support * 0x4000 - 0x4fff : NACA - * 0x5000 - 0x5fff : SystemCfg * 0x6000 : iSeries and common interrupt prologs * 0x9000 - 0x9fff : Initial segment table */ Index: linux-work/arch/ppc64/boot/Makefile =================================================================== --- linux-work.orig/arch/ppc64/boot/Makefile 2005-01-31 14:18:14.000000000 +1100 +++ linux-work/arch/ppc64/boot/Makefile 2005-02-01 11:50:33.000000000 +1100 @@ -20,17 +20,11 @@ # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE # in the toplevel makefile. -CROSS32_COMPILE ?= -#CROSS32_COMPILE = /usr/local/ppc/bin/powerpc-linux- -BOOTCC := $(CROSS32_COMPILE)gcc HOSTCC := gcc BOOTCFLAGS := $(HOSTCFLAGS) $(LINUXINCLUDE) -fno-builtin -BOOTAS := $(CROSS32_COMPILE)as BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -BOOTLD := $(CROSS32_COMPILE)ld BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds -BOOTOBJCOPY := $(CROSS32_COMPILE)objcopy OBJCOPYFLAGS := contents,alloc,load,readonly,data src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S @@ -38,10 +32,10 @@ obj-boot := $(addsuffix .o, $(basename $(src-boot))) quiet_cmd_bootcc = BOOTCC $@ - cmd_bootcc = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< + cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< quiet_cmd_bootas = BOOTAS $@ - cmd_bootas = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< + cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c $(call if_changed_dep,bootcc) @@ -77,15 +71,15 @@ $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE $(call if_changed,ramdisk) -addsection = $(BOOTOBJCOPY) $(1) \ +addsection = $(CROSS32OBJCOPY) $(1) \ --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) quiet_cmd_addnote = ADDNOTE $@ - cmd_addnote = $(BOOTLD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ + cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ quiet_cmd_piggy = PIGGY $@ - cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(BOOTAS) -o $@ + cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@ $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE $(call if_changed,gzip) From benh at kernel.crashing.org Tue Feb 1 14:15:27 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 01 Feb 2005 14:15:27 +1100 Subject: pci: Arch hook to determine config space size In-Reply-To: <41FEB492.2020002@us.ibm.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> <41FEA4AA.1080407@us.ibm.com> <200501312256.44692.arnd@arndb.de> <41FEB492.2020002@us.ibm.com> Message-ID: <1107227727.5963.46.camel@gaston> On Mon, 2005-01-31 at 16:43 -0600, Brian King wrote: > diff -puN include/asm-ppc64/prom.h~ppc64_pcix_mode2_cfg include/asm-ppc64/prom.h > --- linux-2.6.11-rc2-bk9/include/asm-ppc64/prom.h~ppc64_pcix_mode2_cfg 2005-01-31 14:32:01.000000000 -0600 > +++ linux-2.6.11-rc2-bk9-bjking1/include/asm-ppc64/prom.h 2005-01-31 14:32:01.000000000 -0600 > @@ -137,6 +137,7 @@ struct device_node { > int devfn; /* for pci devices */ > int eeh_mode; /* See eeh.h for possible EEH_MODEs */ > int eeh_config_addr; > + int pci_ext_config_space; /* for phb's or bridges */ > struct pci_controller *phb; /* for pci devices */ > struct iommu_table *iommu_table; /* for phb's or bridges */ Grrr... more crap added to the device-node, I don't like that ... This is a PHB only field, can't it be in struct pci_controller instead ? Ben. From brking at us.ibm.com Tue Feb 1 15:52:29 2005 From: brking at us.ibm.com (Brian King) Date: Mon, 31 Jan 2005 22:52:29 -0600 Subject: pci: Arch hook to determine config space size In-Reply-To: <1107227727.5963.46.camel@gaston> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> <41FEA4AA.1080407@us.ibm.com> <200501312256.44692.arnd@arndb.de> <41FEB492.2020002@us.ibm.com> <1107227727.5963.46.camel@gaston> Message-ID: <41FF0B0D.8020003@us.ibm.com> Benjamin Herrenschmidt wrote: > On Mon, 2005-01-31 at 16:43 -0600, Brian King wrote: > > >>diff -puN include/asm-ppc64/prom.h~ppc64_pcix_mode2_cfg include/asm-ppc64/prom.h >>--- linux-2.6.11-rc2-bk9/include/asm-ppc64/prom.h~ppc64_pcix_mode2_cfg 2005-01-31 14:32:01.000000000 -0600 >>+++ linux-2.6.11-rc2-bk9-bjking1/include/asm-ppc64/prom.h 2005-01-31 14:32:01.000000000 -0600 >>@@ -137,6 +137,7 @@ struct device_node { >> int devfn; /* for pci devices */ >> int eeh_mode; /* See eeh.h for possible EEH_MODEs */ >> int eeh_config_addr; >>+ int pci_ext_config_space; /* for phb's or bridges */ >> struct pci_controller *phb; /* for pci devices */ >> struct iommu_table *iommu_table; /* for phb's or bridges */ > > > Grrr... more crap added to the device-node, I don't like that ... > > This is a PHB only field, can't it be in struct pci_controller instead ? Assuming I am reading the spec correctly, this is only a property of the PHB, so I could move it into the pci_controller struct instead. -- Brian King eServer Storage I/O IBM Linux Technology Center -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ppc64_pcix_mode2_cfg.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050131/738fdf76/attachment.txt From sfr at canb.auug.org.au Tue Feb 1 15:59:01 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Tue, 1 Feb 2005 15:59:01 +1100 Subject: [PATCH] ppc64 iseries: can't remove viocd module when no cdroms Message-ID: <20050201155901.62d7c14d.sfr@canb.auug.org.au> Hi Andrew, This patch fixes a bug where attempting to remove the viocd module when no virtual cdroms where actually present would cause an oops. The driver was not completing its initialisation in this case. Signed-off-by: Stephen Rothwell -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN linus-bk/drivers/cdrom/viocd.c linus-bk.viocd.1/drivers/cdrom/viocd.c --- linus-bk/drivers/cdrom/viocd.c 2004-11-16 16:05:11.000000000 +1100 +++ linus-bk.viocd.1/drivers/cdrom/viocd.c 2005-02-01 15:52:03.000000000 +1100 @@ -765,8 +765,6 @@ vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event); get_viocd_info(); - if (viocd_numdev == 0) - goto out_undo_vio; spin_lock_init(&viocd_reqlock); @@ -786,7 +784,6 @@ dma_free_coherent(iSeries_vio_dev, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, viocd_unitinfo, unitinfo_dmaaddr); -out_undo_vio: vio_clearHandler(viomajorsubtype_cdio); viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); out_unregister: -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050201/2b951bc5/attachment.pgp From benh at kernel.crashing.org Tue Feb 1 15:57:44 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 01 Feb 2005 15:57:44 +1100 Subject: pci: Arch hook to determine config space size In-Reply-To: <41FF0B0D.8020003@us.ibm.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> <41FEA4AA.1080407@us.ibm.com> <200501312256.44692.arnd@arndb.de> <41FEB492.2020002@us.ibm.com> <1107227727.5963.46.camel@gaston> <41FF0B0D.8020003@us.ibm.com> Message-ID: <1107233864.5963.65.camel@gaston> On Mon, 2005-01-31 at 22:52 -0600, Brian King wrote: > Assuming I am reading the spec correctly, this is only a property of the > PHB, so I could move it into the pci_controller struct instead. Note that Arnd seems to imply the opposite ... BTW. I'm thinking about moving all those PCI/VIO related fields out of struct device_node to their own structure and keep only a pointer to that structure in device_node. That way, we avoid the bloat for every single non-pci node in the system, and we can have different structures for different bus types (along with proper iommu function pointers and that sort-of-thing). So if you think you really need a per-device info here, feel free to add it to device_node for now, and I'll move it to the new structure along with the rest of the stuff once I find time to do this patch. Ben. From sam at ravnborg.org Tue Feb 1 16:41:49 2005 From: sam at ravnborg.org (Sam Ravnborg) Date: Tue, 1 Feb 2005 06:41:49 +0100 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline In-Reply-To: <1107218282.5906.33.camel@gaston> References: <1107151447.5712.81.camel@gaston> <20050131192713.GA16268@mars.ravnborg.org> <1107218282.5906.33.camel@gaston> Message-ID: <20050201054149.GA8136@mars.ravnborg.org> On Tue, Feb 01, 2005 at 11:38:02AM +1100, Benjamin Herrenschmidt wrote: > > > Also notice that ':=' uses all over. No need to use late evaluation when > > no dynamic references are used ($ $@ etc.). > > Hrm... Rusty tells me that you got it backward ;) Anyway, I'll stick > to := for now, it's not really an issue. := Right hand side is evaluated when encountered. Often what you want. So for example CC := cc here CC is assigned the value cc when seen. = Right hand side is evaluated only when left hand side is used. Also very usefull. Example just mocked up: cmd_vdso32_cc = $(CC) -T $^ -o $@ Doing late evaluation will cause correct replacement of $^ and $@ when used. When cmd_vdso_32 is defined make does not know the desired values for $^ and $@ - this is only known when cmd_vdso_32 is actually used. Hope this clarifies it. Sam From sam at ravnborg.org Tue Feb 1 16:45:47 2005 From: sam at ravnborg.org (Sam Ravnborg) Date: Tue, 1 Feb 2005 06:45:47 +0100 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline #2 In-Reply-To: <1107222584.5906.43.camel@gaston> References: <1107222584.5906.43.camel@gaston> Message-ID: <20050201054547.GB8136@mars.ravnborg.org> On Tue, Feb 01, 2005 at 12:49:44PM +1100, Benjamin Herrenschmidt wrote: core-y += arch/ppc64/kernel/ > +core-y += arch/ppc64/kernel/vdso32/ > +core-y += arch/ppc64/kernel/vdso64/ Please include your previous change to reflect this in arch/ppc64/kernel/Makefile It is much more obvious to look up this in the Makefile like we do for the rest of the kernel. Sam From benh at kernel.crashing.org Tue Feb 1 16:55:01 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 01 Feb 2005 16:55:01 +1100 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline In-Reply-To: <20050201054149.GA8136@mars.ravnborg.org> References: <1107151447.5712.81.camel@gaston> <20050131192713.GA16268@mars.ravnborg.org> <1107218282.5906.33.camel@gaston> <20050201054149.GA8136@mars.ravnborg.org> Message-ID: <1107237301.5963.67.camel@gaston> > Right hand side is evaluated only when left hand side is used. > Also very usefull. Example just mocked up: > cmd_vdso32_cc = $(CC) -T $^ -o $@ > > Doing late evaluation will cause correct replacement of $^ and $@ when > used. When cmd_vdso_32 is defined make does not know the desired values > for $^ and $@ - this is only known when cmd_vdso_32 is actually used. > > Hope this clarifies it. Definitely, thanks. Ben. From grundler at parisc-linux.org Tue Feb 1 18:46:57 2005 From: grundler at parisc-linux.org (Grant Grundler) Date: Tue, 1 Feb 2005 00:46:57 -0700 Subject: pci: Arch hook to determine config space size In-Reply-To: <41FE8994.4040802@us.ibm.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050128185234.GB21760@infradead.org> <20050129040647.GA6261@kroah.com> <41FE82B6.9060407@us.ibm.com> <41FE8994.4040802@us.ibm.com> Message-ID: <20050201074657.GA548@colo.lackof.org> On Mon, Jan 31, 2005 at 01:40:04PM -0600, Brian King wrote: > CC'ing the linux-pci mailing list... thanks... > > This patch adds an arch hook so > > that individual archs can indicate if the underlying system supports > > expanded config space accesses or not. > >@@ -653,6 +653,8 @@ static int pci_cfg_space_size(struct pci > > goto fail; > > } > > > >+ if (!pcibios_exp_cfg_space(dev)) > >+ goto fail; > > if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) > > goto fail; pci_read_config_dword lands in arch specific code. See drivers/pci/access.c:PCI_OP_READ() macro. I'm missing what pcibios_exp_cfg_space() does that can't be handled by the bus_ops supplied by pci_scan_bus(). I would expect the pci_read_config_dword to fail for being out of bounds. Is that wrong? Or is bus_ops not feasible in this case because pcibios needs access to pci_dev? If it's feasible, maybe the right place to add this hook is to pci_read_config_dword which is also handed the pci_dev. And add another function pointer to bus_ops (which could be NULL) to check chipset support for Expanded Config space before calling pci_bus_read_config_dword. Thats cleaner than adding a hook before each use of pci_read_config_dword. hth, grant From matthew at wil.cx Tue Feb 1 23:32:49 2005 From: matthew at wil.cx (Matthew Wilcox) Date: Tue, 1 Feb 2005 12:32:49 +0000 Subject: pci: Arch hook to determine config space size In-Reply-To: <41FF0B0D.8020003@us.ibm.com> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> <41FEA4AA.1080407@us.ibm.com> <200501312256.44692.arnd@arndb.de> <41FEB492.2020002@us.ibm.com> <1107227727.5963.46.camel@gaston> <41FF0B0D.8020003@us.ibm.com> Message-ID: <20050201123249.GA10088@parcelfarce.linux.theplanet.co.uk> On Mon, Jan 31, 2005 at 10:52:29PM -0600, Brian King wrote: > @@ -62,8 +72,11 @@ static int rtas_read_config(struct devic > return PCIBIOS_DEVICE_NOT_FOUND; > if (where & (size - 1)) > return PCIBIOS_BAD_REGISTER_NUMBER; You should probably delete this redundant test at the same time ... > + if (!config_access_valid(dn, where)) > + return PCIBIOS_BAD_REGISTER_NUMBER; > > - addr = (dn->busno << 16) | (dn->devfn << 8) | where; > + addr = ((where & 0xf00) << 20) | (dn->busno << 16) | > + (dn->devfn << 8) | (where & 0xff); > buid = dn->phb->buid; > if (buid) { > ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, -- "Next the statesmen will invent cheap lies, putting the blame upon the nation that is attacked, and every man will be glad of those conscience-soothing falsities, and will diligently study them, and refuse to examine any refutations of them; and thus he will by and by convince himself that the war is just, and will thank God for the better sleep he enjoys after this process of grotesque self-deception." -- Mark Twain From brking at us.ibm.com Wed Feb 2 02:23:36 2005 From: brking at us.ibm.com (Brian King) Date: Tue, 01 Feb 2005 09:23:36 -0600 Subject: pci: Arch hook to determine config space size In-Reply-To: <20050201074657.GA548@colo.lackof.org> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050128185234.GB21760@infradead.org> <20050129040647.GA6261@kroah.com> <41FE82B6.9060407@us.ibm.com> <41FE8994.4040802@us.ibm.com> <20050201074657.GA548@colo.lackof.org> Message-ID: <41FF9EF8.2000101@us.ibm.com> Grant Grundler wrote: > On Mon, Jan 31, 2005 at 01:40:04PM -0600, Brian King wrote: > >>CC'ing the linux-pci mailing list... > > > thanks... > > >>>This patch adds an arch hook so >>>that individual archs can indicate if the underlying system supports >>>expanded config space accesses or not. > > >>>@@ -653,6 +653,8 @@ static int pci_cfg_space_size(struct pci >>> goto fail; >>> } >>> >>>+ if (!pcibios_exp_cfg_space(dev)) >>>+ goto fail; >>> if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) >>> goto fail; > > > pci_read_config_dword lands in arch specific code. > See drivers/pci/access.c:PCI_OP_READ() macro. > > I'm missing what pcibios_exp_cfg_space() does that can't be handled by > the bus_ops supplied by pci_scan_bus(). > > I would expect the pci_read_config_dword to fail for being out of bounds. > Is that wrong? > Or is bus_ops not feasible in this case because pcibios needs access > to pci_dev? The current patch for this has become essentially that. It is now a PPC64 specific patch that adds bounds checking in the PPC64 PCI config access functions. -Brian -- Brian King eServer Storage I/O IBM Linux Technology Center From zwane at arm.linux.org.uk Wed Feb 2 05:25:14 2005 From: zwane at arm.linux.org.uk (Zwane Mwaikambo) Date: Tue, 1 Feb 2005 11:25:14 -0700 (MST) Subject: [PATCH] PPC64: Generic hotplug cpu support Message-ID: Patch provides a generic hotplug cpu implementation, with the only current user being pmac. This doesn't replace real hotplug code as is currently used by LPAR systems. Ben i can add the additional pmac specific code to put the processor into a sleeping state seperately. Thanks to Nathan for testing. arch/ppc64/Kconfig | 2 arch/ppc64/kernel/idle.c | 4 + arch/ppc64/kernel/irq.c | 29 +++++++++++++ arch/ppc64/kernel/pSeries_setup.c | 5 +- arch/ppc64/kernel/pmac_setup.c | 3 + arch/ppc64/kernel/pmac_smp.c | 5 ++ arch/ppc64/kernel/setup.c | 3 - arch/ppc64/kernel/smp.c | 80 ++++++++++++++++++++++++++++++++++++++ arch/ppc64/kernel/sysfs.c | 6 -- include/asm-ppc64/machdep.h | 1 include/asm-ppc64/smp.h | 9 +++- 11 files changed, 136 insertions(+), 11 deletions(-) Signed-off-by: Zwane Mwaikambo Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/Kconfig =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/Kconfig,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 Kconfig --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/Kconfig 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/Kconfig 1 Feb 2005 05:01:10 -0000 @@ -313,7 +313,7 @@ source "drivers/pci/Kconfig" config HOTPLUG_CPU bool "Support for hot-pluggable CPUs" - depends on SMP && EXPERIMENTAL && PPC_PSERIES + depends on SMP && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC) select HOTPLUG ---help--- Say Y here to be able to turn CPUs off and on. Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/idle.c =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/kernel/idle.c,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 idle.c --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/idle.c 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/idle.c 1 Feb 2005 06:32:09 -0000 @@ -293,6 +293,10 @@ static int native_idle(void) power4_idle(); if (need_resched()) schedule(); + + if (cpu_is_offline(smp_processor_id()) && + system_state == SYSTEM_RUNNING) + cpu_die(); } return 0; } Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/irq.c =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/kernel/irq.c,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 irq.c --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/irq.c 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/irq.c 1 Feb 2005 05:18:21 -0000 @@ -115,6 +115,35 @@ skip: return 0; } +#ifdef CONFIG_HOTPLUG_CPU +void fixup_irqs(cpumask_t map) +{ + unsigned int irq; + static int warned; + + for_each_irq(irq) { + cpumask_t mask; + + if (irq_desc[irq].status & IRQ_PER_CPU) + continue; + + cpus_and(mask, irq_affinity[irq], map); + if (any_online_cpu(mask) == NR_CPUS) { + printk("Breaking affinity for irq %i\n", irq); + mask = map; + } + if (irq_desc[irq].handler->set_affinity) + irq_desc[irq].handler->set_affinity(irq, mask); + else if (irq_desc[irq].action && !(warned++)) + printk("Cannot set affinity for irq %i\n", irq); + } + + local_irq_enable(); + mdelay(1); + local_irq_disable(); +} +#endif + extern int noirqdebug; /* Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pSeries_setup.c =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/kernel/pSeries_setup.c,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 pSeries_setup.c --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pSeries_setup.c 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pSeries_setup.c 1 Feb 2005 05:01:10 -0000 @@ -320,8 +320,9 @@ static void __init pSeries_discover_pic } } -static void pSeries_cpu_die(void) +static void pSeries_mach_cpu_die(void) { + idle_task_exit(); local_irq_disable(); /* Some hardware requires clearing the CPPR, while other hardware does not * it is safe either way @@ -599,7 +600,7 @@ struct machdep_calls __initdata pSeries_ .power_off = rtas_power_off, .halt = rtas_halt, .panic = rtas_os_term, - .cpu_die = pSeries_cpu_die, + .cpu_die = pSeries_mach_cpu_die, .get_boot_time = pSeries_get_boot_time, .get_rtc_time = pSeries_get_rtc_time, .set_rtc_time = pSeries_set_rtc_time, Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pmac_setup.c =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/kernel/pmac_setup.c,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 pmac_setup.c --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pmac_setup.c 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pmac_setup.c 1 Feb 2005 06:49:25 -0000 @@ -439,6 +439,9 @@ static int __init pmac_probe(int platfor } struct machdep_calls __initdata pmac_md = { +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = generic_mach_cpu_die, +#endif .probe = pmac_probe, .setup_arch = pmac_setup_arch, .init_early = pmac_init_early, Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pmac_smp.c =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/kernel/pmac_smp.c,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 pmac_smp.c --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pmac_smp.c 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/pmac_smp.c 1 Feb 2005 06:50:02 -0000 @@ -308,4 +308,9 @@ struct smp_ops_t core99_smp_ops __pmacda void __init pmac_setup_smp(void) { smp_ops = &core99_smp_ops; +#ifdef CONFIG_HOTPLUG_CPU + smp_ops->cpu_enable = generic_cpu_enable; + smp_ops->cpu_disable = generic_cpu_disable; + smp_ops->cpu_die = generic_cpu_die; +#endif } Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/setup.c =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/kernel/setup.c,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 setup.c --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/setup.c 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/setup.c 1 Feb 2005 06:25:29 -0000 @@ -1345,9 +1345,6 @@ early_param("xmon", early_xmon); void cpu_die(void) { - idle_task_exit(); if (ppc_md.cpu_die) ppc_md.cpu_die(); - local_irq_disable(); - for (;;); } Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/smp.c =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/kernel/smp.c,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 smp.c --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/smp.c 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/smp.c 1 Feb 2005 06:36:42 -0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -406,10 +407,89 @@ void __devinit smp_prepare_boot_cpu(void current_set[boot_cpuid] = current->thread_info; } +#ifdef CONFIG_HOTPLUG_CPU +/* State of each CPU during hotplug phases */ +DEFINE_PER_CPU(int, cpu_state) = { 0 }; + +int generic_cpu_disable(void) +{ + unsigned int cpu = smp_processor_id(); + + if (cpu == boot_cpuid) + return -EBUSY; + + systemcfg->processorCount--; + cpu_clear(cpu, cpu_online_map); + fixup_irqs(cpu_online_map); + return 0; +} + +int generic_cpu_enable(unsigned int cpu) +{ + /* Do the normal bootup if we haven't + * already bootstrapped. */ + if (system_state != SYSTEM_RUNNING) + return -ENOSYS; + + /* get the target out of it's holding state */ + per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; + wmb(); + + while (!cpu_online(cpu)) + cpu_relax(); + + fixup_irqs(cpu_online_map); + /* counter the irq disable in fixup_irqs */ + local_irq_enable(); + return 0; +} + +void generic_cpu_die(unsigned int cpu) +{ + int i; + + for (i = 0; i < 100; i++) { + rmb(); + if (per_cpu(cpu_state, cpu) == CPU_DEAD) + return; + msleep(100); + } + printk(KERN_ERR "CPU%d didn't die...\n", cpu); +} + +void generic_mach_cpu_die(void) +{ + unsigned int cpu; + + local_irq_disable(); + cpu = smp_processor_id(); + printk(KERN_DEBUG "CPU%d offline\n", cpu); + __get_cpu_var(cpu_state) = CPU_DEAD; + wmb(); + while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) + cpu_relax(); + + flush_tlb_pending(); + cpu_set(cpu, cpu_online_map); + local_irq_enable(); +} +#endif + +static int __devinit cpu_enable(unsigned int cpu) +{ + if (smp_ops->cpu_enable) + return smp_ops->cpu_enable(cpu); + + return -ENOSYS; +} + int __devinit __cpu_up(unsigned int cpu) { int c; + if (!cpu_enable(cpu)) + return 0; + /* At boot, don't bother with non-present cpus -JSCHOPP */ if (system_state < SYSTEM_RUNNING && !cpu_present(cpu)) return -ENOENT; Index: linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/sysfs.c =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/arch/ppc64/kernel/sysfs.c,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 sysfs.c --- linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/sysfs.c 29 Jan 2005 21:29:21 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/arch/ppc64/kernel/sysfs.c 1 Feb 2005 05:01:10 -0000 @@ -18,7 +18,7 @@ #include #include #include - +#include static DEFINE_PER_CPU(struct cpu, cpu_devices); @@ -413,9 +413,7 @@ static int __init topology_init(void) * CPU. For instance, the boot cpu might never be valid * for hotplugging. */ -#ifdef CONFIG_HOTPLUG_CPU - if (systemcfg->platform != PLATFORM_PSERIES_LPAR) -#endif + if (!ppc_md.cpu_die) c->no_control = 1; if (cpu_online(cpu) || (c->no_control == 0)) { Index: linux-2.6.11-rc2-mm2-ppc64/include/asm-ppc64/machdep.h =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/include/asm-ppc64/machdep.h,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 machdep.h --- linux-2.6.11-rc2-mm2-ppc64/include/asm-ppc64/machdep.h 29 Jan 2005 21:29:28 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/include/asm-ppc64/machdep.h 1 Feb 2005 05:56:24 -0000 @@ -30,6 +30,7 @@ struct smp_ops_t { void (*setup_cpu)(int nr); void (*take_timebase)(void); void (*give_timebase)(void); + int (*cpu_enable)(unsigned int nr); int (*cpu_disable)(void); void (*cpu_die)(unsigned int nr); }; Index: linux-2.6.11-rc2-mm2-ppc64/include/asm-ppc64/smp.h =================================================================== RCS file: /home/cvsroot/linux-2.6.11-rc2-mm2/include/asm-ppc64/smp.h,v retrieving revision 1.1.1.1 diff -u -p -B -r1.1.1.1 smp.h --- linux-2.6.11-rc2-mm2-ppc64/include/asm-ppc64/smp.h 29 Jan 2005 21:29:28 -0000 1.1.1.1 +++ linux-2.6.11-rc2-mm2-ppc64/include/asm-ppc64/smp.h 1 Feb 2005 06:25:08 -0000 @@ -29,7 +29,7 @@ extern int boot_cpuid; extern int boot_cpuid_phys; -extern void cpu_die(void) __attribute__((noreturn)); +extern void cpu_die(void); #ifdef CONFIG_SMP @@ -37,6 +37,13 @@ extern void smp_send_debugger_break(int struct pt_regs; extern void smp_message_recv(int, struct pt_regs *); +#ifdef CONFIG_HOTPLUG_CPU +extern void fixup_irqs(cpumask_t map); +int generic_cpu_disable(void); +int generic_cpu_enable(unsigned int cpu); +void generic_cpu_die(unsigned int cpu); +void generic_mach_cpu_die(void); +#endif #define __smp_processor_id() (get_paca()->paca_index) #define hard_smp_processor_id() (get_paca()->hw_cpu_id) From olh at suse.de Wed Feb 2 06:27:35 2005 From: olh at suse.de (Olaf Hering) Date: Tue, 1 Feb 2005 20:27:35 +0100 Subject: [PATCH] e1000, errata 2{3, 4} - possible EEH or memory corruption when DMA crosses a 64k boundary Message-ID: <20050201192735.GB7433@suse.de> We have this patch in SLES9 SP1. I asked google about 'fix for errata 23, cant cross 64kB boundary', and it shhows such a patch is also part of RH 2.6.9. It still applies to current Linus tree. Can you check wether this is still required for the current driver? References: SUSE48368 LTC12567 Need to check 64k boundary on DMA address as well. We also need to have 64k boundary checking on the DMA address that comes back from pci_map_single(). This address is what will be passed to the adapter on ppc64 for it to DMA into. It's the address that the adapter sees which will trip erratum 23. The so patched driver passed a quick netperf run and a weekend long stress test. diff -puN drivers/net/e1000-new/e1000_main.c~64k-align-check-dma-suse drivers/net/e1000-new/e1000_main.c --- linux-2.6.5-7.127/drivers/net/e1000-new/e1000_main.c~64k-align-check-dma-suse Wed Dec 8 16:55:46 2004 +++ linux-2.6.5-7.127-moilanen/drivers/net/e1000-new/e1000_main.c Thu Dec 9 15:46:04 2004 @@ -2579,6 +2579,29 @@ e1000_alloc_rx_buffers(struct e1000_adap adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); + if(adapter->hw.mac_type == e1000_82545 || + adapter->hw.mac_type == e1000_82546) { + /* fix for errata 23, cant cross 64kB boundary */ + begin = (unsigned long)buffer_info->dma; + end = (unsigned long)(adapter->rx_buffer_len) - 1; + + if(!e1000_check_64k_alignment(adapter, begin, end)) { + + DPRINTK(RX_ERR,ERR,"dma align check failed: " + "begin: 0x%lx, end: 0x%lx\n", begin, end); + + dev_kfree_skb(skb); + buffer_info->skb = NULL; + + pci_unmap_single(pdev, + buffer_info->dma, + adapter->rx_buffer_len, + PCI_DMA_FROMDEVICE); + + break; /* while !buffer_info->skb */ + } + } + rx_desc = E1000_RX_DESC(*rx_ring, i); rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); From jimix at watson.ibm.com Wed Feb 2 06:23:39 2005 From: jimix at watson.ibm.com (Jimi Xenidis) Date: Tue, 1 Feb 2005 14:23:39 -0500 Subject: [PATCH] drivers/char/hvcs.c and devfs Message-ID: <16895.55099.774986.376938@kitch0.watson.ibm.com> The hvcs driver does not register a devfs_name resulting in devfs creating /dev/* entries. The following one line patch remedies the problem. Signed-off-by: Jimi Xenidis --- orig/drivers/char/hvcs.c +++ mod/drivers/char/hvcs.c @@ -1363,6 +1363,7 @@ hvcs_tty_driver->driver_name = hvcs_driver_name; hvcs_tty_driver->name = hvcs_device_node; + hvcs_tty_driver->devfs_name = hvcs_device_node; /* * We'll let the system assign us a major number, indicated by leaving From jimix at watson.ibm.com Wed Feb 2 06:34:31 2005 From: jimix at watson.ibm.com (Jimi Xenidis) Date: Tue, 1 Feb 2005 14:34:31 -0500 Subject: HUPin the ttys in drivers/char/hvcs.c Message-ID: <16895.55751.310549.454083@kitch0.watson.ibm.com> In an LPAR environment there is the hvc (client side VTERM) and the hvcs (server side VTERM). If the /dev/hvcs is paired/registered with a VTERM what is removed (as in the case of LPAR death) the H_GET_TERM_CHAR hcall will eventually return H_Closed. IMHO, when this event occurs the /dev/hvcs should get HUPed and ultimately an H_FREE_VTERM should occurs on the channel. Otherwise the administrator would have to clean up after it. Thoughts? -JX From jdmason at us.ibm.com Wed Feb 2 06:33:59 2005 From: jdmason at us.ibm.com (Jon Mason) Date: Tue, 1 Feb 2005 13:33:59 -0600 Subject: [PATCH] e1000, errata 2{3, 4} - possible EEH or memory corruption when DMA crosses a 64k boundary In-Reply-To: <20050201192735.GB7433@suse.de> References: <20050201192735.GB7433@suse.de> Message-ID: <200502011333.59262.jdmason@us.ibm.com> On Tuesday 01 February 2005 01:27 pm, Olaf Hering wrote: > > We have this patch in SLES9 SP1. > I asked google about 'fix for errata 23, cant cross 64kB boundary', and > it shhows such a patch is also part of RH 2.6.9. > It still applies to current Linus tree. > Can you check wether this is still required for the current driver? This patch is still lacking from the latest e1000 driver. Intel has the patch in their queue, so it will be needed until they release their next version of the e1000 driver. From ganesh.venkatesan at intel.com Wed Feb 2 06:36:31 2005 From: ganesh.venkatesan at intel.com (Venkatesan, Ganesh) Date: Tue, 1 Feb 2005 11:36:31 -0800 Subject: [PATCH] e1000, errata 2{3, 4} - possible EEH or memory corruption when DMA crosses a 64k boundary Message-ID: <468F3FDA28AA87429AD807992E22D07E041A065B@orsmsx408> The patch attached to your mail does not seem to be complete. Did the mail application truncate? In any case, this fix is required in e1000. It is *not* in the latest driver that is released but *is* in the driver that is lined up for release in a couple of weeks. Thanks, Ganesh. >-----Original Message----- >From: Olaf Hering [mailto:olh at suse.de] >Sent: Tuesday, February 01, 2005 11:28 AM >To: Venkatesan, Ganesh; netdev at oss.sgi.com >Cc: linuxppc64-dev at ozlabs.org >Subject: [PATCH] e1000, errata 2{3,4} - possible EEH or memory corruption >when DMA crosses a 64k boundary > > >We have this patch in SLES9 SP1. >I asked google about 'fix for errata 23, cant cross 64kB boundary', and >it shhows such a patch is also part of RH 2.6.9. >It still applies to current Linus tree. >Can you check wether this is still required for the current driver? > > >References: SUSE48368 LTC12567 > >Need to check 64k boundary on DMA address as well. > >We also need to have 64k boundary checking on the DMA address >that comes back from pci_map_single(). This address is what will >be passed to the adapter on ppc64 for it to DMA into. It's the >address that the adapter sees which will trip erratum 23. > >The so patched driver passed a quick netperf run and a weekend >long stress test. > >diff -puN drivers/net/e1000-new/e1000_main.c~64k-align-check-dma-suse >drivers/net/e1000-new/e1000_main.c >--- linux-2.6.5-7.127/drivers/net/e1000-new/e1000_main.c~64k-align-check- >dma-suse Wed Dec 8 16:55:46 2004 >+++ linux-2.6.5-7.127-moilanen/drivers/net/e1000-new/e1000_main.c Thu Dec >9 15:46:04 2004 >@@ -2579,6 +2579,29 @@ e1000_alloc_rx_buffers(struct e1000_adap > adapter->rx_buffer_len, > PCI_DMA_FROMDEVICE); > >+ if(adapter->hw.mac_type == e1000_82545 || >+ adapter->hw.mac_type == e1000_82546) { >+ /* fix for errata 23, cant cross 64kB boundary */ >+ begin = (unsigned long)buffer_info->dma; >+ end = (unsigned long)(adapter->rx_buffer_len) - 1; >+ >+ if(!e1000_check_64k_alignment(adapter, begin, end)) { >+ >+ DPRINTK(RX_ERR,ERR,"dma align check failed: " >+ "begin: 0x%lx, end: 0x%lx\n", begin, end); >+ >+ dev_kfree_skb(skb); >+ buffer_info->skb = NULL; >+ >+ pci_unmap_single(pdev, >+ buffer_info->dma, >+ adapter->rx_buffer_len, >+ PCI_DMA_FROMDEVICE); >+ >+ break; /* while !buffer_info->skb */ >+ } >+ } >+ > rx_desc = E1000_RX_DESC(*rx_ring, i); > rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); > From olh at suse.de Wed Feb 2 06:40:10 2005 From: olh at suse.de (Olaf Hering) Date: Tue, 1 Feb 2005 20:40:10 +0100 Subject: [PATCH] e1000, errata 2{3, 4} - possible EEH or memory corruption when DMA crosses a 64k boundary In-Reply-To: <468F3FDA28AA87429AD807992E22D07E041A065B@orsmsx408> References: <468F3FDA28AA87429AD807992E22D07E041A065B@orsmsx408> Message-ID: <20050201194010.GA7892@suse.de> On Tue, Feb 01, Venkatesan, Ganesh wrote: > In any case, this fix is required in e1000. It is *not* in the latest > driver that is released but *is* in the driver that is lined up for > release in a couple of weeks. Thats good enough, just that things dont get lost. There are probably a few separate patches for each problem found. We are still in the process of sorting out our +2k patch mess. From brking at us.ibm.com Wed Feb 2 07:16:47 2005 From: brking at us.ibm.com (Brian King) Date: Tue, 01 Feb 2005 14:16:47 -0600 Subject: pci: Arch hook to determine config space size In-Reply-To: <20050201123249.GA10088@parcelfarce.linux.theplanet.co.uk> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <20050131192955.GJ31145@parcelfarce.linux.theplanet.co.uk> <41FEA4AA.1080407@us.ibm.com> <200501312256.44692.arnd@arndb.de> <41FEB492.2020002@us.ibm.com> <1107227727.5963.46.camel@gaston> <41FF0B0D.8020003@us.ibm.com> <20050201123249.GA10088@parcelfarce.linux.theplanet.co.uk> Message-ID: <41FFE3AF.706@us.ibm.com> Matthew Wilcox wrote: > On Mon, Jan 31, 2005 at 10:52:29PM -0600, Brian King wrote: > >>@@ -62,8 +72,11 @@ static int rtas_read_config(struct devic >> return PCIBIOS_DEVICE_NOT_FOUND; >> if (where & (size - 1)) >> return PCIBIOS_BAD_REGISTER_NUMBER; > > > You should probably delete this redundant test at the same time ... Done. The new patch below also adds some address checking to iSeries config accessor functions. Additionally, this patch should address Arnd's concern, as it now looks for the "ibm,pci-config-space-type" property on the device itself rather than on the bridge. -- Brian King eServer Storage I/O IBM Linux Technology Center -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ppc64_pcix_mode2_cfg.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050201/f3a6a775/attachment.txt From sonny at burdell.org Wed Feb 2 06:52:07 2005 From: sonny at burdell.org (Sonny Rao) Date: Tue, 1 Feb 2005 14:52:07 -0500 Subject: Very Large "zero" slab expected? Message-ID: <20050201195207.GA5723@kevlar.burdell.org> Hi, I'm running a fairly heavy database workload using DB/2 on a 4-way 720 ontop of ext3 trying to replicate a separate VM performance issue. During and after the run, I see a massive about of slab memory being used by the "zero" cache, which appears to a be a ppc64 specific cache for pmd's and pgd's. Basically, about 1GB out of my total of 8GB on the system is being consumed by this. Is this expected ? It seems excessive considering my mapped memory is only about 2GB during the run. The DB/2 buffer pool was set to 4GB and none of it used hugh pages. Here's the relavent snippet from slabinfo: slabinfo - version: 2.0 # name : tunables : slabdata zero 256424 256431 4096 1 1 : tunables 24 12 8 : slabdata 256424 256431 0 Any ideas as to why there are so many of these ? Sonny From kravetz at us.ibm.com Wed Feb 2 09:44:33 2005 From: kravetz at us.ibm.com (Mike Kravetz) Date: Tue, 1 Feb 2005 14:44:33 -0800 Subject: ppc64 memory hotplug config options Message-ID: <20050201224433.GA5689@w-mikek2.ibm.com> I'm working on memory hotplug for ppc64 and wanted to get some opinions/information on config option dependencies. In the current hotplug memory development patch set, there are four interrelated config options. FLATMEM - Indicates a 'flat' contiguous memory model. SPARSEMEM - Indicates a 'sparse' memory model that may contain holes. HOTPLUG_MEMORY - Allow hotplug memory operations. NUMA - Add support for NUMA architecture. Some dependencies are obvious. If you want HOTPLUG_MEMORY, you must have SPARSEMEM (as removing memory will leave holes). However, I was curious about the relationship between NUMA and SPARSEMEM/FLATMEM on ppc64. In the current mainline kernels, NUMA depends on DISCONTIGMEM. However, I believe this is mainly due to a bunch of code for node specific memory access being part of DISCONTIGMEM. It seems that DISCONTIGMEM and NUMA are more intertwined than they need to be. Is it possible to have a 'flat' (no holes) memory layout on a ppc64 box with NUMA characteristics? I would think that the firmware/hypervisor could present memory to the OS that appears to have no holes even though different portions of memory have different access characteristics. Thanks, -- Mike From sonny at burdell.org Wed Feb 2 10:02:39 2005 From: sonny at burdell.org (Sonny Rao) Date: Tue, 1 Feb 2005 18:02:39 -0500 Subject: Very Large "zero" slab expected? In-Reply-To: <20050201195207.GA5723@kevlar.burdell.org> References: <20050201195207.GA5723@kevlar.burdell.org> Message-ID: <20050201230239.GA8589@kevlar.burdell.org> On Tue, Feb 01, 2005 at 02:52:07PM -0500, Sonny Rao wrote: > Hi, I'm running a fairly heavy database workload using DB/2 on a 4-way > 720 ontop of ext3 trying to replicate a separate VM performance issue. > > During and after the run, I see a massive about of slab memory being > used by the "zero" cache, which appears to a be a ppc64 specific > cache for pmd's and pgd's. > > Basically, about 1GB out of my total of 8GB on the system is being > consumed by this. Is this expected ? It seems excessive > considering my mapped memory is only about 2GB during the run. > > The DB/2 buffer pool was set to 4GB and none of it used hugh pages. > > Here's the relavent snippet from slabinfo: > slabinfo - version: 2.0 > # name : tunables : slabdata > zero 256424 256431 4096 1 1 : tunables 24 12 8 : slabdata 256424 256431 0 > > Any ideas as to why there are so many of these ? More info : Here's /proc/meminfo output from a similar run, with 4GB of RAM instead of 8GB: portrait:~ # cat /proc/meminfo MemTotal: 4099072 kB MemFree: 15008 kB Buffers: 38580 kB Cached: 2941320 kB SwapCached: 118492 kB Active: 2672776 kB Inactive: 645284 kB HighTotal: 0 kB HighFree: 0 kB LowTotal: 4099072 kB LowFree: 15008 kB SwapTotal: 1050616 kB SwapFree: 341156 kB Dirty: 372 kB Writeback: 4 kB Mapped: 1827844 kB Slab: 715384 kB Committed_AS: 5342648 kB PageTables: 610864 kB VmallocTotal: 2147483647 kB VmallocUsed: 25340 kB VmallocChunk: 2147458223 kB HugePages_Total: 0 HugePages_Free: 0 Hugepagesize: 16384 kB And the top few lines of slabtop: Active / Total Objects (% used) : 728019 / 747302 (97.4%) Active / Total Slabs (% used) : 177511 / 177591 (100.0%) Active / Total Caches (% used) : 79 / 120 (65.8%) Active / Total Size (% used) : 705236.61K / 709101.23K (99.5%) Minimum / Average / Maximum Object : 0.02K / 0.95K / 128.00K OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME 336360 335400 99% 0.09K 8409 40 33636K buffer_head 157860 156817 99% 0.12K 5262 30 21048K size-128 154036 153988 99% 4.00K 154036 1 616144K zero 22572 22120 97% 0.16K 1026 22 4104K vm_area_struct 18571 18074 97% 0.52K 2653 7 10612K radix_tree_node So, you can see at this point we have around 600MB of these "zero" pages being used. There are about 150 db2 processes running using lots of shared memory: portrait:~ # ipcs ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x763ee574 2392064 db2inst1 767 39987136 161 0x763ee561 2424833 db2inst1 701 39370752 159 0x00000000 2457602 db2fenc1 701 164052992 161 0x6803bbdb 2490371 db2inst1 761 50331648 1 0x00000000 2785285 db2inst1 701 1073741824 145 0x00000000 2818054 db2inst1 701 1073741824 145 0x00000000 2850823 db2inst1 701 1073741824 145 0x00000000 2883592 db2inst1 701 117735424 145 Thanks, Sonny From paulus at samba.org Wed Feb 2 10:39:02 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 2 Feb 2005 10:39:02 +1100 Subject: Very Large "zero" slab expected? In-Reply-To: <20050201195207.GA5723@kevlar.burdell.org> References: <20050201195207.GA5723@kevlar.burdell.org> Message-ID: <16896.4886.136678.130456@cargo.ozlabs.ibm.com> Sonny Rao writes: > Hi, I'm running a fairly heavy database workload using DB/2 on a 4-way > 720 ontop of ext3 trying to replicate a separate VM performance issue. > > During and after the run, I see a massive about of slab memory being > used by the "zero" cache, which appears to a be a ppc64 specific > cache for pmd's and pgd's. > > Basically, about 1GB out of my total of 8GB on the system is being > consumed by this. Is this expected ? It seems excessive > considering my mapped memory is only about 2GB during the run. > > The DB/2 buffer pool was set to 4GB and none of it used hugh pages. How many DB/2 processes had the buffer pool mapped? It was probably 100 or more, I would guess. The zero slab cache is used for pte pages as well as pmds and pgds, and each process will have a separate page table tree, which will occupy about 1/500th or so of the amount of mapped memory, per process. So if you had ~125 processes the page table trees would occupy about 1GB for a 4GB buffer pool. The solution is to implement shared page tables. Some people here in the LTC are looking at possibly doing that, but getting it accepted into mainline could be tricky. Paul. From sonny at burdell.org Wed Feb 2 10:27:24 2005 From: sonny at burdell.org (Sonny Rao) Date: Tue, 1 Feb 2005 18:27:24 -0500 Subject: Very Large "zero" slab expected? In-Reply-To: <16896.4886.136678.130456@cargo.ozlabs.ibm.com> References: <20050201195207.GA5723@kevlar.burdell.org> <16896.4886.136678.130456@cargo.ozlabs.ibm.com> Message-ID: <20050201232724.GA8934@kevlar.burdell.org> On Wed, Feb 02, 2005 at 10:39:02AM +1100, Paul Mackerras wrote: > Sonny Rao writes: > > > Hi, I'm running a fairly heavy database workload using DB/2 on a 4-way > > 720 ontop of ext3 trying to replicate a separate VM performance issue. > > > > During and after the run, I see a massive about of slab memory being > > used by the "zero" cache, which appears to a be a ppc64 specific > > cache for pmd's and pgd's. > > > > Basically, about 1GB out of my total of 8GB on the system is being > > consumed by this. Is this expected ? It seems excessive > > considering my mapped memory is only about 2GB during the run. > > > > The DB/2 buffer pool was set to 4GB and none of it used hugh pages. > > How many DB/2 processes had the buffer pool mapped? It was probably > 100 or more, I would guess. The zero slab cache is used for pte pages > as well as pmds and pgds, and each process will have a separate page > table tree, which will occupy about 1/500th or so of the amount of > mapped memory, per process. So if you had ~125 processes the page > table trees would occupy about 1GB for a 4GB buffer pool. Yes, around 150 processes. Now that I actually look at it, this number corresponds to what is shown under "PageTables" in meminfo. > The solution is to implement shared page tables. Some people here in > the LTC are looking at possibly doing that, but getting it accepted > into mainline could be tricky. Ok great just wanted to make sure this is expected, thanks. BTW, those people you mentioned work across the hall from my office, and are causing quite a ruckus :) Sonny From sonny at burdell.org Wed Feb 2 10:30:23 2005 From: sonny at burdell.org (Sonny Rao) Date: Tue, 1 Feb 2005 18:30:23 -0500 Subject: Very Large "zero" slab expected? In-Reply-To: <16896.4886.136678.130456@cargo.ozlabs.ibm.com> References: <20050201195207.GA5723@kevlar.burdell.org> <16896.4886.136678.130456@cargo.ozlabs.ibm.com> Message-ID: <20050201233023.GA9063@kevlar.burdell.org> On Wed, Feb 02, 2005 at 10:39:02AM +1100, Paul Mackerras wrote: > Sonny Rao writes: > > > Hi, I'm running a fairly heavy database workload using DB/2 on a 4-way > > 720 ontop of ext3 trying to replicate a separate VM performance issue. > > > > During and after the run, I see a massive about of slab memory being > > used by the "zero" cache, which appears to a be a ppc64 specific > > cache for pmd's and pgd's. > > > > Basically, about 1GB out of my total of 8GB on the system is being > > consumed by this. Is this expected ? It seems excessive > > considering my mapped memory is only about 2GB during the run. > > > > The DB/2 buffer pool was set to 4GB and none of it used hugh pages. > > How many DB/2 processes had the buffer pool mapped? It was probably > 100 or more, I would guess. The zero slab cache is used for pte pages > as well as pmds and pgds, and each process will have a separate page > table tree, which will occupy about 1/500th or so of the amount of > mapped memory, per process. So if you had ~125 processes the page > table trees would occupy about 1GB for a 4GB buffer pool. > > The solution is to implement shared page tables. Some people here in > the LTC are looking at possibly doing that, but getting it accepted > into mainline could be tricky. By the way, the name "zero" slab is not very descriptive, some of the PPC64 developers here in Austin didn't even know what it was off hand. You might consider renaming it to avoid confusion. Thanks, Sonny From linas at austin.ibm.com Wed Feb 2 12:15:11 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 1 Feb 2005 19:15:11 -0600 Subject: [PATCH] PPC64: draft version of EEH code. Message-ID: <20050202011511.GB9140@austin.ibm.com> Hi Ben, Paulus, Attached is my current draft version of the EEH patches. Its lightly tested. It fixes a few bugs compared to previous versions. -- I've chopped out the device_node tracking stuff, because device nodes no longer seem to disappear out from under me. -- #define EEH_MAX_FAILS bumped large; the e1000 driver makes thoursands of attempts before it gives up. -- The fail count is tracked in a distinct variable now. -- I still don't know why the PCI config space doesn't get set up, so this patch sets it manually. As before, the patch is in two parts; one for the ppc64 side, and one for the hotplug side. --linas -------------- next part -------------- ===== arch/ppc64/kernel/eeh.c 1.41 vs edited ===== --- 1.41/arch/ppc64/kernel/eeh.c 2005-01-06 13:05:42 -06:00 +++ edited/arch/ppc64/kernel/eeh.c 2005-02-01 14:16:42 -06:00 @@ -17,21 +17,19 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include #include #include -#include #include #include #include #include #include -#include +#include #include #include #include #include -#include #include "pci.h" #undef DEBUG @@ -88,8 +86,7 @@ static struct notifier_block *eeh_notifi * is broken and panic. This sets the threshold for how many read * attempts we allow before panicking. */ -#define EEH_MAX_FAILS 1000 -static atomic_t eeh_fail_count; +#define EEH_MAX_FAILS 100000 /* RTAS tokens */ static int ibm_set_eeh_option; @@ -106,6 +103,10 @@ static spinlock_t slot_errbuf_lock = SPI static int eeh_error_buf_size; /* System monitoring statistics */ +static DEFINE_PER_CPU(unsigned long, no_device); +static DEFINE_PER_CPU(unsigned long, no_dn); +static DEFINE_PER_CPU(unsigned long, no_cfg_addr); +static DEFINE_PER_CPU(unsigned long, ignored_check); static DEFINE_PER_CPU(unsigned long, total_mmio_ffs); static DEFINE_PER_CPU(unsigned long, false_positives); static DEFINE_PER_CPU(unsigned long, ignored_failures); @@ -224,9 +225,9 @@ pci_addr_cache_insert(struct pci_dev *de while (*p) { parent = *p; piar = rb_entry(parent, struct pci_io_addr_range, rb_node); - if (alo < piar->addr_lo) { + if (ahi < piar->addr_lo) { p = &parent->rb_left; - } else if (ahi > piar->addr_hi) { + } else if (alo > piar->addr_hi) { p = &parent->rb_right; } else { if (dev != piar->pcidev || @@ -244,6 +245,11 @@ pci_addr_cache_insert(struct pci_dev *de piar->addr_hi = ahi; piar->pcidev = dev; piar->flags = flags; + +#ifdef DEBUG + printk (KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n", + alo, ahi, pci_name (dev)); +#endif rb_link_node(&piar->rb_node, parent, p); rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root); @@ -368,6 +374,7 @@ void pci_addr_cache_remove_device(struct */ void __init pci_addr_cache_build(void) { + struct device_node *dn; struct pci_dev *dev = NULL; spin_lock_init(&pci_io_addr_cache_root.piar_lock); @@ -378,6 +385,17 @@ void __init pci_addr_cache_build(void) continue; } pci_addr_cache_insert_device(dev); + + /* Save the BAR's; firmware doesn't restore these after EEH reset */ + dn = pci_device_to_OF_node(dev); + if (dn) { + int i; + for (i = 0; i < 16; i++) + pci_read_config_dword(dev, i * 4, &dn->config_space[i]); + + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + dn->eeh_is_bridge = 1; + } } #ifdef DEBUG @@ -389,6 +407,32 @@ void __init pci_addr_cache_build(void) /* --------------------------------------------------------------- */ /* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */ +void eeh_slot_error_detail (struct device_node *dn, int severity) +{ + unsigned long flags; + int rc; + + if (!dn) return; + + /* Log the error with the rtas logger */ + spin_lock_irqsave(&slot_errbuf_lock, flags); + memset(slot_errbuf, 0, eeh_error_buf_size); + + rc = rtas_call(ibm_slot_error_detail, + 8, 1, NULL, dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid), NULL, 0, + virt_to_phys(slot_errbuf), + eeh_error_buf_size, + severity); + + if (rc == 0) + log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0); + spin_unlock_irqrestore(&slot_errbuf_lock, flags); +} + +EXPORT_SYMBOL(eeh_slot_error_detail); + /** * eeh_register_notifier - Register to find out about EEH events. * @nb: notifier block to callback on events @@ -424,7 +468,7 @@ static int read_slot_reset_state(struct outputs = 3; } - return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, + return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); } @@ -484,11 +528,9 @@ static void eeh_event_handler(void *dumm "%s %s\n", event->reset_state, pci_name(event->dev), pci_pretty_name(event->dev)); - atomic_set(&eeh_fail_count, 0); - notifier_call_chain (&eeh_notifier_chain, - EEH_NOTIFY_FREEZE, event); - __get_cpu_var(slot_resets)++; + notifier_call_chain (&eeh_notifier_chain, + EEH_NOTIFY_FREEZE, event); pci_dev_put(event->dev); kfree(event); @@ -496,8 +538,8 @@ static void eeh_event_handler(void *dumm } /** - * eeh_token_to_phys - convert EEH address token to phys address - * @token i/o token, should be address in the form 0xE.... + * eeh_token_to_phys - convert I/O address to phys address + * @token i/o address, should be address in the form 0xA.... */ static inline unsigned long eeh_token_to_phys(unsigned long token) { @@ -512,6 +554,17 @@ static inline unsigned long eeh_token_to return pa | (token & (PAGE_SIZE-1)); } +static inline struct pci_dev * eeh_get_pci_dev(struct device_node *dn) +{ + struct pci_dev *dev = NULL; + + for_each_pci_dev(dev) { + if (pci_device_to_OF_node(dev) == dn) + return dev; + } + return NULL; +} + /** * eeh_dn_check_failure - check if all 1's data is due to EEH slot freeze * @dn device node @@ -532,7 +585,7 @@ int eeh_dn_check_failure(struct device_n int ret; int rets[3]; unsigned long flags; - int rc, reset_state; + int reset_state; struct eeh_event *event; __get_cpu_var(total_mmio_ffs)++; @@ -540,16 +593,20 @@ int eeh_dn_check_failure(struct device_n if (!eeh_subsystem_enabled) return 0; - if (!dn) + if (!dn) { + __get_cpu_var(no_dn)++; return 0; + } /* Access to IO BARs might get this far and still not want checking. */ if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || dn->eeh_mode & EEH_MODE_NOCHECK) { + __get_cpu_var(ignored_check)++; return 0; } if (!dn->eeh_config_addr) { + __get_cpu_var(no_cfg_addr)++; return 0; } @@ -558,8 +615,11 @@ int eeh_dn_check_failure(struct device_n * slot, we know it's bad already, we don't need to check... */ if (dn->eeh_mode & EEH_MODE_ISOLATED) { - atomic_inc(&eeh_fail_count); - if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { + dn->eeh_check_count ++; + if (dn->eeh_check_count >= EEH_MAX_FAILS) { + printk (KERN_ERR "EEH: Driver ignored %d bad reads, panicing\n", + dn->eeh_check_count); + dump_stack(); /* re-read the slot reset state */ if (read_slot_reset_state(dn, rets) != 0) rets[0] = -1; /* reset state unknown */ @@ -581,34 +641,25 @@ int eeh_dn_check_failure(struct device_n return 0; } - /* prevent repeated reports of this failure */ + /* Prevent repeated reports of this failure */ dn->eeh_mode |= EEH_MODE_ISOLATED; reset_state = rets[0]; + /* Log the error with the rtas logger */ + if (dn->eeh_freeze_count < EEH_MAX_ALLOWED_FREEZES) { + eeh_slot_error_detail (dn, 1 /* Temporary Error */); + } else { + eeh_slot_error_detail (dn, 2 /* Permanent Error */); + } - spin_lock_irqsave(&slot_errbuf_lock, flags); - memset(slot_errbuf, 0, eeh_error_buf_size); - - rc = rtas_call(ibm_slot_error_detail, - 8, 1, NULL, dn->eeh_config_addr, - BUID_HI(dn->phb->buid), - BUID_LO(dn->phb->buid), NULL, 0, - virt_to_phys(slot_errbuf), - eeh_error_buf_size, - 1 /* Temporary Error */); - - if (rc == 0) - log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0); - spin_unlock_irqrestore(&slot_errbuf_lock, flags); - - printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n", - rets[0], dn->name, dn->full_name); event = kmalloc(sizeof(*event), GFP_ATOMIC); if (event == NULL) { - eeh_panic(dev, reset_state); + printk (KERN_ERR "EEH: out of memory, event not handled\n"); return 1; } + if (!dev) + dev = eeh_get_pci_dev (dn); event->dev = dev; event->dn = dn; event->reset_state = reset_state; @@ -634,7 +685,6 @@ EXPORT_SYMBOL(eeh_dn_check_failure); * @token i/o token, should be address in the form 0xA.... * @val value, should be all 1's (XXX why do we need this arg??) * - * Check for an eeh failure at the given token address. * Check for an EEH failure at the given token address. Call this * routine if the result of a read was all 0xff's and you want to * find out if this is due to an EEH slot freeze event. This routine @@ -642,6 +692,7 @@ EXPORT_SYMBOL(eeh_dn_check_failure); * * Note this routine is safe to call in an interrupt context. */ + unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val) { unsigned long addr; @@ -651,8 +702,10 @@ unsigned long eeh_check_failure(const vo /* Finding the phys addr + pci device; this is pretty quick. */ addr = eeh_token_to_phys((unsigned long __force) token); dev = pci_get_device_by_addr(addr); - if (!dev) + if (!dev) { + __get_cpu_var(no_device)++; return val; + } dn = pci_device_to_OF_node(dev); eeh_dn_check_failure (dn, dev); @@ -663,6 +716,123 @@ unsigned long eeh_check_failure(const vo EXPORT_SYMBOL(eeh_check_failure); +/* ------------------------------------------------------------- */ +/* The code below deals with error recovery */ + +void +rtas_set_slot_reset(struct device_node *dn) +{ + int token = rtas_token ("ibm,set-slot-reset"); + int rc; + + if (token == RTAS_UNKNOWN_SERVICE) + return; + rc = rtas_call(token,4,1, NULL, + dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid), + 1); + if (rc) { + printk (KERN_WARNING "EEH: Unable to reset the failed slot\n"); + return; + } + + /* The PCI bus requires that the reset be held high for at least + * a 100 milliseconds. We wait a bit longer 'just in case'. + */ + msleep (200); + + rc = rtas_call(token,4,1, NULL, + dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid), + 0); +} + +EXPORT_SYMBOL(rtas_set_slot_reset); + +void +rtas_configure_bridge(struct device_node *dn) +{ + int token = rtas_token ("ibm,configure-bridge"); + int rc; + + if (token == RTAS_UNKNOWN_SERVICE) + return; + rc = rtas_call(token,3,1, NULL, + dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid)); + if (rc) { + printk (KERN_WARNING "EEH: Unable to configure device bridge\n"); + } +} + +EXPORT_SYMBOL(rtas_configure_bridge); + +/* ------------------------------------------------------- */ +/** Save and restore of PCI BARs + * + * Although firmware will set up BARs during boot, it doesn't + * set up device BAR's after a device reset, although it will, + * if requested, set up bridge configuration. Thus, we need to + * configure the PCI devices ourselves. Config-space setup is + * stored in the PCI structures which are normally deleted during + * device removal. Thus, the "save" routine references the + * structures so that they aren't deleted. + */ + +/** + * __restore_bars - Restore the Base Address Registers + * Loads the PCI configuration space base address registers, + * the expansion ROM base address, the latency timer, and etc. + * from the saved values in the device node. + */ +static inline void __restore_bars (struct device_node *dn) +{ + int i; + for (i=4; i<10; i++) { + rtas_write_config(dn, i*4, 4, dn->config_space[i]); + } + + /* 12 == Expansion ROM Address */ + rtas_write_config(dn, 12*4, 4, dn->config_space[12]); + +#define SAVED_BYTE(OFF) (((u8 *)(dn->config_space))[OFF]) + + rtas_write_config (dn, PCI_CACHE_LINE_SIZE, 1, + SAVED_BYTE(PCI_CACHE_LINE_SIZE)); + + rtas_write_config (dn, PCI_LATENCY_TIMER, 1, + SAVED_BYTE(PCI_LATENCY_TIMER)); + + rtas_write_config (dn, PCI_INTERRUPT_LINE, 1, + SAVED_BYTE(PCI_INTERRUPT_LINE)); +} + +/** + * eeh_restore_bars - restore the PCI config space info + */ +void eeh_restore_bars(struct device_node *dn) +{ + if (! dn->eeh_is_bridge) + __restore_bars (dn); + + if (dn->child) + eeh_restore_bars (dn->child); + + if (dn->sibling) + eeh_restore_bars (dn->sibling); +} + +EXPORT_SYMBOL(eeh_restore_bars); + +/* ------------------------------------------------------------- */ +/* The code below deals with enabling EEH for devices during the + * early boot sequence. EEH must be enabled before any PCI probing + * can be done. + */ + struct eeh_early_enable_info { unsigned int buid_hi; unsigned int buid_lo; @@ -742,7 +912,7 @@ static void *early_enable_eeh(struct dev dn->full_name); } - return NULL; + return NULL; } /* @@ -829,7 +999,9 @@ void eeh_add_device_early(struct device_ return; phb = dn->phb; if (NULL == phb || 0 == phb->buid) { - printk(KERN_WARNING "EEH: Expected buid but found none\n"); + printk(KERN_WARNING "EEH: Expected buid but found none for %s\n", + dn->full_name); + dump_stack(); return; } @@ -848,6 +1020,9 @@ EXPORT_SYMBOL(eeh_add_device_early); */ void eeh_add_device_late(struct pci_dev *dev) { + int i; + struct device_node *dn; + if (!dev || !eeh_subsystem_enabled) return; @@ -857,6 +1032,14 @@ void eeh_add_device_late(struct pci_dev #endif pci_addr_cache_insert_device (dev); + + /* Save the BAR's; firmware doesn't restore these after EEH reset */ + dn = pci_device_to_OF_node(dev); + for (i = 0; i < 16; i++) + pci_read_config_dword(dev, i * 4, &dn->config_space[i]); + + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + dn->eeh_is_bridge = 1; } EXPORT_SYMBOL(eeh_add_device_late); @@ -886,12 +1069,17 @@ static int proc_eeh_show(struct seq_file unsigned int cpu; unsigned long ffs = 0, positives = 0, failures = 0; unsigned long resets = 0; + unsigned long no_dev = 0, no_dn = 0, no_cfg = 0, no_check = 0; for_each_cpu(cpu) { ffs += per_cpu(total_mmio_ffs, cpu); positives += per_cpu(false_positives, cpu); failures += per_cpu(ignored_failures, cpu); resets += per_cpu(slot_resets, cpu); + no_dev += per_cpu(no_device, cpu); + no_dn += per_cpu(no_dn, cpu); + no_cfg += per_cpu(no_cfg_addr, cpu); + no_check += per_cpu(ignored_check, cpu); } if (0 == eeh_subsystem_enabled) { @@ -899,13 +1087,17 @@ static int proc_eeh_show(struct seq_file seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs); } else { seq_printf(m, "EEH Subsystem is enabled\n"); - seq_printf(m, "eeh_total_mmio_ffs=%ld\n" + seq_printf(m, + "no device=%ld\n" + "no device node=%ld\n" + "no config address=%ld\n" + "check not wanted=%ld\n" + "eeh_total_mmio_ffs=%ld\n" "eeh_false_positives=%ld\n" "eeh_ignored_failures=%ld\n" - "eeh_slot_resets=%ld\n" - "eeh_fail_count=%d\n", - ffs, positives, failures, resets, - eeh_fail_count.counter); + "eeh_slot_resets=%ld\n", + no_dev, no_dn, no_cfg, no_check, + ffs, positives, failures, resets); } return 0; ===== arch/ppc64/kernel/pSeries_pci.c 1.59 vs edited ===== --- 1.59/arch/ppc64/kernel/pSeries_pci.c 2004-11-15 21:29:10 -06:00 +++ edited/arch/ppc64/kernel/pSeries_pci.c 2005-01-20 17:25:37 -06:00 @@ -102,7 +102,7 @@ static int rtas_pci_read_config(struct p return PCIBIOS_DEVICE_NOT_FOUND; } -static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) +int rtas_write_config(struct device_node *dn, int where, int size, u32 val) { unsigned long buid, addr; int ret; ===== include/asm-ppc64/eeh.h 1.23 vs edited ===== --- 1.23/include/asm-ppc64/eeh.h 2004-10-25 18:17:38 -05:00 +++ edited/include/asm-ppc64/eeh.h 2005-02-01 13:24:13 -06:00 @@ -22,8 +22,8 @@ #include #include -#include #include +#include struct pci_dev; struct device_node; @@ -33,6 +33,10 @@ struct device_node; #define EEH_MODE_NOCHECK (1<<1) #define EEH_MODE_ISOLATED (1<<2) +/* Max number of EEH freezes allowed before we consider the device + * to be permanently disabled. */ +#define EEH_MAX_ALLOWED_FREEZES 5 + #ifdef CONFIG_PPC_PSERIES extern void __init eeh_init(void); unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val); @@ -57,6 +61,34 @@ void eeh_add_device_early(struct device_ void eeh_add_device_late(struct pci_dev *); /** + * eeh_slot_error_detail -- record and EEH error condition to the log + * @severity: 1 if temporary, 2 if permanent failure. + * + * Obtains the the EEH error details from the RTAS subsystem, + * and then logs these details with the RTAS error log system. + */ +void eeh_slot_error_detail (struct device_node *dn, int severity); + +/** + * rtas_set_slot_reset -- unfreeze a frozen slot + * + * Clear the EEH-frozen condition on a slot. This routine + * does this by asserting the PCI #RST line for 1/8th of + * a second; this routine will sleep while the adapter is + * being reset. + */ +void rtas_set_slot_reset (struct device_node *dn); + +/** + * rtas_configure_bridge -- firmware initialization of pci bridge + * + * Ask the firmware to configure any PCI bridge devices + * located behind the indicated node. Required after a + * pci device reset. + */ +void rtas_configure_bridge(struct device_node *dn); + +/** * eeh_remove_device - undo EEH setup for the indicated pci device * @dev: pci device to be removed * @@ -91,6 +123,10 @@ struct eeh_event { /** Register to find out about EEH events. */ int eeh_register_notifier(struct notifier_block *nb); int eeh_unregister_notifier(struct notifier_block *nb); + +/** Restore device configuration info across device resets. + */ +void eeh_restore_bars(struct device_node *); /** * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. ===== include/asm-ppc64/prom.h 1.24 vs edited ===== --- 1.24/include/asm-ppc64/prom.h 2004-11-25 00:42:42 -06:00 +++ edited/include/asm-ppc64/prom.h 2005-01-31 18:01:01 -06:00 @@ -164,8 +164,12 @@ struct device_node { int status; /* Current device status (non-zero is bad) */ int eeh_mode; /* See eeh.h for possible EEH_MODEs */ int eeh_config_addr; + int eeh_check_count; /* number of times device driver ignored error */ + int eeh_freeze_count; /* number of times this device froze up. */ + int eeh_is_bridge; /* device is pci-to-pci bridge */ struct pci_controller *phb; /* for pci devices */ struct iommu_table *iommu_table; /* for phb's or bridges */ + u32 config_space[16]; /* saved PCI config space */ struct property *properties; struct device_node *parent; ===== include/asm-ppc64/rtas.h 1.25 vs edited ===== --- 1.25/include/asm-ppc64/rtas.h 2004-11-25 00:42:42 -06:00 +++ edited/include/asm-ppc64/rtas.h 2005-01-20 17:25:37 -06:00 @@ -241,4 +241,6 @@ extern void rtas_stop_self(void); /* RMO buffer reserved for user-space RTAS use */ extern unsigned long rtas_rmo_buf; +extern int rtas_write_config(struct device_node *dn, int where, int size, u32 val); + #endif /* _PPC64_RTAS_H */ -------------- next part -------------- ===== drivers/pci/hotplug/rpaphp.h 1.11 vs edited ===== --- 1.11/drivers/pci/hotplug/rpaphp.h 2004-10-06 11:43:44 -05:00 +++ edited/drivers/pci/hotplug/rpaphp.h 2005-01-20 17:25:37 -06:00 @@ -125,7 +125,8 @@ extern int rpaphp_enable_pci_slot(struct extern int register_pci_slot(struct slot *slot); extern int rpaphp_unconfig_pci_adapter(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev); +extern void init_eeh_handler (void); +extern void exit_eeh_handler (void); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); ===== drivers/pci/hotplug/rpaphp_core.c 1.18 vs edited ===== --- 1.18/drivers/pci/hotplug/rpaphp_core.c 2004-10-06 11:43:44 -05:00 +++ edited/drivers/pci/hotplug/rpaphp_core.c 2005-01-20 17:25:37 -06:00 @@ -443,12 +443,18 @@ static int __init rpaphp_init(void) { info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + /* Get set to handle EEH events. */ + init_eeh_handler(); + /* read all the PRA info from the system */ return init_rpa(); } static void __exit rpaphp_exit(void) { + /* Let EEH know we are going away. */ + exit_eeh_handler(); + cleanup_slots(); } ===== drivers/pci/hotplug/rpaphp_pci.c 1.17 vs edited ===== --- 1.17/drivers/pci/hotplug/rpaphp_pci.c 2004-11-18 02:36:18 -06:00 +++ edited/drivers/pci/hotplug/rpaphp_pci.c 2005-02-01 18:57:35 -06:00 @@ -22,8 +22,12 @@ * Send feedback to * */ +#include +#include #include +#include #include +#include #include #include "../pci.h" /* for pci_add_new_bus */ @@ -62,6 +66,7 @@ int rpaphp_claim_resource(struct pci_dev root ? "Address space collision on" : "No parent found for", resource, dtype, pci_name(dev), res->start, res->end); + dump_stack(); } return err; } @@ -184,6 +189,19 @@ rpaphp_fixup_new_pci_devices(struct pci_ static int rpaphp_pci_config_bridge(struct pci_dev *dev); +static void rpaphp_eeh_add_bus_device(struct pci_bus *bus) +{ + struct pci_dev *dev; + list_for_each_entry(dev, &bus->devices, bus_list) { + eeh_add_device_late(dev); + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + struct pci_bus *subbus = dev->subordinate; + if (bus) + rpaphp_eeh_add_bus_device (subbus); + } + } +} + /***************************************************************************** rpaphp_pci_config_slot() will configure all devices under the given slot->dn and return the the first pci_dev. @@ -211,6 +229,8 @@ rpaphp_pci_config_slot(struct device_nod } if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) rpaphp_pci_config_bridge(dev); + + rpaphp_eeh_add_bus_device(bus); } return dev; } @@ -219,7 +239,6 @@ static int rpaphp_pci_config_bridge(stru { u8 sec_busno; struct pci_bus *child_bus; - struct pci_dev *child_dev; dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); @@ -236,11 +255,7 @@ static int rpaphp_pci_config_bridge(stru /* do pci_scan_child_bus */ pci_scan_child_bus(child_bus); - list_for_each_entry(child_dev, &child_bus->devices, bus_list) { - eeh_add_device_late(child_dev); - } - - /* fixup new pci devices without touching bus struct */ + /* Fixup new pci devices without touching bus struct */ rpaphp_fixup_new_pci_devices(child_bus, 0); /* Make the discovered devices available */ @@ -278,7 +293,7 @@ static void print_slot_pci_funcs(struct return; } #else -static void print_slot_pci_funcs(struct slot *slot) +static inline void print_slot_pci_funcs(struct slot *slot) { return; } @@ -360,7 +375,6 @@ static void rpaphp_eeh_remove_bus_device if (pdev) rpaphp_eeh_remove_bus_device(pdev); } - } return; } @@ -562,36 +576,181 @@ exit: return retval; } -struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev) +/** + * rpaphp_search_bus_for_dev - return 1 if device is under this bus, else 0 + * @bus: the bus to search for this device. + * @dev: the pci device we are looking for. + */ +static int rpaphp_search_bus_for_dev (struct pci_bus *bus, struct pci_dev *dev) { - struct list_head *tmp, *n; - struct slot *slot; + struct list_head *ln; + + if (!bus) return 0; + + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *pdev = pci_dev_b(ln); + if (pdev == dev) + return 1; + if (pdev->subordinate) { + int rc; + rc = rpaphp_search_bus_for_dev (pdev->subordinate, dev); + if (rc) + return 1; + } + } + return 0; +} + +/** + * rpaphp_find_slot - find and return the slot holding the device + * @dev: pci device for which we want the slot structure. + */ +static struct slot *rpaphp_find_slot(struct pci_dev *dev) +{ + struct list_head *tmp, *n; + struct slot *slot; list_for_each_safe(tmp, n, &rpaphp_slot_head) { struct pci_bus *bus; - struct list_head *ln; slot = list_entry(tmp, struct slot, rpaphp_slot_list); - if (slot->bridge == NULL) { - if (slot->dev_type == PCI_DEV) { - printk(KERN_WARNING "PCI slot missing bridge %s %s \n", - slot->name, slot->location); - } + + /* PHB's don't have bridges. */ + if (slot->bridge == NULL) continue; - } + + /* The PCI device could be the slot itself. */ + if (slot->bridge == dev) + return slot; bus = slot->bridge->subordinate; if (!bus) { + printk (KERN_WARNING "PCI bridge is missing bus: %s %s\n", + pci_name (slot->bridge), pci_pretty_name (slot->bridge)); continue; /* should never happen? */ } - for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { - struct pci_dev *pdev = pci_dev_b(ln); - if (pdev == dev) - return slot->hotplug_slot; - } - } + if (rpaphp_search_bus_for_dev (bus, dev)) + return slot; + } return NULL; } -EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot); +/* ------------------------------------------------------- */ +/** + * handle_eeh_events -- reset a PCI device after hard lockup. + * + * pSeries systems will isolate a PCI slot if the PCI-Host + * bridge detects address or data parity errors, DMA's + * occuring to wild addresses (which usually happen due to + * bugs in device drivers or in PCI adapter firmware). + * Slot isolations also occur if #SERR, #PERR or other misc + * PCI-related errors are detected. + * + * Recovery process consists of unplugging the device driver + * (which generated hotplug events to userspace), then issuing + * a PCI #RST to the device, then reconfiguring the PCI config + * space for all bridges & devices under this slot, and then + * finally restarting the device drivers (which cause a second + * set of hotplug events to go out to userspace). + */ +int eeh_reset_device (struct pci_dev *dev, int reconfig) +{ + int freeze_count=0; + struct slot *frozen_slot; + + if (!dev) + return 1; + + frozen_slot = rpaphp_find_slot(dev); + if (!frozen_slot) + { + printk (KERN_ERR "EEH: Cannot find PCI slot for %s %s\n", + pci_name(dev), pci_pretty_name (dev)); + return 1; + } + + if (frozen_slot->dn->child) + freeze_count = frozen_slot->dn->child->eeh_freeze_count; + + if (reconfig) rpaphp_unconfig_pci_adapter (frozen_slot); + + freeze_count ++; + if (freeze_count > EEH_MAX_ALLOWED_FREEZES) { + /* + * About 90% of all real-life EEH failures in the field + * are due to poorly seated PCI cards. Only 10% or so are + * due to actual, failed cards + */ + printk (KERN_ERR + "EEH: device %s:%s has failed %d times \n" + "and has been permanently disabled. Please try reseating\n" + "this device or replacing it.\n", + pci_name (dev), + pci_pretty_name (dev), + freeze_count); + return 1; + } + printk (KERN_WARNING + "EEH: This device has failed %d times since last reboot: %s:%s\n", + freeze_count, + pci_name (dev), + pci_pretty_name (dev)); + + /* Reset the pci controller. (Asserts RST#; resets config space). + * Reconfigure bridges and devices */ + rtas_set_slot_reset (frozen_slot->dn->child); + + rtas_configure_bridge(frozen_slot->dn); + eeh_restore_bars(frozen_slot->dn->child); + + /* Give the system 5 seconds to finish running the user-space + * hotplug scripts, e.g. ifdown for ethernet. Yes, this is a hack, + * but if we don't do this, weird things happen. + */ + if (reconfig) { + ssleep (5); + rpaphp_enable_pci_slot (frozen_slot); + } + + /* Store the freeze count with the pci adapter, and not the slot. + * This way, if the device is replaced, the count is cleared. + */ + if (frozen_slot->dn->child) + frozen_slot->dn->child->eeh_freeze_count = freeze_count; + + return 0; +} + +int handle_eeh_events (struct notifier_block *self, + unsigned long reason, void *ev) +{ + struct eeh_event *event = ev; + + if (!event->dev) + { + if (event->dn) + printk ("EEH: Cannot find the PCI device for dn %s\n", + event->dn->full_name); + else + printk ("EEH: EEH error caught, but no PCI device specified!\n"); + return 1; + } + +if(!strncmp (pci_pretty_name (event->dev), "Mylex Corporation Gemstone", 25)) return 0; + return eeh_reset_device (event->dev, 1); +} + +static struct notifier_block eeh_block; + +void __init init_eeh_handler (void) +{ + eeh_block.notifier_call = handle_eeh_events; + eeh_register_notifier (&eeh_block); +} + +void __exit exit_eeh_handler (void) +{ + eeh_unregister_notifier (&eeh_block); +} + From benh at kernel.crashing.org Wed Feb 2 15:17:48 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Wed, 02 Feb 2005 15:17:48 +1100 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: <20050202011511.GB9140@austin.ibm.com> References: <20050202011511.GB9140@austin.ibm.com> Message-ID: <1107317868.1665.68.camel@gaston> Ok, built your stuff, applied, setup a partition on an SF2 with an ethernet e100 card in a hotplug slot, got the errinj tools (0.8.5), enabled error injection in the FSP, rebooted the partition, and then did: linux:~ # /opt/ibmras/errinjct eeh -f 0 -p U7311.D20.10488BA-P1-C02-T1 Injecting an ioa-bus-error... cpu 0x0: Vector: 700 (Program Check) at [c0000000332c38b0] pc: 00000000077d9374 lr: 000000000000dafc sp: c0000000332c3b30 msr: 81002 current = 0xc000000034b5b030 paca = 0xc000000000573000 pid = 11206, comm = errinjct cpu 0x0: Vector: 700 (Program Check) at [c0000000332c2e00] pc: 00000000077d9374 lr: 000000000000dafc sp: c0000000332c3080 msr: 81002 current = 0xc000000034b5b030 paca = 0xc000000000573000 pid = 11206, comm = errinjct cpu 0x0: Exception 700 (Program Check) in xmon, returning to main loop xmon: WARNING: bad recursive fault on cpu 0x0 Looks like it died in RTAS or something weird like that ... Ben. From benh at kernel.crashing.org Wed Feb 2 17:11:14 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Wed, 02 Feb 2005 17:11:14 +1100 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: <1107317868.1665.68.camel@gaston> References: <20050202011511.GB9140@austin.ibm.com> <1107317868.1665.68.camel@gaston> Message-ID: <1107324674.5625.79.camel@gaston> On Wed, 2005-02-02 at 15:17 +1100, Benjamin Herrenschmidt wrote: > Ok, built your stuff, applied, setup a partition on an SF2 with an > ethernet e100 card in a hotplug slot, got the errinj tools (0.8.5), > enabled error injection in the FSP, rebooted the partition, and then > did: > > .../... Ok, it looks like rtas gets destroyed in memory, apparently by the the injection tool itself who is mmap'ing crap. Unfortunately, the .tar.gz that comes with it on the RAS page doesn't contains what it advertises (instead, it contains the source for the rtas error daemon), so I can't debug the tool. Linas, can you fix the source package (and send me the source for errinjct) ? Ben. From arnd at arndb.de Wed Feb 2 21:05:36 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Wed, 2 Feb 2005 11:05:36 +0100 Subject: pci: Arch hook to determine config space size In-Reply-To: <1107233864.5963.65.camel@gaston> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <41FF0B0D.8020003@us.ibm.com> <1107233864.5963.65.camel@gaston> Message-ID: <200502021105.42249.arnd@arndb.de> On Dinsdag 01 Februar 2005 05:57, Benjamin Herrenschmidt wrote: > BTW. I'm thinking about moving all those PCI/VIO related fields out of > struct device_node to their own structure and keep only a pointer to > that structure in device_node. That way, we avoid the bloat for every > single non-pci node in the system, and we can have different structures > for different bus types (along with proper iommu function pointers and > that sort-of-thing). How about something along the lines of this patch? Instead of adding a pointer to the pci data from the device node, it embeds the node inside a new struct pci_device_node. The patch is not complete and therefore not expected to work as is, but maybe you want to reuse it. The interesting part that is missing is creating and destroying pci_device_nodes in prom.c, maybe you have an idea how to do that. I'm also not sure about eeh. Are the eeh functions known to be called only for device_nodes of PCI devices? If not, eeh_mode and eeh_config_addr might have to stay inside of device_node. Arnd <>< Signed-off-by: Arnd Bergmann Index: linux-2.6-64/arch/ppc64/kernel/pci.h =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/pci.h 2005-01-24 23:46:37.000000000 +0100 +++ linux-2.6-64/arch/ppc64/kernel/pci.h 2005-02-02 00:11:01.485740824 +0100 @@ -29,8 +29,8 @@ /* PCI device_node operations */ struct device_node; -typedef void *(*traverse_func)(struct device_node *me, void *data); -void *traverse_pci_devices(struct device_node *start, traverse_func pre, +typedef void *(*traverse_func)(struct pci_device_node *me, void *data); +void *traverse_pci_devices(struct pci_device_node *start, traverse_func pre, void *data); void pci_devs_phb_init(void); Index: linux-2.6-64/arch/ppc64/kernel/pSeries_iommu.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/pSeries_iommu.c 2005-02-01 22:53:00.673332472 +0100 +++ linux-2.6-64/arch/ppc64/kernel/pSeries_iommu.c 2005-02-02 00:11:01.486740672 +0100 @@ -48,7 +48,7 @@ #define DBG(fmt...) -extern int is_python(struct device_node *); +extern int is_python(struct pci_device_node *); static void tce_build_pSeries(struct iommu_table *tbl, long index, long npages, unsigned long uaddr, @@ -289,7 +289,7 @@ * Currently we hard code these sizes (more or less). */ static void iommu_table_setparms_lpar(struct pci_controller *phb, - struct device_node *dn, + struct pci_device_node *dn, struct iommu_table *tbl, unsigned int *dma_window) { @@ -308,7 +308,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) { - struct device_node *dn, *pdn; + struct pci_device_node *dn, *pdn; DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); @@ -331,7 +331,7 @@ DBG("Python root bus %s\n", bus->name); - iohole = (unsigned int *)get_property(dn, "io-hole", 0); + iohole = (unsigned int *)get_property(&dn->node, "io-hole", 0); if (iohole) { /* On first bus we need to leave room for the @@ -349,7 +349,7 @@ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms(dn->phb, dn, tbl); + iommu_table_setparms(dn->phb, &dn->node, tbl); dn->iommu_table = iommu_init_table(tbl); } else { /* 256 MB window by default */ @@ -368,7 +368,7 @@ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms(dn->phb, dn, tbl); + iommu_table_setparms(dn->phb, &dn->node, tbl); dn->iommu_table = iommu_init_table(tbl); } else { @@ -382,17 +382,19 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) { struct iommu_table *tbl; - struct device_node *dn, *pdn; + struct pci_device_node *dn, *pdn; + struct device_node *n; unsigned int *dma_window = NULL; dn = pci_bus_to_OF_node(bus); /* Find nearest ibm,dma-window, walking up the device tree */ - for (pdn = dn; pdn != NULL; pdn = pdn->parent) { - dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); + for (n = &dn->node; n; n = n->parent) { + dma_window = (unsigned int *)get_property(n, "ibm,dma-window", NULL); if (dma_window != NULL) break; } + pdn = to_pci_node(n); if (dma_window == NULL) { DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name); @@ -420,7 +422,7 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) { - struct device_node *dn, *mydn; + struct pci_device_node *dn, *mydn; DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name); /* Now copy the iommu_table ptr from the bus device down to the @@ -430,7 +432,7 @@ mydn = dn = pci_device_to_OF_node(dev); while (dn && dn->iommu_table == NULL) - dn = dn->parent; + dn = to_pci_node(dn->node.parent); if (dn) { mydn->iommu_table = dn->iommu_table; Index: linux-2.6-64/include/asm-ppc64/pci-bridge.h =================================================================== --- linux-2.6-64.orig/include/asm-ppc64/pci-bridge.h 2005-01-24 23:47:11.000000000 +0100 +++ linux-2.6-64/include/asm-ppc64/pci-bridge.h 2005-02-02 00:11:01.486740672 +0100 @@ -53,22 +53,23 @@ /* Get a device_node from a pci_dev. This code must be fast except in the case * where the sysdata is incorrect and needs to be fixed up (hopefully just once) */ -static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) +static inline struct pci_device_node *pci_device_to_OF_node(struct pci_dev *dev) { struct device_node *dn = dev->sysdata; + struct pci_device_node *pdn = to_pci_node(dn); - if (dn->devfn == dev->devfn && dn->busno == dev->bus->number) - return dn; /* fast path. sysdata is good */ + if (pdn->devfn == dev->devfn && pdn->busno == dev->bus->number) + return pdn; /* fast path. sysdata is good */ else - return fetch_dev_dn(dev); + return to_pci_node(fetch_dev_dn(dev)); } -static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) +static inline struct pci_device_node *pci_bus_to_OF_node(struct pci_bus *bus) { if (bus->self) return pci_device_to_OF_node(bus->self); else - return bus->sysdata; /* Must be root bus (PHB) */ + return to_pci_node(bus->sysdata); /* Must be root bus (PHB) */ } extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, @@ -83,7 +84,7 @@ struct device_node *busdn = bus->sysdata; BUG_ON(busdn == NULL); - return busdn->phb; + return to_pci_node(busdn)->phb; } #endif Index: linux-2.6-64/include/asm-ppc64/eeh.h =================================================================== --- linux-2.6-64.orig/include/asm-ppc64/eeh.h 2005-02-01 22:32:12.361104776 +0100 +++ linux-2.6-64/include/asm-ppc64/eeh.h 2005-02-02 00:11:01.487740520 +0100 @@ -27,7 +27,7 @@ struct pci_dev; struct device_node; -struct device_node; +struct pci_device_node; struct notifier_block; #ifdef CONFIG_EEH @@ -40,7 +40,7 @@ void __init eeh_init(void); unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val); -int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev); +int eeh_dn_check_failure(struct pci_device_node *dn, struct pci_dev *dev); void __init pci_addr_cache_build(void); /** @@ -52,7 +52,7 @@ * device (including config space i/o). Call eeh_add_device_late * to finish the eeh setup for this device. */ -void eeh_add_device_early(struct device_node *); +void eeh_add_device_early(struct pci_device_node *); void eeh_add_device_late(struct pci_dev *); /** Index: linux-2.6-64/arch/ppc64/kernel/sys_ppc32.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/sys_ppc32.c 2005-02-01 22:53:00.673332472 +0100 +++ linux-2.6-64/arch/ppc64/kernel/sys_ppc32.c 2005-02-02 00:11:01.487740520 +0100 @@ -744,7 +744,7 @@ struct pci_controller* hose; struct list_head *ln; struct pci_bus *bus = NULL; - struct device_node *hose_node; + struct pci_device_node *hose_node; /* Argh ! Please forgive me for that hack, but that's the * simplest way to get existing XFree to not lockup on some @@ -771,7 +771,7 @@ if (bus == NULL || bus->sysdata == NULL) return -ENODEV; - hose_node = (struct device_node *)bus->sysdata; + hose_node = to_pci_node(bus->sysdata); hose = hose_node->phb; switch (which) { Index: linux-2.6-64/arch/ppc64/kernel/iommu.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/iommu.c 2005-01-24 23:46:37.000000000 +0100 +++ linux-2.6-64/arch/ppc64/kernel/iommu.c 2005-02-02 00:11:01.488740368 +0100 @@ -432,7 +432,7 @@ return tbl; } -void iommu_free_table(struct device_node *dn) +void iommu_free_table(struct pci_device_node *dn) { struct iommu_table *tbl = dn->iommu_table; unsigned long bitmap_sz, i; @@ -440,7 +440,7 @@ if (!tbl || !tbl->it_map) { printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__, - dn->full_name); + dn->node.full_name); return; } @@ -449,7 +449,7 @@ for (i = 0; i < (tbl->it_size/64); i++) { if (tbl->it_map[i] != 0) { printk(KERN_WARNING "%s: Unexpected TCEs for %s\n", - __FUNCTION__, dn->full_name); + __FUNCTION__, dn->node.full_name); break; } } Index: linux-2.6-64/include/asm-ppc64/iommu.h =================================================================== --- linux-2.6-64.orig/include/asm-ppc64/iommu.h 2005-01-24 23:47:11.000000000 +0100 +++ linux-2.6-64/include/asm-ppc64/iommu.h 2005-02-02 00:11:01.488740368 +0100 @@ -101,6 +101,7 @@ #endif /* CONFIG_PPC_ISERIES */ struct scatterlist; +struct pci_device_node; #ifdef CONFIG_PPC_MULTIPLATFORM @@ -109,14 +110,14 @@ extern void iommu_setup_u3(void); /* Frees table for an individual device node */ -extern void iommu_free_table(struct device_node *dn); +extern void iommu_free_table(struct pci_device_node *dn); #endif /* CONFIG_PPC_MULTIPLATFORM */ #ifdef CONFIG_PPC_PSERIES /* Creates table for an individual device node */ -extern void iommu_devnode_init_pSeries(struct device_node *dn); +extern void iommu_devnode_init_pSeries(struct pci_device_node *dn); #endif /* CONFIG_PPC_PSERIES */ Index: linux-2.6-64/arch/ppc64/kernel/pci.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/pci.c 2005-01-24 23:46:36.000000000 +0100 +++ linux-2.6-64/arch/ppc64/kernel/pci.c 2005-02-02 00:11:01.489740216 +0100 @@ -447,13 +447,13 @@ static ssize_t pci_show_devspec(struct device *dev, char *buf) { struct pci_dev *pdev; - struct device_node *np; + struct pci_device_node *np; pdev = to_pci_dev (dev); np = pci_device_to_OF_node(pdev); - if (np == NULL || np->full_name == NULL) + if (np == NULL || np->node.full_name == NULL) return 0; - return sprintf(buf, "%s", np->full_name); + return sprintf(buf, "%s", np->node.full_name); } static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); #endif /* CONFIG_PPC_MULTIPLATFORM */ @@ -734,7 +734,8 @@ */ int pcibios_scan_all_fns(struct pci_bus *bus, int devfn) { - struct device_node *busdn, *dn; + struct pci_device_node *busdn; + struct device_node *dn; if (bus->self) busdn = pci_device_to_OF_node(bus->self); @@ -749,8 +750,8 @@ * device tree. If they are then we need to scan all the * functions of this slot. */ - for (dn = busdn->child; dn; dn = dn->sibling) - if ((dn->devfn >> 3) == (devfn >> 3)) + for (dn = busdn->node.child; dn; dn = dn->sibling) + if ((to_pci_node(dn)->devfn >> 3) == (devfn >> 3)) return 1; return 0; @@ -851,7 +852,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev) { u8 intpin; - struct device_node *node; + struct pci_device_node *node; pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intpin); if (intpin == 0) @@ -861,10 +862,10 @@ if (node == NULL) return -1; - if (node->n_intrs == 0) + if (node->node.n_intrs == 0) return -1; - pci_dev->irq = node->intrs[0].line; + pci_dev->irq = node->node.intrs[0].line; pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq); Index: linux-2.6-64/include/asm-ppc64/prom.h =================================================================== --- linux-2.6-64.orig/include/asm-ppc64/prom.h 2005-02-01 22:32:12.365104168 +0100 +++ linux-2.6-64/include/asm-ppc64/prom.h 2005-02-02 00:11:01.490740064 +0100 @@ -131,15 +131,6 @@ struct interrupt_info *intrs; char *full_name; - /* PCI stuff probably doesn't belong here */ - int busno; /* for pci devices */ - int bussubno; /* for pci devices */ - int devfn; /* for pci devices */ - int eeh_mode; /* See eeh.h for possible EEH_MODEs */ - int eeh_config_addr; - struct pci_controller *phb; /* for pci devices */ - struct iommu_table *iommu_table; /* for phb's or bridges */ - struct property *properties; struct device_node *parent; struct device_node *child; @@ -153,6 +144,22 @@ unsigned long _flags; }; +struct pci_device_node { + int busno; + int bussubno; + int devfn; + int eeh_mode; /* See eeh.h for possible EEH_MODEs */ + int eeh_config_addr; + struct pci_controller *phb; + struct iommu_table *iommu_table; /* for phb's or bridges */ + struct device_node node; +}; + +static inline struct pci_device_node *to_pci_node(struct device_node *n) +{ + return n ? container_of(n, struct pci_device_node, node) : NULL; +} + extern struct device_node *of_chosen; /* flag descriptions */ Index: linux-2.6-64/arch/ppc64/kernel/pci_iommu.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/pci_iommu.c 2005-01-24 23:46:37.000000000 +0100 +++ linux-2.6-64/arch/ppc64/kernel/pci_iommu.c 2005-02-02 00:11:01.490740064 +0100 @@ -48,7 +48,7 @@ * pci_device_to_OF_node since ->sysdata will have been initialised * in the iommu init code for all devices. */ -#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata)) +#define PCI_GET_DN(dev) (to_pci_node(((dev)->sysdata))) static inline struct iommu_table *devnode_table(struct pci_dev *dev) { Index: linux-2.6-64/arch/ppc64/kernel/pci_dn.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/pci_dn.c 2005-01-24 23:46:37.000000000 +0100 +++ linux-2.6-64/arch/ppc64/kernel/pci_dn.c 2005-02-02 00:11:01.490740064 +0100 @@ -34,13 +34,13 @@ * Traverse_func that inits the PCI fields of the device node. * NOTE: this *must* be done before read/write config to the device. */ -static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) +static void * __devinit update_dn_pci_info(struct pci_device_node *dn, void *data) { struct pci_controller *phb = data; u32 *regs; dn->phb = phb; - regs = (u32 *)get_property(dn, "reg", NULL); + regs = (u32 *)get_property(&dn->node, "reg", NULL); if (regs) { /* First register entry is addr (00BBSS00) */ dn->busno = (regs[0] >> 16) & 0xff; @@ -67,21 +67,21 @@ * one of these nodes we also assume its siblings are non-pci for * performance. */ -void *traverse_pci_devices(struct device_node *start, traverse_func pre, +void *traverse_pci_devices(struct pci_device_node *start, traverse_func pre, void *data) { struct device_node *dn, *nextdn; void *ret; /* We started with a phb, iterate all childs */ - for (dn = start->child; dn; dn = nextdn) { + for (dn = start->node.child; dn; dn = nextdn) { u32 *classp, class; nextdn = NULL; classp = (u32 *)get_property(dn, "class-code", NULL); class = classp ? *classp : 0; - if (pre && ((ret = pre(dn, data)) != NULL)) + if (pre && ((ret = pre(to_pci_node(dn), data)) != NULL)) return ret; /* If we are a PCI bridge, go down */ @@ -96,7 +96,7 @@ /* Walk up to next valid sibling. */ do { dn = dn->parent; - if (dn == start) + if (dn == &start->node) return NULL; } while (dn->sibling == NULL); nextdn = dn->sibling; @@ -107,7 +107,7 @@ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) { - struct device_node * dn = (struct device_node *) phb->arch_data; + struct pci_device_node *dn = to_pci_node(phb->arch_data); /* PHB nodes themselves must not match */ dn->devfn = dn->busno = -1; @@ -121,7 +121,7 @@ * Traversal func that looks for a value. * If found, the device_node is returned (thus terminating the traversal). */ -static void *is_devfn_node(struct device_node *dn, void *data) +static void *is_devfn_node(struct pci_device_node *dn, void *data) { int busno = ((unsigned long)data >> 8) & 0xff; int devfn = ((unsigned long)data) & 0xff; @@ -144,13 +144,13 @@ */ struct device_node *fetch_dev_dn(struct pci_dev *dev) { - struct device_node *orig_dn = dev->sysdata; + struct pci_device_node *orig_dn = to_pci_node(dev->sysdata); struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */ - struct device_node *phb_dn; + struct pci_device_node *phb_dn; struct device_node *dn; unsigned long searchval = (dev->bus->number << 8) | dev->devfn; - phb_dn = phb->arch_data; + phb_dn = to_pci_node(phb->arch_data); dn = traverse_pci_devices(phb_dn, is_devfn_node, (void *)searchval); if (dn) dev->sysdata = dn; Index: linux-2.6-64/arch/ppc64/kernel/eeh.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/eeh.c 2005-02-02 00:10:53.126011696 +0100 +++ linux-2.6-64/arch/ppc64/kernel/eeh.c 2005-02-02 00:11:06.039048616 +0100 @@ -254,7 +254,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) { - struct device_node *dn; + struct pci_device_node *dn; int i; int inserted = 0; @@ -413,7 +413,7 @@ * @dn: device node to read * @rets: array to return results in */ -static int read_slot_reset_state(struct device_node *dn, int rets[]) +static int read_slot_reset_state(struct pci_device_node *dn, int rets[]) { int token, outputs; @@ -528,7 +528,7 @@ * * It is safe to call this routine in an interrupt context. */ -int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) +int eeh_dn_check_failure(struct pci_device_node *dn, struct pci_dev *dev) { int ret; int rets[3]; @@ -603,7 +603,7 @@ spin_unlock_irqrestore(&slot_errbuf_lock, flags); printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n", - rets[0], dn->name, dn->full_name); + rets[0], dn->node.name, dn->node.full_name); event = kmalloc(sizeof(*event), GFP_ATOMIC); if (event == NULL) { eeh_panic(dev, reset_state); @@ -611,7 +611,7 @@ } event->dev = dev; - event->dn = dn; + event->dn = &dn->node; event->reset_state = reset_state; /* We may or may not be called in an interrupt context */ @@ -647,7 +647,7 @@ { unsigned long addr; struct pci_dev *dev; - struct device_node *dn; + struct pci_device_node *dn; /* Finding the phys addr + pci device; this is pretty quick. */ addr = eeh_token_to_phys((unsigned long __force) token); @@ -670,8 +670,9 @@ }; /* Enable eeh for the given device node. */ -static void *early_enable_eeh(struct device_node *dn, void *data) +static void *early_enable_eeh(struct pci_device_node *pdn, void *data) { + struct device_node *dn = &pdn->node; struct eeh_early_enable_info *info = data; int ret; char *status = get_property(dn, "status", NULL); @@ -681,7 +682,7 @@ u32 *regs; int enable; - dn->eeh_mode = 0; + pdn->eeh_mode = 0; if (status && strcmp(status, "ok") != 0) return NULL; /* ignore devices with bad status */ @@ -692,7 +693,7 @@ /* There is nothing to check on PCI to ISA bridges */ if (dn->type && !strcmp(dn->type, "isa")) { - dn->eeh_mode |= EEH_MODE_NOCHECK; + pdn->eeh_mode |= EEH_MODE_NOCHECK; return NULL; } @@ -709,7 +710,7 @@ enable = 0; if (!enable) - dn->eeh_mode |= EEH_MODE_NOCHECK; + pdn->eeh_mode |= EEH_MODE_NOCHECK; /* Ok... see if this device supports EEH. Some do, some don't, * and the only way to find out is to check each and every one. */ @@ -722,8 +723,8 @@ EEH_ENABLE); if (ret == 0) { eeh_subsystem_enabled = 1; - dn->eeh_mode |= EEH_MODE_SUPPORTED; - dn->eeh_config_addr = regs[0]; + pdn->eeh_mode |= EEH_MODE_SUPPORTED; + pdn->eeh_config_addr = regs[0]; #ifdef DEBUG printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name); #endif @@ -731,10 +732,12 @@ /* This device doesn't support EEH, but it may have an * EEH parent, in which case we mark it as supported. */ - if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) { + if (dn->parent && (to_pci_node(dn->parent)->eeh_mode + & EEH_MODE_SUPPORTED)) { /* Parent supports EEH. */ - dn->eeh_mode |= EEH_MODE_SUPPORTED; - dn->eeh_config_addr = dn->parent->eeh_config_addr; + pdn->eeh_mode |= EEH_MODE_SUPPORTED; + pdn->eeh_config_addr = + to_pci_node(dn->parent)->eeh_config_addr; return NULL; } } @@ -798,7 +801,7 @@ info.buid_lo = BUID_LO(buid); info.buid_hi = BUID_HI(buid); - traverse_pci_devices(phb, early_enable_eeh, &info); + traverse_pci_devices(to_pci_node(phb), early_enable_eeh, &info); } if (eeh_subsystem_enabled) @@ -819,7 +822,7 @@ * on the CEC architecture, type of the device, on earlier boot * command-line arguments & etc. */ -void eeh_add_device_early(struct device_node *dn) +void eeh_add_device_early(struct pci_device_node *dn) { struct pci_controller *phb; struct eeh_early_enable_info info; Index: linux-2.6-64/arch/ppc64/kernel/prom.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/prom.c 2005-02-02 00:10:53.129011240 +0100 +++ linux-2.6-64/arch/ppc64/kernel/prom.c 2005-02-02 00:11:06.041048312 +0100 @@ -1802,8 +1802,11 @@ */ static void of_cleanup_node(struct device_node *np) { - if (np->iommu_table && get_property(np, "ibm,dma-window", NULL)) - iommu_free_table(np); + if (get_property(np, "ibm,dma-window", NULL)) { + struct pci_device_node *p = to_pci_node(np); + if (p->iommu_table) + iommu_free_table(p); + } } /* Index: linux-2.6-64/arch/ppc64/kernel/pSeries_pci.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/pSeries_pci.c 2005-02-02 00:10:53.127011544 +0100 +++ linux-2.6-64/arch/ppc64/kernel/pSeries_pci.c 2005-02-02 00:11:06.040048464 +0100 @@ -52,14 +52,12 @@ extern struct mpic *pSeries_mpic; -static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) +static int rtas_read_config(struct pci_device_node *dn, int where, int size, u32 *val) { int returnval = -1; unsigned long buid, addr; int ret; - if (!dn) - return PCIBIOS_DEVICE_NOT_FOUND; if (where & (size - 1)) return PCIBIOS_BAD_REGISTER_NUMBER; @@ -87,7 +85,8 @@ unsigned int devfn, int where, int size, u32 *val) { - struct device_node *busdn, *dn; + struct pci_device_node *busdn; + struct device_node *dn; if (bus->self) busdn = pci_device_to_OF_node(bus->self); @@ -95,13 +94,15 @@ busdn = bus->sysdata; /* must be a phb */ /* Search only direct children of the bus */ - for (dn = busdn->child; dn; dn = dn->sibling) - if (dn->devfn == devfn) - return rtas_read_config(dn, where, size, val); + for (dn = busdn->node.child; dn; dn = dn->sibling) { + struct pci_device_node *pdn = to_pci_node(dn); + if (pdn->devfn == devfn) + return rtas_read_config(pdn, where, size, val); + } return PCIBIOS_DEVICE_NOT_FOUND; } -static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) +static int rtas_write_config(struct pci_device_node *dn, int where, int size, u32 val) { unsigned long buid, addr; int ret; @@ -129,7 +130,8 @@ unsigned int devfn, int where, int size, u32 val) { - struct device_node *busdn, *dn; + struct pci_device_node *busdn; + struct device_node *dn; if (bus->self) busdn = pci_device_to_OF_node(bus->self); @@ -137,9 +139,11 @@ busdn = bus->sysdata; /* must be a phb */ /* Search only direct children of the bus */ - for (dn = busdn->child; dn; dn = dn->sibling) - if (dn->devfn == devfn) - return rtas_write_config(dn, where, size, val); + for (dn = busdn->node.child; dn; dn = dn->sibling) { + struct pci_device_node *pdn = to_pci_node(dn); + if (pdn->devfn == devfn) + return rtas_write_config(pdn, where, size, val); + } return PCIBIOS_DEVICE_NOT_FOUND; } -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050202/a095da2d/attachment.pgp From sleddog at us.ibm.com Thu Feb 3 03:50:34 2005 From: sleddog at us.ibm.com (Dave C Boutcher) Date: Wed, 2 Feb 2005 10:50:34 -0600 Subject: HUPin the ttys in drivers/char/hvcs.c In-Reply-To: <16895.55751.310549.454083@kitch0.watson.ibm.com> References: <16895.55751.310549.454083@kitch0.watson.ibm.com> Message-ID: <20050202165034.GA17490@cs.umn.edu> On Tue, Feb 01, 2005 at 02:34:31PM -0500, Jimi Xenidis wrote: > > In an LPAR environment there is the hvc (client side VTERM) and the > hvcs (server side VTERM). If the /dev/hvcs is paired/registered > with a VTERM what is removed (as in the case of LPAR death) the > H_GET_TERM_CHAR hcall will eventually return H_Closed. > > IMHO, when this event occurs the /dev/hvcs should get HUPed and > ultimately an H_FREE_VTERM should occurs on the channel. > Otherwise the administrator would have to clean up after it. I think a typical case is where the administrator leaves the console active for long periods of time (so as to have a record of things like panics.) I think a reboot of the client partition also causes H_Closed (though I could be wrong about that, and Ryan is off having a baby so I can't ask him.) I wouldn't want a client reboot to cause a HUP. -- Dave Boutcher From nfont at austin.ibm.com Thu Feb 3 04:30:05 2005 From: nfont at austin.ibm.com (Nathan Fontenot) Date: Wed, 02 Feb 2005 11:30:05 -0600 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: <1107324674.5625.79.camel@gaston> References: <20050202011511.GB9140@austin.ibm.com> <1107317868.1665.68.camel@gaston> <1107324674.5625.79.camel@gaston> Message-ID: <1107365406.32699.7.camel@dyn95394167.austin.ibm.com> On Wed, 2005-02-02 at 17:11 +1100, Benjamin Herrenschmidt wrote: > Unfortunately, the > .tar.gz that comes with it on the RAS page doesn't contains what it > advertises (instead, it contains the source for the rtas error daemon), > so I can't debug the tool. > > Linas, can you fix the source package (and send me the source for > errinjct) ? > > Ben. > Oops. The source tarball on the website should contain the correct source code now. -Nathan F. From linas at austin.ibm.com Thu Feb 3 06:08:57 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Wed, 2 Feb 2005 13:08:57 -0600 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: <1107317868.1665.68.camel@gaston> References: <20050202011511.GB9140@austin.ibm.com> <1107317868.1665.68.camel@gaston> Message-ID: <20050202190857.GC9140@austin.ibm.com> On Wed, Feb 02, 2005 at 03:17:48PM +1100, Benjamin Herrenschmidt was heard to remark: > > cpu 0x0: Vector: 700 (Program Check) at [c0000000332c38b0] > pc: 00000000077d9374 > lr: 000000000000dafc > sp: c0000000332c3b30 > msr: 81002 > current = 0xc000000034b5b030 > paca = 0xc000000000573000 > pid = 11206, comm = errinjct MSR shows it died in 32-bit real mode: i.e. in the firmware. I've seen this sporadically, I've assumed it was the off-kilter firmware on the box I have access to. But since you're seeing it... John Rose, the maintainer of librtas (the user space lib that does the memory mapping) tells me that even if corrupt values are passed to RTAS, the firmware should not crash. --linas From cfriesen at nortel.com Thu Feb 3 06:01:33 2005 From: cfriesen at nortel.com (Chris Friesen) Date: Wed, 02 Feb 2005 13:01:33 -0600 Subject: buggy mlock() behaviour in 2.6.9 on ppc64? In-Reply-To: <20050202181737.GA29505@austin.ibm.com> References: <420117CA.8090507@nortelnetworks.com> <20050202181737.GA29505@austin.ibm.com> Message-ID: <4201238D.4030700@nortel.com> Olof Johansson wrote: > On Wed, Feb 02, 2005 at 12:11:22PM -0600, Chris Friesen wrote: >>I've got a simple test app that tries to mmap() and mlock() an amount of >>memory specified on the commandline. >>With the ppc64 kernel, however, the system hangs, and the fans speed >>starts increasing. It seems like it doesn't realize that there is >>simply no way that it will ever be able to succeed. >> >>Is this expected behaviour for ppc64? > linuxppc64-dev at ozlabs.org is the ppc64 mailing list, you might want to > Cc: there instead for the ppc64 questions. Ah, right. I'm copying the list if anyone else wants to take a look. > Anyhow, can you send me the testcase? Sounds like you're running on a > G5, it's easier to debug on a pSeries where we have debugger console. > Unless you have a stealth card in the machine? Yes, I am on a G5 and I don't have a stealth card. Here's the testcase. I've got 2gig of physical memory. "chewtest 1 1000000" gives an error that it can't allocate memory "chewtest 1 500000" gets killed by the oom killer "chewtest 1000 1000" just sits there Chris #include #include #include #include #include #include #include #include #include int main(int argc, char **argv) { if (argc != 3) { printf("usage: %s \n", *argv); return -1; } int mappings = atoi(argv[1]); int ppm = atoi(argv[2]); int mapsize = sysconf(_SC_PAGESIZE)*ppm; int i; int rc; void *buf; for (i=0;i References: <16895.55751.310549.454083@kitch0.watson.ibm.com> Message-ID: <1107373851.16433.8.camel@localhost.localdomain> On Tue, 2005-02-01 at 14:34 -0500, Jimi Xenidis wrote: > In an LPAR environment there is the hvc (client side VTERM) and the > hvcs (server side VTERM). If the /dev/hvcs is paired/registered > with a VTERM what is removed (as in the case of LPAR death) the > H_GET_TERM_CHAR hcall will eventually return H_Closed. > > IMHO, when this event occurs the /dev/hvcs should get HUPed and > ultimately an H_FREE_VTERM should occurs on the channel. > Otherwise the administrator would have to clean up after it. > > Thoughts? > -JX Hey Jimi, Great catch, you're absolutely right. At the moment, hvcs uses /arch/ppc64/kernel/hvconsole.c::hvc_get_chars() to gather character data from the hypervisor. If the partner vty adapter is removed, as you say, an H_Closed will be returned to hvc_get_chars(). This function doesn't do anything with errors atm. I think the best thing to do would be to update the arch code to return an errno when errors are encountered. Then hvcs can kick off a hangup if a partner adapter is removed. Thanks for catching this Jimi. It may take me a bit to get a fix. I have to make sure the hvcs scheduling algorithm can properly handle this scenario. -- Ryan Arnold IBM Linux Technology Center From paulus at samba.org Thu Feb 3 08:10:45 2005 From: paulus at samba.org (Paul Mackerras) Date: Thu, 3 Feb 2005 08:10:45 +1100 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: <20050202190857.GC9140@austin.ibm.com> References: <20050202011511.GB9140@austin.ibm.com> <1107317868.1665.68.camel@gaston> <20050202190857.GC9140@austin.ibm.com> Message-ID: <16897.16853.103205.119522@cargo.ozlabs.ibm.com> Linas Vepstas writes: > On Wed, Feb 02, 2005 at 03:17:48PM +1100, Benjamin Herrenschmidt was heard to remark: > > > > cpu 0x0: Vector: 700 (Program Check) at [c0000000332c38b0] > > pc: 00000000077d9374 > > lr: 000000000000dafc > > sp: c0000000332c3b30 > > msr: 81002 > > current = 0xc000000034b5b030 > > paca = 0xc000000000573000 > > pid = 11206, comm = errinjct > > MSR shows it died in 32-bit real mode: i.e. in the firmware. > > I've seen this sporadically, I've assumed it was the off-kilter firmware > on the box I have access to. But since you're seeing it... > > John Rose, the maintainer of librtas (the user space lib that does > the memory mapping) tells me that even if corrupt values are passed to > RTAS, the firmware should not crash. When Ben and I dug into it a little using xmon, it turned out that 77d9374 (the pc value) was the RTAS entry point. We dumped out memory at that address and it was all zeroes. Hence the 700 exception. Ben then straced the errinjct program, and it was reading the proc file to get the rmo buffer base and getting back 77c9000. Then it did an mmap of /dev/mem at offset 77d9000 for 4096 bytes, which happens to be the first page of the RTAS private data area. So it looks very much like a bug in errinjct is causing it to overwrite the first page of RTAS's data area. Hence the desire to see the source for errinjct. Paul. From johnrose at us.ibm.com Thu Feb 3 08:56:46 2005 From: johnrose at us.ibm.com (John H Rose) Date: Wed, 2 Feb 2005 15:56:46 -0600 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: <16897.16853.103205.119522@cargo.ozlabs.ibm.com> Message-ID: > When Ben and I dug into it a little using xmon, it turned out that > 77d9374 (the pc value) was the RTAS entry point. We dumped out memory > at that address and it was all zeroes. Hence the 700 exception. Ben > then straced the errinjct program, and it was reading the proc file to > get the rmo buffer base and getting back 77c9000. Then it did an mmap > of /dev/mem at offset 77d9000 for 4096 bytes, which happens to be the > first page of the RTAS private data area. So it looks very much like > a bug in errinjct is causing it to overwrite the first page of RTAS's > data area. Hence the desire to see the source for errinjct. It would appear that librtas isn't enforcing the RMO buffer size communicated by /proc/ppc64/rmobuf. This does sound like (partly) a librtas bug, and I'll have it fixed shortly. Librtas hands out low memory space beginning at the base of the reserved region. This could only occur in the case of a system that had already reserved the 19 pages of low memory without releasing any of them. This seems close to impossible, without some application acting erroneously. Thanks- John From benh at kernel.crashing.org Thu Feb 3 11:23:35 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Thu, 03 Feb 2005 11:23:35 +1100 Subject: pci: Arch hook to determine config space size In-Reply-To: <200502021105.42249.arnd@arndb.de> References: <200501281456.j0SEuI12020454@d01av01.pok.ibm.com> <41FF0B0D.8020003@us.ibm.com> <1107233864.5963.65.camel@gaston> <200502021105.42249.arnd@arndb.de> Message-ID: <1107390215.30709.88.camel@gaston> On Wed, 2005-02-02 at 11:05 +0100, Arnd Bergmann wrote: > How about something along the lines of this patch? Instead of adding a > pointer to the pci data from the device node, it embeds the node inside > a new struct pci_device_node. The patch is not complete and therefore > not expected to work as is, but maybe you want to reuse it. > > The interesting part that is missing is creating and destroying > pci_device_nodes in prom.c, maybe you have an idea how to do that. > > I'm also not sure about eeh. Are the eeh functions known to be called > only for device_nodes of PCI devices? If not, eeh_mode and > eeh_config_addr might have to stay inside of device_node. I'd rather not go that way for now. There are at least PCI and VIO devices concerned by this, and maybe more (depending on how I deal with macio devices for example). We also want, ultimately, to have the DMA routines be function pointers in this auxilliary structure. Ben. From benh at kernel.crashing.org Thu Feb 3 12:17:19 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Thu, 03 Feb 2005 12:17:19 +1100 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: References: Message-ID: <1107393440.1665.89.camel@gaston> On Wed, 2005-02-02 at 15:56 -0600, John H Rose wrote: > It would appear that librtas isn't enforcing the RMO buffer size > communicated by /proc/ppc64/rmobuf. This does sound like (partly) a > librtas bug, and I'll have it fixed shortly. > > Librtas hands out low memory space beginning at the base of the reserved > region. This could only occur in the case of a system that had already > reserved the 19 pages of low memory without releasing any of them. This > seems close to impossible, without some application acting erroneously. I have a 100% reprocase here, booting SLES9 and launching errinjct once. Ben. From benh at kernel.crashing.org Thu Feb 3 12:46:12 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Thu, 03 Feb 2005 12:46:12 +1100 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: <1107365406.32699.7.camel@dyn95394167.austin.ibm.com> References: <20050202011511.GB9140@austin.ibm.com> <1107317868.1665.68.camel@gaston> <1107324674.5625.79.camel@gaston> <1107365406.32699.7.camel@dyn95394167.austin.ibm.com> Message-ID: <1107395173.5625.91.camel@gaston> On Wed, 2005-02-02 at 11:30 -0600, Nathan Fontenot wrote: > On Wed, 2005-02-02 at 17:11 +1100, Benjamin Herrenschmidt wrote: > > Unfortunately, the > > .tar.gz that comes with it on the RAS page doesn't contains what it > > advertises (instead, it contains the source for the rtas error daemon), > > so I can't debug the tool. > > > > Linas, can you fix the source package (and send me the source for > > errinjct) ? > > > > Ben. > > > > Oops. The source tarball on the website should contain the correct > source code now. Nope, the tarball still contains rtas_errd instead of errinjct :) Also, is the source for librtas available somewhere ? Ben. From benh at kernel.crashing.org Thu Feb 3 12:50:07 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Thu, 03 Feb 2005 12:50:07 +1100 Subject: [PATCH] PPC64: draft version of EEH code. In-Reply-To: <1107395173.5625.91.camel@gaston> References: <20050202011511.GB9140@austin.ibm.com> <1107317868.1665.68.camel@gaston> <1107324674.5625.79.camel@gaston> <1107365406.32699.7.camel@dyn95394167.austin.ibm.com> <1107395173.5625.91.camel@gaston> Message-ID: <1107395407.1665.93.camel@gaston> > Nope, the tarball still contains rtas_errd instead of errinjct :) Ooops, forget it, mozilla playing tricks with me. > Also, is the source for librtas available somewhere ? That one still applies :) Ben. From linas at austin.ibm.com Fri Feb 4 11:55:28 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Thu, 3 Feb 2005 18:55:28 -0600 Subject: [PATCH]: Another Revision for EEH Message-ID: <20050204005528.GH9140@austin.ibm.com> Hi Ben, Paul, Not to shower you with endless patches, but another bug report came in today. Appearently, we were not handling the "slot reset state == 5 (permanent failure)" case at all. FWIW, the patches below now handle the case, but I had to restructure the code a fair amount to do this cleanly. Which is fine, because I like the restructured version better anyway. --linas -------------- next part -------------- ===== arch/ppc64/kernel/eeh.c 1.41 vs edited ===== --- 1.41/arch/ppc64/kernel/eeh.c 2005-01-06 13:05:42 -06:00 +++ edited/arch/ppc64/kernel/eeh.c 2005-02-03 18:30:33 -06:00 @@ -17,21 +17,19 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include #include #include -#include #include #include #include #include #include -#include +#include #include #include #include #include -#include #include "pci.h" #undef DEBUG @@ -88,8 +86,7 @@ static struct notifier_block *eeh_notifi * is broken and panic. This sets the threshold for how many read * attempts we allow before panicking. */ -#define EEH_MAX_FAILS 1000 -static atomic_t eeh_fail_count; +#define EEH_MAX_FAILS 100000 /* RTAS tokens */ static int ibm_set_eeh_option; @@ -106,6 +103,10 @@ static spinlock_t slot_errbuf_lock = SPI static int eeh_error_buf_size; /* System monitoring statistics */ +static DEFINE_PER_CPU(unsigned long, no_device); +static DEFINE_PER_CPU(unsigned long, no_dn); +static DEFINE_PER_CPU(unsigned long, no_cfg_addr); +static DEFINE_PER_CPU(unsigned long, ignored_check); static DEFINE_PER_CPU(unsigned long, total_mmio_ffs); static DEFINE_PER_CPU(unsigned long, false_positives); static DEFINE_PER_CPU(unsigned long, ignored_failures); @@ -224,9 +225,9 @@ pci_addr_cache_insert(struct pci_dev *de while (*p) { parent = *p; piar = rb_entry(parent, struct pci_io_addr_range, rb_node); - if (alo < piar->addr_lo) { + if (ahi < piar->addr_lo) { p = &parent->rb_left; - } else if (ahi > piar->addr_hi) { + } else if (alo > piar->addr_hi) { p = &parent->rb_right; } else { if (dev != piar->pcidev || @@ -244,6 +245,11 @@ pci_addr_cache_insert(struct pci_dev *de piar->addr_hi = ahi; piar->pcidev = dev; piar->flags = flags; + +#ifdef DEBUG + printk (KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n", + alo, ahi, pci_name (dev)); +#endif rb_link_node(&piar->rb_node, parent, p); rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root); @@ -368,6 +374,7 @@ void pci_addr_cache_remove_device(struct */ void __init pci_addr_cache_build(void) { + struct device_node *dn; struct pci_dev *dev = NULL; spin_lock_init(&pci_io_addr_cache_root.piar_lock); @@ -378,6 +385,17 @@ void __init pci_addr_cache_build(void) continue; } pci_addr_cache_insert_device(dev); + + /* Save the BAR's; firmware doesn't restore these after EEH reset */ + dn = pci_device_to_OF_node(dev); + if (dn) { + int i; + for (i = 0; i < 16; i++) + pci_read_config_dword(dev, i * 4, &dn->config_space[i]); + + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + dn->eeh_is_bridge = 1; + } } #ifdef DEBUG @@ -389,6 +407,32 @@ void __init pci_addr_cache_build(void) /* --------------------------------------------------------------- */ /* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */ +void eeh_slot_error_detail (struct device_node *dn, int severity) +{ + unsigned long flags; + int rc; + + if (!dn) return; + + /* Log the error with the rtas logger */ + spin_lock_irqsave(&slot_errbuf_lock, flags); + memset(slot_errbuf, 0, eeh_error_buf_size); + + rc = rtas_call(ibm_slot_error_detail, + 8, 1, NULL, dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid), NULL, 0, + virt_to_phys(slot_errbuf), + eeh_error_buf_size, + severity); + + if (rc == 0) + log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0); + spin_unlock_irqrestore(&slot_errbuf_lock, flags); +} + +EXPORT_SYMBOL(eeh_slot_error_detail); + /** * eeh_register_notifier - Register to find out about EEH events. * @nb: notifier block to callback on events @@ -421,10 +465,11 @@ static int read_slot_reset_state(struct outputs = 4; } else { token = ibm_read_slot_reset_state; + rets[2] = 0; /* fake PE Unavailable info */ outputs = 3; } - return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, + return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); } @@ -480,15 +525,15 @@ static void eeh_event_handler(void *dumm if (event == NULL) break; - printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device " - "%s %s\n", event->reset_state, - pci_name(event->dev), pci_pretty_name(event->dev)); - - atomic_set(&eeh_fail_count, 0); - notifier_call_chain (&eeh_notifier_chain, - EEH_NOTIFY_FREEZE, event); + if (event->reset_state != 5) { + printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device " + "%s %s\n", event->reset_state, + pci_name(event->dev), pci_pretty_name(event->dev)); + } __get_cpu_var(slot_resets)++; + notifier_call_chain (&eeh_notifier_chain, + EEH_NOTIFY_FREEZE, event); pci_dev_put(event->dev); kfree(event); @@ -496,8 +541,8 @@ static void eeh_event_handler(void *dumm } /** - * eeh_token_to_phys - convert EEH address token to phys address - * @token i/o token, should be address in the form 0xE.... + * eeh_token_to_phys - convert I/O address to phys address + * @token i/o address, should be address in the form 0xA.... */ static inline unsigned long eeh_token_to_phys(unsigned long token) { @@ -512,6 +557,17 @@ static inline unsigned long eeh_token_to return pa | (token & (PAGE_SIZE-1)); } +static inline struct pci_dev * eeh_get_pci_dev(struct device_node *dn) +{ + struct pci_dev *dev = NULL; + + for_each_pci_dev(dev) { + if (pci_device_to_OF_node(dev) == dn) + return dev; + } + return NULL; +} + /** * eeh_dn_check_failure - check if all 1's data is due to EEH slot freeze * @dn device node @@ -532,7 +588,6 @@ int eeh_dn_check_failure(struct device_n int ret; int rets[3]; unsigned long flags; - int rc, reset_state; struct eeh_event *event; __get_cpu_var(total_mmio_ffs)++; @@ -540,16 +595,20 @@ int eeh_dn_check_failure(struct device_n if (!eeh_subsystem_enabled) return 0; - if (!dn) + if (!dn) { + __get_cpu_var(no_dn)++; return 0; + } /* Access to IO BARs might get this far and still not want checking. */ if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || dn->eeh_mode & EEH_MODE_NOCHECK) { + __get_cpu_var(ignored_check)++; return 0; } if (!dn->eeh_config_addr) { + __get_cpu_var(no_cfg_addr)++; return 0; } @@ -558,8 +617,11 @@ int eeh_dn_check_failure(struct device_n * slot, we know it's bad already, we don't need to check... */ if (dn->eeh_mode & EEH_MODE_ISOLATED) { - atomic_inc(&eeh_fail_count); - if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { + dn->eeh_check_count ++; + if (dn->eeh_check_count >= EEH_MAX_FAILS) { + printk (KERN_ERR "EEH: Driver ignored %d bad reads, panicing\n", + dn->eeh_check_count); + dump_stack(); /* re-read the slot reset state */ if (read_slot_reset_state(dn, rets) != 0) rets[0] = -1; /* reset state unknown */ @@ -576,42 +638,27 @@ int eeh_dn_check_failure(struct device_n * In any case they must share a common PHB. */ ret = read_slot_reset_state(dn, rets); - if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) { + if (!(ret == 0 && ((rets[1] == 1 && (rets[0] == 2 || rets[0] >= 4)) + || (rets[0] == 5)))) { __get_cpu_var(false_positives)++; return 0; } - /* prevent repeated reports of this failure */ + /* Prevent repeated reports of this failure */ dn->eeh_mode |= EEH_MODE_ISOLATED; - reset_state = rets[0]; - - spin_lock_irqsave(&slot_errbuf_lock, flags); - memset(slot_errbuf, 0, eeh_error_buf_size); - - rc = rtas_call(ibm_slot_error_detail, - 8, 1, NULL, dn->eeh_config_addr, - BUID_HI(dn->phb->buid), - BUID_LO(dn->phb->buid), NULL, 0, - virt_to_phys(slot_errbuf), - eeh_error_buf_size, - 1 /* Temporary Error */); - - if (rc == 0) - log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0); - spin_unlock_irqrestore(&slot_errbuf_lock, flags); - - printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n", - rets[0], dn->name, dn->full_name); event = kmalloc(sizeof(*event), GFP_ATOMIC); if (event == NULL) { - eeh_panic(dev, reset_state); + printk (KERN_ERR "EEH: out of memory, event not handled\n"); return 1; } + if (!dev) + dev = eeh_get_pci_dev (dn); event->dev = dev; event->dn = dn; - event->reset_state = reset_state; + event->reset_state = rets[0]; + event->time_unavail = rets[2]; /* We may or may not be called in an interrupt context */ spin_lock_irqsave(&eeh_eventlist_lock, flags); @@ -621,7 +668,7 @@ int eeh_dn_check_failure(struct device_n /* Most EEH events are due to device driver bugs. Having * a stack trace will help the device-driver authors figure * out what happened. So print that out. */ - dump_stack(); + if (rets[0] != 5) dump_stack(); schedule_work(&eeh_event_wq); return 0; @@ -634,7 +681,6 @@ EXPORT_SYMBOL(eeh_dn_check_failure); * @token i/o token, should be address in the form 0xA.... * @val value, should be all 1's (XXX why do we need this arg??) * - * Check for an eeh failure at the given token address. * Check for an EEH failure at the given token address. Call this * routine if the result of a read was all 0xff's and you want to * find out if this is due to an EEH slot freeze event. This routine @@ -642,6 +688,7 @@ EXPORT_SYMBOL(eeh_dn_check_failure); * * Note this routine is safe to call in an interrupt context. */ + unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val) { unsigned long addr; @@ -651,8 +698,10 @@ unsigned long eeh_check_failure(const vo /* Finding the phys addr + pci device; this is pretty quick. */ addr = eeh_token_to_phys((unsigned long __force) token); dev = pci_get_device_by_addr(addr); - if (!dev) + if (!dev) { + __get_cpu_var(no_device)++; return val; + } dn = pci_device_to_OF_node(dev); eeh_dn_check_failure (dn, dev); @@ -663,6 +712,123 @@ unsigned long eeh_check_failure(const vo EXPORT_SYMBOL(eeh_check_failure); +/* ------------------------------------------------------------- */ +/* The code below deals with error recovery */ + +void +rtas_set_slot_reset(struct device_node *dn) +{ + int token = rtas_token ("ibm,set-slot-reset"); + int rc; + + if (token == RTAS_UNKNOWN_SERVICE) + return; + rc = rtas_call(token,4,1, NULL, + dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid), + 1); + if (rc) { + printk (KERN_WARNING "EEH: Unable to reset the failed slot\n"); + return; + } + + /* The PCI bus requires that the reset be held high for at least + * a 100 milliseconds. We wait a bit longer 'just in case'. + */ + msleep (200); + + rc = rtas_call(token,4,1, NULL, + dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid), + 0); +} + +EXPORT_SYMBOL(rtas_set_slot_reset); + +void +rtas_configure_bridge(struct device_node *dn) +{ + int token = rtas_token ("ibm,configure-bridge"); + int rc; + + if (token == RTAS_UNKNOWN_SERVICE) + return; + rc = rtas_call(token,3,1, NULL, + dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid)); + if (rc) { + printk (KERN_WARNING "EEH: Unable to configure device bridge\n"); + } +} + +EXPORT_SYMBOL(rtas_configure_bridge); + +/* ------------------------------------------------------- */ +/** Save and restore of PCI BARs + * + * Although firmware will set up BARs during boot, it doesn't + * set up device BAR's after a device reset, although it will, + * if requested, set up bridge configuration. Thus, we need to + * configure the PCI devices ourselves. Config-space setup is + * stored in the PCI structures which are normally deleted during + * device removal. Thus, the "save" routine references the + * structures so that they aren't deleted. + */ + +/** + * __restore_bars - Restore the Base Address Registers + * Loads the PCI configuration space base address registers, + * the expansion ROM base address, the latency timer, and etc. + * from the saved values in the device node. + */ +static inline void __restore_bars (struct device_node *dn) +{ + int i; + for (i=4; i<10; i++) { + rtas_write_config(dn, i*4, 4, dn->config_space[i]); + } + + /* 12 == Expansion ROM Address */ + rtas_write_config(dn, 12*4, 4, dn->config_space[12]); + +#define SAVED_BYTE(OFF) (((u8 *)(dn->config_space))[OFF]) + + rtas_write_config (dn, PCI_CACHE_LINE_SIZE, 1, + SAVED_BYTE(PCI_CACHE_LINE_SIZE)); + + rtas_write_config (dn, PCI_LATENCY_TIMER, 1, + SAVED_BYTE(PCI_LATENCY_TIMER)); + + rtas_write_config (dn, PCI_INTERRUPT_LINE, 1, + SAVED_BYTE(PCI_INTERRUPT_LINE)); +} + +/** + * eeh_restore_bars - restore the PCI config space info + */ +void eeh_restore_bars(struct device_node *dn) +{ + if (! dn->eeh_is_bridge) + __restore_bars (dn); + + if (dn->child) + eeh_restore_bars (dn->child); + + if (dn->sibling) + eeh_restore_bars (dn->sibling); +} + +EXPORT_SYMBOL(eeh_restore_bars); + +/* ------------------------------------------------------------- */ +/* The code below deals with enabling EEH for devices during the + * early boot sequence. EEH must be enabled before any PCI probing + * can be done. + */ + struct eeh_early_enable_info { unsigned int buid_hi; unsigned int buid_lo; @@ -742,7 +908,7 @@ static void *early_enable_eeh(struct dev dn->full_name); } - return NULL; + return NULL; } /* @@ -829,7 +995,9 @@ void eeh_add_device_early(struct device_ return; phb = dn->phb; if (NULL == phb || 0 == phb->buid) { - printk(KERN_WARNING "EEH: Expected buid but found none\n"); + printk(KERN_WARNING "EEH: Expected buid but found none for %s\n", + dn->full_name); + dump_stack(); return; } @@ -848,6 +1016,9 @@ EXPORT_SYMBOL(eeh_add_device_early); */ void eeh_add_device_late(struct pci_dev *dev) { + int i; + struct device_node *dn; + if (!dev || !eeh_subsystem_enabled) return; @@ -857,6 +1028,14 @@ void eeh_add_device_late(struct pci_dev #endif pci_addr_cache_insert_device (dev); + + /* Save the BAR's; firmware doesn't restore these after EEH reset */ + dn = pci_device_to_OF_node(dev); + for (i = 0; i < 16; i++) + pci_read_config_dword(dev, i * 4, &dn->config_space[i]); + + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + dn->eeh_is_bridge = 1; } EXPORT_SYMBOL(eeh_add_device_late); @@ -886,12 +1065,17 @@ static int proc_eeh_show(struct seq_file unsigned int cpu; unsigned long ffs = 0, positives = 0, failures = 0; unsigned long resets = 0; + unsigned long no_dev = 0, no_dn = 0, no_cfg = 0, no_check = 0; for_each_cpu(cpu) { ffs += per_cpu(total_mmio_ffs, cpu); positives += per_cpu(false_positives, cpu); failures += per_cpu(ignored_failures, cpu); resets += per_cpu(slot_resets, cpu); + no_dev += per_cpu(no_device, cpu); + no_dn += per_cpu(no_dn, cpu); + no_cfg += per_cpu(no_cfg_addr, cpu); + no_check += per_cpu(ignored_check, cpu); } if (0 == eeh_subsystem_enabled) { @@ -899,13 +1083,17 @@ static int proc_eeh_show(struct seq_file seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs); } else { seq_printf(m, "EEH Subsystem is enabled\n"); - seq_printf(m, "eeh_total_mmio_ffs=%ld\n" + seq_printf(m, + "no device=%ld\n" + "no device node=%ld\n" + "no config address=%ld\n" + "check not wanted=%ld\n" + "eeh_total_mmio_ffs=%ld\n" "eeh_false_positives=%ld\n" "eeh_ignored_failures=%ld\n" - "eeh_slot_resets=%ld\n" - "eeh_fail_count=%d\n", - ffs, positives, failures, resets, - eeh_fail_count.counter); + "eeh_slot_resets=%ld\n", + no_dev, no_dn, no_cfg, no_check, + ffs, positives, failures, resets); } return 0; ===== arch/ppc64/kernel/pSeries_pci.c 1.59 vs edited ===== --- 1.59/arch/ppc64/kernel/pSeries_pci.c 2004-11-15 21:29:10 -06:00 +++ edited/arch/ppc64/kernel/pSeries_pci.c 2005-01-20 17:25:37 -06:00 @@ -102,7 +102,7 @@ static int rtas_pci_read_config(struct p return PCIBIOS_DEVICE_NOT_FOUND; } -static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) +int rtas_write_config(struct device_node *dn, int where, int size, u32 val) { unsigned long buid, addr; int ret; ===== include/asm-ppc64/eeh.h 1.23 vs edited ===== --- 1.23/include/asm-ppc64/eeh.h 2004-10-25 18:17:38 -05:00 +++ edited/include/asm-ppc64/eeh.h 2005-02-03 15:05:52 -06:00 @@ -22,8 +22,8 @@ #include #include -#include #include +#include struct pci_dev; struct device_node; @@ -33,6 +33,10 @@ struct device_node; #define EEH_MODE_NOCHECK (1<<1) #define EEH_MODE_ISOLATED (1<<2) +/* Max number of EEH freezes allowed before we consider the device + * to be permanently disabled. */ +#define EEH_MAX_ALLOWED_FREEZES 5 + #ifdef CONFIG_PPC_PSERIES extern void __init eeh_init(void); unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val); @@ -57,6 +61,34 @@ void eeh_add_device_early(struct device_ void eeh_add_device_late(struct pci_dev *); /** + * eeh_slot_error_detail -- record and EEH error condition to the log + * @severity: 1 if temporary, 2 if permanent failure. + * + * Obtains the the EEH error details from the RTAS subsystem, + * and then logs these details with the RTAS error log system. + */ +void eeh_slot_error_detail (struct device_node *dn, int severity); + +/** + * rtas_set_slot_reset -- unfreeze a frozen slot + * + * Clear the EEH-frozen condition on a slot. This routine + * does this by asserting the PCI #RST line for 1/8th of + * a second; this routine will sleep while the adapter is + * being reset. + */ +void rtas_set_slot_reset (struct device_node *dn); + +/** + * rtas_configure_bridge -- firmware initialization of pci bridge + * + * Ask the firmware to configure any PCI bridge devices + * located behind the indicated node. Required after a + * pci device reset. + */ +void rtas_configure_bridge(struct device_node *dn); + +/** * eeh_remove_device - undo EEH setup for the indicated pci device * @dev: pci device to be removed * @@ -86,11 +118,16 @@ struct eeh_event { struct pci_dev *dev; struct device_node *dn; int reset_state; + int time_unavail; }; /** Register to find out about EEH events. */ int eeh_register_notifier(struct notifier_block *nb); int eeh_unregister_notifier(struct notifier_block *nb); + +/** Restore device configuration info across device resets. + */ +void eeh_restore_bars(struct device_node *); /** * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. ===== include/asm-ppc64/prom.h 1.24 vs edited ===== --- 1.24/include/asm-ppc64/prom.h 2004-11-25 00:42:42 -06:00 +++ edited/include/asm-ppc64/prom.h 2005-01-31 18:01:01 -06:00 @@ -164,8 +164,12 @@ struct device_node { int status; /* Current device status (non-zero is bad) */ int eeh_mode; /* See eeh.h for possible EEH_MODEs */ int eeh_config_addr; + int eeh_check_count; /* number of times device driver ignored error */ + int eeh_freeze_count; /* number of times this device froze up. */ + int eeh_is_bridge; /* device is pci-to-pci bridge */ struct pci_controller *phb; /* for pci devices */ struct iommu_table *iommu_table; /* for phb's or bridges */ + u32 config_space[16]; /* saved PCI config space */ struct property *properties; struct device_node *parent; ===== include/asm-ppc64/rtas.h 1.25 vs edited ===== --- 1.25/include/asm-ppc64/rtas.h 2004-11-25 00:42:42 -06:00 +++ edited/include/asm-ppc64/rtas.h 2005-01-20 17:25:37 -06:00 @@ -241,4 +241,6 @@ extern void rtas_stop_self(void); /* RMO buffer reserved for user-space RTAS use */ extern unsigned long rtas_rmo_buf; +extern int rtas_write_config(struct device_node *dn, int where, int size, u32 val); + #endif /* _PPC64_RTAS_H */ -------------- next part -------------- ===== drivers/pci/hotplug/rpaphp.h 1.11 vs edited ===== --- 1.11/drivers/pci/hotplug/rpaphp.h 2004-10-06 11:43:44 -05:00 +++ edited/drivers/pci/hotplug/rpaphp.h 2005-01-20 17:25:37 -06:00 @@ -125,7 +125,8 @@ extern int rpaphp_enable_pci_slot(struct extern int register_pci_slot(struct slot *slot); extern int rpaphp_unconfig_pci_adapter(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev); +extern void init_eeh_handler (void); +extern void exit_eeh_handler (void); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); ===== drivers/pci/hotplug/rpaphp_core.c 1.18 vs edited ===== --- 1.18/drivers/pci/hotplug/rpaphp_core.c 2004-10-06 11:43:44 -05:00 +++ edited/drivers/pci/hotplug/rpaphp_core.c 2005-01-20 17:25:37 -06:00 @@ -443,12 +443,18 @@ static int __init rpaphp_init(void) { info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + /* Get set to handle EEH events. */ + init_eeh_handler(); + /* read all the PRA info from the system */ return init_rpa(); } static void __exit rpaphp_exit(void) { + /* Let EEH know we are going away. */ + exit_eeh_handler(); + cleanup_slots(); } ===== drivers/pci/hotplug/rpaphp_pci.c 1.17 vs edited ===== --- 1.17/drivers/pci/hotplug/rpaphp_pci.c 2004-11-18 02:36:18 -06:00 +++ edited/drivers/pci/hotplug/rpaphp_pci.c 2005-02-03 18:40:27 -06:00 @@ -22,8 +22,12 @@ * Send feedback to * */ +#include +#include #include +#include #include +#include #include #include "../pci.h" /* for pci_add_new_bus */ @@ -62,6 +66,7 @@ int rpaphp_claim_resource(struct pci_dev root ? "Address space collision on" : "No parent found for", resource, dtype, pci_name(dev), res->start, res->end); + dump_stack(); } return err; } @@ -184,6 +189,19 @@ rpaphp_fixup_new_pci_devices(struct pci_ static int rpaphp_pci_config_bridge(struct pci_dev *dev); +static void rpaphp_eeh_add_bus_device(struct pci_bus *bus) +{ + struct pci_dev *dev; + list_for_each_entry(dev, &bus->devices, bus_list) { + eeh_add_device_late(dev); + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + struct pci_bus *subbus = dev->subordinate; + if (bus) + rpaphp_eeh_add_bus_device (subbus); + } + } +} + /***************************************************************************** rpaphp_pci_config_slot() will configure all devices under the given slot->dn and return the the first pci_dev. @@ -211,6 +229,8 @@ rpaphp_pci_config_slot(struct device_nod } if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) rpaphp_pci_config_bridge(dev); + + rpaphp_eeh_add_bus_device(bus); } return dev; } @@ -219,7 +239,6 @@ static int rpaphp_pci_config_bridge(stru { u8 sec_busno; struct pci_bus *child_bus; - struct pci_dev *child_dev; dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); @@ -236,11 +255,7 @@ static int rpaphp_pci_config_bridge(stru /* do pci_scan_child_bus */ pci_scan_child_bus(child_bus); - list_for_each_entry(child_dev, &child_bus->devices, bus_list) { - eeh_add_device_late(child_dev); - } - - /* fixup new pci devices without touching bus struct */ + /* Fixup new pci devices without touching bus struct */ rpaphp_fixup_new_pci_devices(child_bus, 0); /* Make the discovered devices available */ @@ -278,7 +293,7 @@ static void print_slot_pci_funcs(struct return; } #else -static void print_slot_pci_funcs(struct slot *slot) +static inline void print_slot_pci_funcs(struct slot *slot) { return; } @@ -360,7 +375,6 @@ static void rpaphp_eeh_remove_bus_device if (pdev) rpaphp_eeh_remove_bus_device(pdev); } - } return; } @@ -562,36 +576,229 @@ exit: return retval; } -struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev) +/** + * rpaphp_search_bus_for_dev - return 1 if device is under this bus, else 0 + * @bus: the bus to search for this device. + * @dev: the pci device we are looking for. + */ +static int rpaphp_search_bus_for_dev (struct pci_bus *bus, struct pci_dev *dev) +{ + struct list_head *ln; + + if (!bus) return 0; + + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *pdev = pci_dev_b(ln); + if (pdev == dev) + return 1; + if (pdev->subordinate) { + int rc; + rc = rpaphp_search_bus_for_dev (pdev->subordinate, dev); + if (rc) + return 1; + } + } + return 0; +} + +/** + * rpaphp_find_slot - find and return the slot holding the device + * @dev: pci device for which we want the slot structure. + */ +static struct slot *rpaphp_find_slot(struct pci_dev *dev) { - struct list_head *tmp, *n; - struct slot *slot; + struct list_head *tmp, *n; + struct slot *slot; list_for_each_safe(tmp, n, &rpaphp_slot_head) { struct pci_bus *bus; - struct list_head *ln; slot = list_entry(tmp, struct slot, rpaphp_slot_list); - if (slot->bridge == NULL) { - if (slot->dev_type == PCI_DEV) { - printk(KERN_WARNING "PCI slot missing bridge %s %s \n", - slot->name, slot->location); - } + + /* PHB's don't have bridges. */ + if (slot->bridge == NULL) continue; - } + + /* The PCI device could be the slot itself. */ + if (slot->bridge == dev) + return slot; bus = slot->bridge->subordinate; if (!bus) { + printk (KERN_WARNING "PCI bridge is missing bus: %s %s\n", + pci_name (slot->bridge), pci_pretty_name (slot->bridge)); continue; /* should never happen? */ } - for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { - struct pci_dev *pdev = pci_dev_b(ln); - if (pdev == dev) - return slot->hotplug_slot; - } - } + if (rpaphp_search_bus_for_dev (bus, dev)) + return slot; + } return NULL; } -EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot); +/* ------------------------------------------------------- */ +/** + * handle_eeh_events -- reset a PCI device after hard lockup. + * + * pSeries systems will isolate a PCI slot if the PCI-Host + * bridge detects address or data parity errors, DMA's + * occuring to wild addresses (which usually happen due to + * bugs in device drivers or in PCI adapter firmware). + * Slot isolations also occur if #SERR, #PERR or other misc + * PCI-related errors are detected. + * + * Recovery process consists of unplugging the device driver + * (which generated hotplug events to userspace), then issuing + * a PCI #RST to the device, then reconfiguring the PCI config + * space for all bridges & devices under this slot, and then + * finally restarting the device drivers (which cause a second + * set of hotplug events to go out to userspace). + */ +int eeh_reset_device (struct pci_dev *dev, int reconfig) +{ + int freeze_count=0; + struct slot *frozen_slot; + + if (!dev) + return 1; + + frozen_slot = rpaphp_find_slot(dev); + if (!frozen_slot) + { + printk (KERN_ERR "EEH: Cannot find PCI slot for %s %s\n", + pci_name(dev), pci_pretty_name (dev)); + return 1; + } + + if (reconfig) rpaphp_unconfig_pci_adapter (frozen_slot); + + /* Reset the pci controller. (Asserts RST#; resets config space). + * Reconfigure bridges and devices */ + rtas_set_slot_reset (frozen_slot->dn->child); + + rtas_configure_bridge(frozen_slot->dn); + eeh_restore_bars(frozen_slot->dn->child); + + /* Give the system 5 seconds to finish running the user-space + * hotplug scripts, e.g. ifdown for ethernet. Yes, this is a hack, + * but if we don't do this, weird things happen. + */ + if (reconfig) { + ssleep (5); + rpaphp_enable_pci_slot (frozen_slot); + } + return 0; +} + +/* The longest amount of time to wait for a pci device + * to come back on line, in seconds. + */ +#define MAX_WAIT_FOR_RECOVERY 15 + +int handle_eeh_events (struct notifier_block *self, + unsigned long reason, void *ev) +{ + int freeze_count=0; + struct slot *frozen_slot; + struct eeh_event *event = ev; + struct pci_dev *dev = event->dev; + int perm_failure = 0; + int rc; + + if (!dev) + { + if (event->dn) + printk ("EEH: Cannot find the PCI device for dn %s\n", + event->dn->full_name); + else + printk ("EEH: EEH error caught, but no PCI device specified!\n"); + return 1; + } + + frozen_slot = rpaphp_find_slot(dev); + if (!frozen_slot) + { + printk (KERN_ERR "EEH: Cannot find PCI slot for %s %s\n", + pci_name(dev), pci_pretty_name (dev)); + return 1; + } + + /* We get "permanent failure" messages on empty slots. + * These are false alarms. Empty slots have no child dn. */ + if ((event->reset_state == 5) && (frozen_slot->dn->child == NULL)) + return 0; + + if (frozen_slot->dn->child) + freeze_count = frozen_slot->dn->child->eeh_freeze_count; + freeze_count ++; + if (freeze_count > EEH_MAX_ALLOWED_FREEZES) + perm_failure = 1; + + /* If the reset state is a '5' and the time to reset is 0 (infinity) + * or is more then 15 seconds, then mark this as a permanent failure. + */ + if ((event->reset_state == 5) && + ((event->time_unavail <= 0) || + (event->time_unavail > MAX_WAIT_FOR_RECOVERY*1000))) + perm_failure = 1; + + /* Log the error with the rtas logger. */ + if (perm_failure) { + /* + * About 90% of all real-life EEH failures in the field + * are due to poorly seated PCI cards. Only 10% or so are + * due to actual, failed cards. + */ + printk (KERN_ERR + "EEH: device %s:%s has failed %d times \n" + "and has been permanently disabled. Please try reseating\n" + "this device or replacing it.\n", + pci_name (dev), + pci_pretty_name (dev), + freeze_count); + + eeh_slot_error_detail (frozen_slot->dn->child, 2 /* Permanent Error */); + + /* Unconfigure the thing and go home. */ + rpaphp_unconfig_pci_adapter (frozen_slot); + return 1; + } else { + eeh_slot_error_detail (frozen_slot->dn->child, 1 /* Temporary Error */); + } + + printk (KERN_WARNING + "EEH: This device has failed %d times since last reboot: %s:%s\n", + freeze_count, + pci_name (dev), + pci_pretty_name (dev)); + + /* OK, firmware told us to wait. So wait */ + if (event->reset_state == 5) + msleep (event->time_unavail); + +if(strncmp (pci_pretty_name (event->dev), "Mylex Corporation Gemstone", 25)) { + rc = eeh_reset_device (event->dev, 1); +} + + /* Store the freeze count with the pci adapter, and not the slot. + * This way, if the device is replaced, the count is cleared. + */ + if (frozen_slot->dn->child) + frozen_slot->dn->child->eeh_freeze_count = freeze_count; + + return rc; +} + +static struct notifier_block eeh_block; + +void __init init_eeh_handler (void) +{ + eeh_block.notifier_call = handle_eeh_events; + eeh_register_notifier (&eeh_block); +} + +void __exit exit_eeh_handler (void) +{ + eeh_unregister_notifier (&eeh_block); +} + From akpm at osdl.org Fri Feb 4 16:32:05 2005 From: akpm at osdl.org (Andrew Morton) Date: Thu, 3 Feb 2005 21:32:05 -0800 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline #2 In-Reply-To: <1107222584.5906.43.camel@gaston> References: <1107222584.5906.43.camel@gaston> Message-ID: <20050203213205.58b5907d.akpm@osdl.org> Benjamin Herrenschmidt wrote: > > This patch adds to the ppc64 kernel a virtual .so (vDSO) that is mapped into every > process space, similar to the x86 vsyscall page. erp. Do I need a toolchain upgrade? arch/ppc64/kernel/vdso32/gettimeofday.S: Assembler messages: arch/ppc64/kernel/vdso32/gettimeofday.S:27: Error: unknown pseudo-op: `.cfi_startproc' arch/ppc64/kernel/vdso32/gettimeofday.S:29: Error: unknown pseudo-op: `.cfi_register' arch/ppc64/kernel/vdso32/gettimeofday.S:68: Error: unknown pseudo-op: `.cfi_endproc' arch/ppc64/kernel/vdso32/gettimeofday.S:77: Error: unknown pseudo-op: `.cfi_startproc' arch/ppc64/kernel/vdso32/gettimeofday.S:139: Error: unknown pseudo-op: `.cfi_endproc' arch/ppc64/kernel/vdso64/gettimeofday.S: Assembler messages: arch/ppc64/kernel/vdso64/gettimeofday.S:27: Error: unknown pseudo-op: `.cfi_startproc' arch/ppc64/kernel/vdso64/gettimeofday.S:29: Error: unknown pseudo-op: `.cfi_register' arch/ppc64/kernel/vdso64/gettimeofday.S:53: Error: unknown pseudo-op: `.cfi_endproc' From amodra at bigpond.net.au Fri Feb 4 16:43:04 2005 From: amodra at bigpond.net.au (Alan Modra) Date: Fri, 4 Feb 2005 16:13:04 +1030 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline #2 In-Reply-To: <20050203213205.58b5907d.akpm@osdl.org> References: <1107222584.5906.43.camel@gaston> <20050203213205.58b5907d.akpm@osdl.org> Message-ID: <20050204054304.GL24757@bubble.modra.org> On Thu, Feb 03, 2005 at 09:32:05PM -0800, Andrew Morton wrote: > erp. Do I need a toolchain upgrade? Definitely. If your assembler doesn't understand .cfi_startproc it's so old it's mouldy. > arch/ppc64/kernel/vdso32/gettimeofday.S: Assembler messages: > arch/ppc64/kernel/vdso32/gettimeofday.S:27: Error: unknown pseudo-op: `.cfi_startproc' -- Alan Modra IBM OzLabs - Linux Technology Centre From ahuja at austin.ibm.com Fri Feb 4 17:06:12 2005 From: ahuja at austin.ibm.com (Manish Ahuja) Date: Fri, 04 Feb 2005 00:06:12 -0600 Subject: Collect real process and processor utilization values when virtualization is enabled. In-Reply-To: <16868.36168.772082.315933@cargo.ozlabs.ibm.com> References: <41E4787D.90309@austin.ibm.com> <16868.36168.772082.315933@cargo.ozlabs.ibm.com> Message-ID: <420310D4.4000400@austin.ibm.com> Cleaned up version .... Renamed variables... etc ----------------------- There is a requirement to collect real usage values of each partition in LPAR environment on pseries as well as iseries. This patch enables that feature. The current purr (processor Utilization register ) values of each of the processors is stored in a per_cpu data array. this is then summed and used to calculate various numbers for managing lpars. The patch also calculates how much real cpu time each process uses and stores this value in a ppc64 specific struct. The value is needed by CKRM to do further calculations. Signed-off-by: Manish Ahuja -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: patch4.txt Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050204/d0313236/attachment.txt From nathanl at austin.ibm.com Fri Feb 4 17:50:33 2005 From: nathanl at austin.ibm.com (Nathan Lynch) Date: Fri, 04 Feb 2005 00:50:33 -0600 Subject: [PATCH] make cpu hotplug play well with maxcpus and smt-enabled parameters Message-ID: <1107499833.7882.2.camel@biclops> This patch allows you to boot a pSeries system with maxcpus=x or smt-enabled=off (or both) and bring up the offline cpus later from userspace, assuming the kernel was built with CONFIG_HOTPLUG_CPU=y. - Record cpus which were started from OF in a cpu map and use that instead of system_state to decide how to start a cpu in smp_startup_cpu. - Change the smp bootup logic slightly so that the path for bringing up secondary threads is exactly the same as hotplugging a cpu later from userspace. - Add a new function to smp_ops - cpu_bootable. This is implemented only by pSeries to filter out secondary threads during boot with smt-enabled=off. Another way this could be done is to change the kick_cpu member to return int and we can check for this case in smp_pSeries_kick_cpu. - Remove the games we play with cpu_present_map and the hard_smp_processor_id to handle smt-enabled=off, since they're now unnecessary. - Remove find_physical_cpu_to_start; assigning threads to logical slots should be done at bootup and at DLPAR time, not during a cpu online operation. A couple of caveats: - You need up-to-date firmware on Power5 for the maxcpus option to work on systems with more than one cpu device node. Otherwise interrupts get misrouted, typically resulting in hangs or "unable to find root filesystem" problems. - This breaks cpu DLPAR in the sense that we need code such as what I posted last week to handle the addition of new cpu device nodes and update the paca and cpu_present_map. Tested on Power5 with and without CONFIG_HOTPLUG_CPU and with various combinations of the maxcpus= and smt-enabled= parameters. arch/ppc64/kernel/pSeries_smp.c | 131 +++++++++++--------------------- arch/ppc64/kernel/setup.c | 12 -- arch/ppc64/kernel/smp.c | 13 --- include/asm-ppc64/machdep.h | 1 4 files changed, 52 insertions(+), 105 deletions(-) Signed-off-by: Nathan Lynch Index: linux-2.6.11-rc3/arch/ppc64/kernel/pSeries_smp.c =================================================================== --- linux-2.6.11-rc3.orig/arch/ppc64/kernel/pSeries_smp.c 2005-02-04 00:40:22.097318813 -0600 +++ linux-2.6.11-rc3/arch/ppc64/kernel/pSeries_smp.c 2005-02-04 00:40:30.743338605 -0600 @@ -53,8 +53,16 @@ #define DBG(fmt...) #endif +/* + * The primary thread of each non-boot processor is recorded here before + * smp init. + */ +static cpumask_t of_spin_map; + extern void pSeries_secondary_smp_init(unsigned long); +#ifdef CONFIG_HOTPLUG_CPU + /* Get state of physical CPU. * Return codes: * 0 - The processor is in the RTAS stopped state @@ -81,9 +89,6 @@ static int query_cpu_stopped(unsigned in return cpu_status; } - -#ifdef CONFIG_HOTPLUG_CPU - int pSeries_cpu_disable(void) { systemcfg->processorCount--; @@ -121,61 +126,14 @@ void pSeries_cpu_die(unsigned int cpu) */ paca[cpu].cpu_start = 0; } - -/* Search all cpu device nodes for an offline logical cpu. If a - * device node has a "ibm,my-drc-index" property (meaning this is an - * LPAR), paranoid-check whether we own the cpu. For each "thread" - * of a cpu, if it is offline and has the same hw index as before, - * grab that in preference. - */ -static unsigned int find_physical_cpu_to_start(unsigned int old_hwindex) -{ - struct device_node *np = NULL; - unsigned int best = -1U; - - while ((np = of_find_node_by_type(np, "cpu"))) { - int nr_threads, len; - u32 *index = (u32 *)get_property(np, "ibm,my-drc-index", NULL); - u32 *tid = (u32 *) - get_property(np, "ibm,ppc-interrupt-server#s", &len); - - if (!tid) - tid = (u32 *)get_property(np, "reg", &len); - - if (!tid) - continue; - - /* If there is a drc-index, make sure that we own - * the cpu. - */ - if (index) { - int state; - int rc = rtas_get_sensor(9003, *index, &state); - if (rc != 0 || state != 1) - continue; - } - - nr_threads = len / sizeof(u32); - - while (nr_threads--) { - if (0 == query_cpu_stopped(tid[nr_threads])) { - best = tid[nr_threads]; - if (best == old_hwindex) - goto out; - } - } - } -out: - of_node_put(np); - return best; -} +#endif /* CONFIG_HOTPLUG_CPU */ /** * smp_startup_cpu() - start the given cpu * - * At boot time, there is nothing to do. At run-time, call RTAS with - * the appropriate start location, if the cpu is in the RTAS stopped - * state. + * At boot time, there is nothing to do for primary threads which were + * started from Open Firmware. For anything else, call RTAS with the + * appropriate start location. * * Returns: * 0 - failure @@ -188,23 +146,15 @@ static inline int __devinit smp_startup_ pSeries_secondary_smp_init)); unsigned int pcpu; - /* At boot time the cpus are already spinning in hold - * loops, so nothing to do. */ - if (system_state < SYSTEM_RUNNING) + if (cpu_isset(lcpu, of_spin_map)) + /* Already started by OF and sitting in spin loop */ return 1; - pcpu = find_physical_cpu_to_start(get_hard_smp_processor_id(lcpu)); - if (pcpu == -1U) { - printk(KERN_INFO "No more cpus available, failing\n"); - return 0; - } + pcpu = get_hard_smp_processor_id(lcpu); /* Fixup atomic count: it exited inside IRQ handler. */ paca[lcpu].__current->thread_info->preempt_count = 0; - /* At boot this is done in prom.c. */ - paca[lcpu].hw_cpu_id = pcpu; - status = rtas_call(rtas_token("start-cpu"), 3, 1, NULL, pcpu, start_here, lcpu); if (status != 0) { @@ -213,12 +163,6 @@ static inline int __devinit smp_startup_ } return 1; } -#else /* ... CONFIG_HOTPLUG_CPU */ -static inline int __devinit smp_startup_cpu(unsigned int lcpu) -{ - return 1; -} -#endif /* CONFIG_HOTPLUG_CPU */ static inline void smp_xics_do_message(int cpu, int msg) { @@ -258,6 +202,8 @@ static void __devinit smp_xics_setup_cpu if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) vpa_init(cpu); + cpu_clear(cpu, of_spin_map); + /* * Put the calling processor into the GIQ. This is really only * necessary from a secondary thread as the OF start-cpu interface @@ -307,6 +253,20 @@ static void __devinit smp_pSeries_kick_c paca[nr].cpu_start = 1; } +static int smp_pSeries_cpu_bootable(unsigned int nr) +{ + /* Special case - we inhibit secondary thread startup + * during boot if the user requests it. Odd-numbered + * cpus are assumed to be secondary threads. + */ + if (system_state < SYSTEM_RUNNING && + cur_cpu_spec->cpu_features & CPU_FTR_SMT && + !smt_enabled_at_boot && nr % 2 != 0) + return 0; + + return 1; +} + static struct smp_ops_t pSeries_mpic_smp_ops = { .message_pass = smp_mpic_message_pass, .probe = smp_mpic_probe, @@ -319,12 +279,13 @@ static struct smp_ops_t pSeries_xics_smp .probe = smp_xics_probe, .kick_cpu = smp_pSeries_kick_cpu, .setup_cpu = smp_xics_setup_cpu, + .cpu_bootable = smp_pSeries_cpu_bootable, }; /* This is called very early */ void __init smp_init_pSeries(void) { - int ret, i; + int i; DBG(" -> smp_init_pSeries()\n"); @@ -338,20 +299,20 @@ void __init smp_init_pSeries(void) smp_ops->cpu_die = pSeries_cpu_die; #endif - /* Start secondary threads on SMT systems; primary threads - * are already in the running state. - */ - for_each_present_cpu(i) { - if (query_cpu_stopped(get_hard_smp_processor_id(i)) == 0) { - printk("%16.16x : starting thread\n", i); - DBG("%16.16x : starting thread\n", i); - rtas_call(rtas_token("start-cpu"), 3, 1, &ret, - get_hard_smp_processor_id(i), - __pa((u32)*((unsigned long *) - pSeries_secondary_smp_init)), - i); + /* Mark threads which are still spinning in hold loops. */ + if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + for_each_present_cpu(i) { + if (i % 2 == 0) + /* + * Even-numbered logical cpus correspond to + * primary threads. + */ + cpu_set(i, of_spin_map); } - } + else + of_spin_map = cpu_present_map; + + cpu_clear(boot_cpuid, of_spin_map); /* Non-lpar has additional take/give timebase */ if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { Index: linux-2.6.11-rc3/include/asm-ppc64/machdep.h =================================================================== --- linux-2.6.11-rc3.orig/include/asm-ppc64/machdep.h 2005-02-04 00:40:22.097318813 -0600 +++ linux-2.6.11-rc3/include/asm-ppc64/machdep.h 2005-02-04 00:40:30.744334576 -0600 @@ -32,6 +32,7 @@ struct smp_ops_t { void (*give_timebase)(void); int (*cpu_disable)(void); void (*cpu_die)(unsigned int nr); + int (*cpu_bootable)(unsigned int nr); }; #endif Index: linux-2.6.11-rc3/arch/ppc64/kernel/smp.c =================================================================== --- linux-2.6.11-rc3.orig/arch/ppc64/kernel/smp.c 2005-02-04 00:40:22.097318813 -0600 +++ linux-2.6.11-rc3/arch/ppc64/kernel/smp.c 2005-02-04 00:40:30.744334576 -0600 @@ -410,9 +410,8 @@ int __devinit __cpu_up(unsigned int cpu) { int c; - /* At boot, don't bother with non-present cpus -JSCHOPP */ - if (system_state < SYSTEM_RUNNING && !cpu_present(cpu)) - return -ENOENT; + if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) + return -EINVAL; paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; @@ -526,14 +525,6 @@ void __init smp_cpus_done(unsigned int m smp_ops->setup_cpu(boot_cpuid); set_cpus_allowed(current, old_mask); - - /* - * We know at boot the maximum number of cpus we can add to - * a partition and set cpu_possible_map accordingly. cpu_present_map - * needs to match for the hotplug code to allow us to hot add - * any offline cpus. - */ - cpu_present_map = cpu_possible_map; } #ifdef CONFIG_HOTPLUG_CPU Index: linux-2.6.11-rc3/arch/ppc64/kernel/setup.c =================================================================== --- linux-2.6.11-rc3.orig/arch/ppc64/kernel/setup.c 2005-02-04 00:40:22.097318813 -0600 +++ linux-2.6.11-rc3/arch/ppc64/kernel/setup.c 2005-02-04 00:40:30.745330546 -0600 @@ -268,15 +268,9 @@ static void __init setup_cpu_maps(void) nthreads = len / sizeof(u32); for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { - /* - * Only spin up secondary threads if SMT is enabled. - * We must leave space in the logical map for the - * threads. - */ - if (j == 0 || smt_enabled_at_boot) { - cpu_set(cpu, cpu_present_map); - set_hard_smp_processor_id(cpu, intserv[j]); - } + cpu_set(cpu, cpu_present_map); + set_hard_smp_processor_id(cpu, intserv[j]); + if (intserv[j] == boot_cpuid_phys) swap_cpuid = cpu; cpu_set(cpu, cpu_possible_map); From olof at austin.ibm.com Fri Feb 4 18:22:54 2005 From: olof at austin.ibm.com (Olof Johansson) Date: Fri, 4 Feb 2005 01:22:54 -0600 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro Message-ID: <20050204072254.GA17565@austin.ibm.com> Hi, It's getting pretty old to have see and type cur_cpu_spec->cpu_features & CPU_FTR_, when a shorter and less TLA-ridden macro is more readable. This also takes care of the differences between PPC and PPC64 cpu features for the common code; most places in PPC could be replaced with the macro as well. Signed-off-by: Olof Johansson --- linux-2.5-olof/arch/ppc/kernel/ppc_htab.c | 8 +++--- linux-2.5-olof/arch/ppc/kernel/setup.c | 4 +-- linux-2.5-olof/arch/ppc/kernel/temp.c | 2 - linux-2.5-olof/arch/ppc/mm/mmu_decl.h | 2 - linux-2.5-olof/arch/ppc/mm/ppc_mmu.c | 4 +-- linux-2.5-olof/arch/ppc/platforms/pmac_cpufreq.c | 2 - linux-2.5-olof/arch/ppc/platforms/pmac_setup.c | 2 - linux-2.5-olof/arch/ppc/platforms/pmac_smp.c | 4 +-- linux-2.5-olof/arch/ppc/platforms/sandpoint.c | 6 ++--- linux-2.5-olof/arch/ppc64/kernel/align.c | 2 - linux-2.5-olof/arch/ppc64/kernel/iSeries_setup.c | 2 - linux-2.5-olof/arch/ppc64/kernel/pSeries_lpar.c | 2 - linux-2.5-olof/arch/ppc64/kernel/process.c | 4 +-- linux-2.5-olof/arch/ppc64/kernel/setup.c | 6 ++--- linux-2.5-olof/arch/ppc64/kernel/smp.c | 2 - linux-2.5-olof/arch/ppc64/kernel/sysfs.c | 22 +++++++++---------- linux-2.5-olof/arch/ppc64/mm/hash_native.c | 14 ++++++------ linux-2.5-olof/arch/ppc64/mm/hash_utils.c | 2 - linux-2.5-olof/arch/ppc64/mm/hugetlbpage.c | 2 - linux-2.5-olof/arch/ppc64/mm/init.c | 10 ++++---- linux-2.5-olof/arch/ppc64/mm/slb.c | 4 +-- linux-2.5-olof/arch/ppc64/mm/stab.c | 2 - linux-2.5-olof/arch/ppc64/oprofile/op_model_power4.c | 2 - linux-2.5-olof/arch/ppc64/oprofile/op_model_rs64.c | 2 - linux-2.5-olof/arch/ppc64/xmon/xmon.c | 8 +++--- linux-2.5-olof/drivers/macintosh/via-pmu.c | 2 - linux-2.5-olof/drivers/md/raid6altivec.uc | 2 - linux-2.5-olof/include/asm-ppc/cputable.h | 2 + linux-2.5-olof/include/asm-ppc64/cacheflush.h | 2 - linux-2.5-olof/include/asm-ppc64/cputable.h | 2 + linux-2.5-olof/include/asm-ppc64/mmu_context.h | 4 +-- linux-2.5-olof/include/asm-ppc64/page.h | 2 - 32 files changed, 70 insertions(+), 66 deletions(-) diff -puN include/asm-ppc64/cputable.h~cpu-has-feature include/asm-ppc64/cputable.h --- linux-2.5/include/asm-ppc64/cputable.h~cpu-has-feature 2005-02-04 00:33:25.000000000 -0600 +++ linux-2.5-olof/include/asm-ppc64/cputable.h 2005-02-04 00:33:26.000000000 -0600 @@ -66,6 +66,8 @@ struct cpu_spec { extern struct cpu_spec cpu_specs[]; extern struct cpu_spec *cur_cpu_spec; +#define CPU_HAS_FEATURE(x) (cur_cpu_spec->cpu_features & CPU_FTR_##x) + /* firmware feature bitmask values */ #define FIRMWARE_MAX_FEATURES 63 diff -puN arch/ppc64/kernel/align.c~cpu-has-feature arch/ppc64/kernel/align.c --- linux-2.5/arch/ppc64/kernel/align.c~cpu-has-feature 2005-02-04 00:33:25.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/align.c 2005-02-04 00:33:26.000000000 -0600 @@ -238,7 +238,7 @@ fix_alignment(struct pt_regs *regs) dsisr = regs->dsisr; - if (cur_cpu_spec->cpu_features & CPU_FTR_NODSISRALIGN) { + if (CPU_HAS_FEATURE(NODSISRALIGN)) { unsigned int real_instr; if (__get_user(real_instr, (unsigned int __user *)regs->nip)) return 0; diff -puN arch/ppc64/kernel/iSeries_setup.c~cpu-has-feature arch/ppc64/kernel/iSeries_setup.c --- linux-2.5/arch/ppc64/kernel/iSeries_setup.c~cpu-has-feature 2005-02-04 00:33:25.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/iSeries_setup.c 2005-02-04 00:33:26.000000000 -0600 @@ -267,7 +267,7 @@ unsigned long iSeries_process_mainstore_ unsigned long i; unsigned long mem_blocks = 0; - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (CPU_HAS_FEATURE(SLB)) mem_blocks = iSeries_process_Regatta_mainstore_vpd(mb_array, max_entries); else diff -puN arch/ppc64/kernel/idle.c~cpu-has-feature arch/ppc64/kernel/idle.c diff -puN arch/ppc64/kernel/process.c~cpu-has-feature arch/ppc64/kernel/process.c --- linux-2.5/arch/ppc64/kernel/process.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/process.c 2005-02-04 00:33:26.000000000 -0600 @@ -388,12 +388,12 @@ copy_thread(int nr, unsigned long clone_ kregs = (struct pt_regs *) sp; sp -= STACK_FRAME_OVERHEAD; p->thread.ksp = sp; - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { + if (CPU_HAS_FEATURE(SLB)) { unsigned long sp_vsid = get_kernel_vsid(sp); sp_vsid <<= SLB_VSID_SHIFT; sp_vsid |= SLB_VSID_KERNEL; - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (CPU_HAS_FEATURE(16M_PAGE)) sp_vsid |= SLB_VSID_L; p->thread.ksp_vsid = sp_vsid; diff -puN arch/ppc64/kernel/smp.c~cpu-has-feature arch/ppc64/kernel/smp.c --- linux-2.5/arch/ppc64/kernel/smp.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/smp.c 2005-02-04 00:33:26.000000000 -0600 @@ -416,7 +416,7 @@ int __devinit __cpu_up(unsigned int cpu) paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; - if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) { + if (!CPU_HAS_FEATURE(SLB)) { void *tmp; /* maximum of 48 CPUs on machines with a segment table */ diff -puN arch/ppc64/kernel/sysfs.c~cpu-has-feature arch/ppc64/kernel/sysfs.c --- linux-2.5/arch/ppc64/kernel/sysfs.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/sysfs.c 2005-02-04 00:33:26.000000000 -0600 @@ -63,7 +63,7 @@ static int __init smt_setup(void) unsigned int *val; unsigned int cpu; - if (!cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (!CPU_HAS_FEATURE(SMT)) return 1; options = find_path_device("/options"); @@ -86,7 +86,7 @@ static int __init setup_smt_snooze_delay unsigned int cpu; int snooze; - if (!cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (!CPU_HAS_FEATURE(SMT)) return 1; smt_snooze_cmdline = 1; @@ -167,7 +167,7 @@ void ppc64_enable_pmcs(void) * On SMT machines we have to set the run latch in the ctrl register * in order to make PMC6 spin. */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) { + if (CPU_HAS_FEATURE(SMT)) { ctrl = mfspr(CTRLF); ctrl |= RUNLATCH; mtspr(CTRLT, ctrl); @@ -266,7 +266,7 @@ static void register_cpu_online(unsigned struct sys_device *s = &c->sysdev; #ifndef CONFIG_PPC_ISERIES - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (CPU_HAS_FEATURE(SMT)) sysdev_create_file(s, &attr_smt_snooze_delay); #endif @@ -275,7 +275,7 @@ static void register_cpu_online(unsigned sysdev_create_file(s, &attr_mmcr0); sysdev_create_file(s, &attr_mmcr1); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (CPU_HAS_FEATURE(MMCRA)) sysdev_create_file(s, &attr_mmcra); sysdev_create_file(s, &attr_pmc1); @@ -285,12 +285,12 @@ static void register_cpu_online(unsigned sysdev_create_file(s, &attr_pmc5); sysdev_create_file(s, &attr_pmc6); - if (cur_cpu_spec->cpu_features & CPU_FTR_PMC8) { + if (CPU_HAS_FEATURE(PMC8)) { sysdev_create_file(s, &attr_pmc7); sysdev_create_file(s, &attr_pmc8); } - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (CPU_HAS_FEATURE(SMT)) sysdev_create_file(s, &attr_purr); } @@ -303,7 +303,7 @@ static void unregister_cpu_online(unsign BUG_ON(c->no_control); #ifndef CONFIG_PPC_ISERIES - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (CPU_HAS_FEATURE(SMT)) sysdev_remove_file(s, &attr_smt_snooze_delay); #endif @@ -312,7 +312,7 @@ static void unregister_cpu_online(unsign sysdev_remove_file(s, &attr_mmcr0); sysdev_remove_file(s, &attr_mmcr1); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (CPU_HAS_FEATURE(MMCRA)) sysdev_remove_file(s, &attr_mmcra); sysdev_remove_file(s, &attr_pmc1); @@ -322,12 +322,12 @@ static void unregister_cpu_online(unsign sysdev_remove_file(s, &attr_pmc5); sysdev_remove_file(s, &attr_pmc6); - if (cur_cpu_spec->cpu_features & CPU_FTR_PMC8) { + if (CPU_HAS_FEATURE(PMC8)) { sysdev_remove_file(s, &attr_pmc7); sysdev_remove_file(s, &attr_pmc8); } - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (CPU_HAS_FEATURE(SMT)) sysdev_remove_file(s, &attr_purr); } #endif /* CONFIG_HOTPLUG_CPU */ diff -puN arch/ppc64/mm/hash_native.c~cpu-has-feature arch/ppc64/mm/hash_native.c --- linux-2.5/arch/ppc64/mm/hash_native.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hash_native.c 2005-02-04 00:33:26.000000000 -0600 @@ -217,10 +217,10 @@ static long native_hpte_updatepp(unsigne } /* Ensure it is out of the tlb too */ - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (CPU_HAS_FEATURE(TLBIEL) && !large && local) { tlbiel(va); } else { - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !CPU_HAS_FEATURE(LOCKLESS_TLBIE); if (lock_tlbie) spin_lock(&native_tlbie_lock); @@ -245,7 +245,7 @@ static void native_hpte_updateboltedpp(u unsigned long vsid, va, vpn, flags = 0; long slot; HPTE *hptep; - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !CPU_HAS_FEATURE(LOCKLESS_TLBIE); vsid = get_kernel_vsid(ea); va = (vsid << 28) | (ea & 0x0fffffff); @@ -273,7 +273,7 @@ static void native_hpte_invalidate(unsig Hpte_dword0 dw0; unsigned long avpn = va >> 23; unsigned long flags; - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !CPU_HAS_FEATURE(LOCKLESS_TLBIE); if (large) avpn &= ~0x1UL; @@ -292,7 +292,7 @@ static void native_hpte_invalidate(unsig } /* Invalidate the tlb */ - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (CPU_HAS_FEATURE(TLBIEL) && !large && local) { tlbiel(va); } else { if (lock_tlbie) @@ -360,7 +360,7 @@ static void native_flush_hash_range(unsi j++; } - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (CPU_HAS_FEATURE(TLBIEL) && !large && local) { asm volatile("ptesync":::"memory"); for (i = 0; i < j; i++) @@ -368,7 +368,7 @@ static void native_flush_hash_range(unsi asm volatile("ptesync":::"memory"); } else { - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !CPU_HAS_FEATURE(LOCKLESS_TLBIE); if (lock_tlbie) spin_lock(&native_tlbie_lock); diff -puN arch/ppc64/mm/hash_utils.c~cpu-has-feature arch/ppc64/mm/hash_utils.c --- linux-2.5/arch/ppc64/mm/hash_utils.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hash_utils.c 2005-02-04 00:33:26.000000000 -0600 @@ -190,7 +190,7 @@ void __init htab_initialize(void) * _NOT_ map it to avoid cache paradoxes as it's remapped non * cacheable later on */ - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (CPU_HAS_FEATURE(16M_PAGE)) use_largepages = 1; /* create bolted the linear mapping in the hash table */ diff -puN arch/ppc64/mm/hugetlbpage.c~cpu-has-feature arch/ppc64/mm/hugetlbpage.c --- linux-2.5/arch/ppc64/mm/hugetlbpage.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hugetlbpage.c 2005-02-04 00:33:26.000000000 -0600 @@ -705,7 +705,7 @@ unsigned long hugetlb_get_unmapped_area( if (len & ~HPAGE_MASK) return -EINVAL; - if (!(cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)) + if (!CPU_HAS_FEATURE(16M_PAGE)) return -EINVAL; if (test_thread_flag(TIF_32BIT)) { diff -puN arch/ppc64/mm/init.c~cpu-has-feature arch/ppc64/mm/init.c --- linux-2.5/arch/ppc64/mm/init.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/mm/init.c 2005-02-04 00:33:26.000000000 -0600 @@ -752,7 +752,7 @@ void __init mem_init(void) */ void flush_dcache_page(struct page *page) { - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (CPU_HAS_FEATURE(COHERENT_ICACHE)) return; /* avoid an atomic op if possible */ if (test_bit(PG_arch_1, &page->flags)) @@ -763,7 +763,7 @@ void clear_user_page(void *page, unsigne { clear_page(page); - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (CPU_HAS_FEATURE(COHERENT_ICACHE)) return; /* * We shouldnt have to do this, but some versions of glibc @@ -796,7 +796,7 @@ void copy_user_page(void *vto, void *vfr return; #endif - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (CPU_HAS_FEATURE(COHERENT_ICACHE)) return; /* avoid an atomic op if possible */ @@ -832,8 +832,8 @@ void update_mmu_cache(struct vm_area_str unsigned long flags; /* handle i-cache coherency */ - if (!(cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) && - !(cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)) { + if (!CPU_HAS_FEATURE(COHERENT_ICACHE) && + !CPU_HAS_FEATURE(NOEXECUTE)) { unsigned long pfn = pte_pfn(pte); if (pfn_valid(pfn)) { struct page *page = pfn_to_page(pfn); diff -puN arch/ppc64/mm/slb.c~cpu-has-feature arch/ppc64/mm/slb.c --- linux-2.5/arch/ppc64/mm/slb.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/mm/slb.c 2005-02-04 00:33:26.000000000 -0600 @@ -51,7 +51,7 @@ static void slb_flush_and_rebolt(void) WARN_ON(!irqs_disabled()); - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (CPU_HAS_FEATURE(16M_PAGE)) ksp_flags |= SLB_VSID_L; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); @@ -139,7 +139,7 @@ void slb_initialize(void) unsigned long flags = SLB_VSID_KERNEL; /* Invalidate the entire SLB (even slot 0) & all the ERATS */ - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (CPU_HAS_FEATURE(16M_PAGE)) flags |= SLB_VSID_L; asm volatile("isync":::"memory"); diff -puN arch/ppc64/mm/stab.c~cpu-has-feature arch/ppc64/mm/stab.c --- linux-2.5/arch/ppc64/mm/stab.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/mm/stab.c 2005-02-04 00:33:26.000000000 -0600 @@ -227,7 +227,7 @@ void stab_initialize(unsigned long stab) { unsigned long vsid = get_kernel_vsid(KERNELBASE); - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { + if (CPU_HAS_FEATURE(SLB)) { slb_initialize(); } else { asm volatile("isync; slbia; isync":::"memory"); diff -puN arch/ppc64/oprofile/op_model_power4.c~cpu-has-feature arch/ppc64/oprofile/op_model_power4.c --- linux-2.5/arch/ppc64/oprofile/op_model_power4.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/oprofile/op_model_power4.c 2005-02-04 00:33:26.000000000 -0600 @@ -54,7 +54,7 @@ static void power4_reg_setup(struct op_c * * It has been verified to work on POWER5 so we enable it there. */ - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA_SIHV) + if (CPU_HAS_FEATURE(MMCRA_SIHV)) mmcra_has_sihv = 1; /* diff -puN arch/ppc64/oprofile/op_model_rs64.c~cpu-has-feature arch/ppc64/oprofile/op_model_rs64.c --- linux-2.5/arch/ppc64/oprofile/op_model_rs64.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/oprofile/op_model_rs64.c 2005-02-04 00:33:26.000000000 -0600 @@ -114,7 +114,7 @@ static void rs64_cpu_setup(void *unused) /* reset MMCR1, MMCRA */ mtspr(SPRN_MMCR1, 0); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (CPU_HAS_FEATURE(MMCRA)) mtspr(SPRN_MMCRA, 0); mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE; diff -puN arch/ppc64/xmon/xmon.c~cpu-has-feature arch/ppc64/xmon/xmon.c --- linux-2.5/arch/ppc64/xmon/xmon.c~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/xmon/xmon.c 2005-02-04 00:33:26.000000000 -0600 @@ -723,7 +723,7 @@ static void insert_cpu_bpts(void) { if (dabr.enabled) set_controlled_dabr(dabr.address | (dabr.enabled & 7)); - if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR)) + if (iabr && CPU_HAS_FEATURE(IABR)) set_iabr(iabr->address | (iabr->enabled & (BP_IABR|BP_IABR_TE))); } @@ -751,7 +751,7 @@ static void remove_bpts(void) static void remove_cpu_bpts(void) { set_controlled_dabr(0); - if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR)) + if (CPU_HAS_FEATURE(IABR)) set_iabr(0); } @@ -1098,7 +1098,7 @@ bpt_cmds(void) break; case 'i': /* bi - hardware instr breakpoint */ - if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) { + if (!CPU_HAS_FEATURE(IABR)) { printf("Hardware instruction breakpoint " "not supported on this cpu\n"); break; @@ -2496,7 +2496,7 @@ void xmon_init(void) void dump_segments(void) { - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (CPU_HAS_FEATURE(SLB)) dump_slb(); else dump_stab(); diff -puN include/asm-ppc64/cacheflush.h~cpu-has-feature include/asm-ppc64/cacheflush.h --- linux-2.5/include/asm-ppc64/cacheflush.h~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/include/asm-ppc64/cacheflush.h 2005-02-04 00:33:26.000000000 -0600 @@ -40,7 +40,7 @@ extern void __flush_dcache_icache(void * static inline void flush_icache_range(unsigned long start, unsigned long stop) { - if (!(cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE)) + if (!CPU_HAS_FEATURE(COHERENT_ICACHE)) __flush_icache_range(start, stop); } diff -puN include/asm-ppc64/mmu_context.h~cpu-has-feature include/asm-ppc64/mmu_context.h --- linux-2.5/include/asm-ppc64/mmu_context.h~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/include/asm-ppc64/mmu_context.h 2005-02-04 00:33:26.000000000 -0600 @@ -59,11 +59,11 @@ static inline void switch_mm(struct mm_s return; #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) + if (CPU_HAS_FEATURE(ALTIVEC)) asm volatile ("dssall"); #endif /* CONFIG_ALTIVEC */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (CPU_HAS_FEATURE(SLB)) switch_slb(tsk, next); else switch_stab(tsk, next); diff -puN include/asm-ppc64/page.h~cpu-has-feature include/asm-ppc64/page.h --- linux-2.5/include/asm-ppc64/page.h~cpu-has-feature 2005-02-04 00:33:26.000000000 -0600 +++ linux-2.5-olof/include/asm-ppc64/page.h 2005-02-04 00:33:26.000000000 -0600 @@ -67,7 +67,7 @@ #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #define in_hugepage_area(context, addr) \ - ((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) && \ + (CPU_HAS_FEATURE(16M_PAGE) && \ ( (((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \ ( ((addr) < 0x100000000L) && \ ((1 << GET_ESID(addr)) & (context).htlb_segs) ) ) ) diff -puN arch/ppc64/kernel/pSeries_lpar.c~cpu-has-feature arch/ppc64/kernel/pSeries_lpar.c --- linux-2.5/arch/ppc64/kernel/pSeries_lpar.c~cpu-has-feature 2005-02-04 00:34:36.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/pSeries_lpar.c 2005-02-04 00:34:52.000000000 -0600 @@ -505,7 +505,7 @@ void pSeries_lpar_flush_hash_range(unsig int i; unsigned long flags = 0; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !CPU_HAS_FEATURE(LOCKLESS_TLBIE); if (lock_tlbie) spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); diff -puN arch/ppc64/kernel/setup.c~cpu-has-feature arch/ppc64/kernel/setup.c --- linux-2.5/arch/ppc64/kernel/setup.c~cpu-has-feature 2005-02-04 00:35:01.000000000 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/setup.c 2005-02-04 00:35:41.000000000 -0600 @@ -315,7 +315,7 @@ static void __init setup_cpu_maps(void) maxcpus = ireg[num_addr_cell + num_size_cell]; /* Double maxcpus for processors which have SMT capability */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (CPU_HAS_FEATURE(SMT)) maxcpus *= 2; if (maxcpus > NR_CPUS) { @@ -339,7 +339,7 @@ static void __init setup_cpu_maps(void) */ for_each_cpu(cpu) { cpu_set(cpu, cpu_sibling_map[cpu]); - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (CPU_HAS_FEATURE(SMT)) cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); } @@ -767,7 +767,7 @@ static int show_cpuinfo(struct seq_file seq_printf(m, "unknown (%08x)", pvr); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) + if (CPU_HAS_FEATURE(ALTIVEC)) seq_printf(m, ", altivec supported"); #endif /* CONFIG_ALTIVEC */ diff -puN drivers/macintosh/via-pmu.c~cpu-has-feature drivers/macintosh/via-pmu.c --- linux-2.5/drivers/macintosh/via-pmu.c~cpu-has-feature 2005-02-04 00:35:56.000000000 -0600 +++ linux-2.5-olof/drivers/macintosh/via-pmu.c 2005-02-04 00:36:28.000000000 -0600 @@ -2389,7 +2389,7 @@ pmac_suspend_devices(void) enable_kernel_fp(); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + if (CPU_HAS_FEATURE(ALTIVEC)) enable_kernel_altivec(); #endif /* CONFIG_ALTIVEC */ diff -puN include/asm-ppc/cputable.h~cpu-has-feature include/asm-ppc/cputable.h --- linux-2.5/include/asm-ppc/cputable.h~cpu-has-feature 2005-02-04 00:37:02.000000000 -0600 +++ linux-2.5-olof/include/asm-ppc/cputable.h 2005-02-04 00:40:29.000000000 -0600 @@ -61,6 +61,8 @@ struct cpu_spec { extern struct cpu_spec cpu_specs[]; extern struct cpu_spec *cur_cpu_spec[]; +#define CPU_HAS_FEATURE(x) (cur_cpu_spec[0]->cpu_features & CPU_FTR_##x) + #endif /* __ASSEMBLY__ */ /* CPU kernel features */ diff -puN arch/ppc/mm/ppc_mmu.c~cpu-has-feature arch/ppc/mm/ppc_mmu.c --- linux-2.5/arch/ppc/mm/ppc_mmu.c~cpu-has-feature 2005-02-04 00:51:34.000000000 -0600 +++ linux-2.5-olof/arch/ppc/mm/ppc_mmu.c 2005-02-04 00:52:27.000000000 -0600 @@ -138,7 +138,7 @@ void __init setbat(int index, unsigned l union ubat *bat = BATS[index]; if (((flags & _PAGE_NO_CACHE) == 0) && - (cur_cpu_spec[0]->cpu_features & CPU_FTR_NEED_COHERENT)) + CPU_HAS_FEATURE(NEED_COHERENT)) flags |= _PAGE_COHERENT; bl = (size >> 17) - 1; @@ -191,7 +191,7 @@ void __init MMU_init_hw(void) extern unsigned int hash_page[]; extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[]; - if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0) { + if (!CPU_HAS_FEATURE(HPTE_TABLE)) { /* * Put a blr (procedure return) instruction at the * start of hash_page, since we can still get DSI diff -puN arch/ppc/mm/mmu_decl.h~cpu-has-feature arch/ppc/mm/mmu_decl.h --- linux-2.5/arch/ppc/mm/mmu_decl.h~cpu-has-feature 2005-02-04 00:52:45.000000000 -0600 +++ linux-2.5-olof/arch/ppc/mm/mmu_decl.h 2005-02-04 00:53:03.000000000 -0600 @@ -75,7 +75,7 @@ static inline void flush_HPTE(unsigned c unsigned long pdval) { if ((Hash != 0) && - (cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE)) + CPU_HAS_FEATURE(HPTE_TABLE)) flush_hash_pages(0, va, pdval, 1); else _tlbie(va); diff -puN arch/ppc/kernel/setup.c~cpu-has-feature arch/ppc/kernel/setup.c --- linux-2.5/arch/ppc/kernel/setup.c~cpu-has-feature 2005-02-04 00:54:27.000000000 -0600 +++ linux-2.5-olof/arch/ppc/kernel/setup.c 2005-02-04 00:55:17.000000000 -0600 @@ -619,7 +619,7 @@ machine_init(unsigned long r3, unsigned /* Checks "l2cr=xxxx" command-line option */ int __init ppc_setup_l2cr(char *str) { - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { + if (CPU_HAS_FEATURE(L2CR)) { unsigned long val = simple_strtoul(str, NULL, 0); printk(KERN_INFO "l2cr set to %lx\n", val); _set_L2CR(0); /* force invalidate by disable cache */ @@ -720,7 +720,7 @@ void __init setup_arch(char **cmdline_p) * Systems with OF can look in the properties on the cpu node(s) * for a possibly more accurate value. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPLIT_ID_CACHE) { + if (CPU_HAS_FEATURE(SPLIT_ID_CACHE)) { dcache_bsize = cur_cpu_spec[0]->dcache_bsize; icache_bsize = cur_cpu_spec[0]->icache_bsize; ucache_bsize = 0; diff -puN arch/ppc/kernel/temp.c~cpu-has-feature arch/ppc/kernel/temp.c --- linux-2.5/arch/ppc/kernel/temp.c~cpu-has-feature 2005-02-04 00:55:40.000000000 -0600 +++ linux-2.5-olof/arch/ppc/kernel/temp.c 2005-02-04 00:56:17.000000000 -0600 @@ -223,7 +223,7 @@ int __init TAU_init(void) /* We assume in SMP that if one CPU has TAU support, they * all have it --BenH */ - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_TAU)) { + if (!CPU_HAS_FEATURE(TAU)) { printk("Thermal assist unit not available\n"); tau_initialized = 0; return 1; diff -puN arch/ppc/platforms/pmac_cpufreq.c~cpu-has-feature arch/ppc/platforms/pmac_cpufreq.c --- linux-2.5/arch/ppc/platforms/pmac_cpufreq.c~cpu-has-feature 2005-02-04 00:56:40.000000000 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_cpufreq.c 2005-02-04 00:57:21.000000000 -0600 @@ -230,7 +230,7 @@ static int __pmac pmu_set_cpu_speed(int enable_kernel_fp(); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + if (CPU_HAS_FEATURE(ALTIVEC)) enable_kernel_altivec(); #endif /* CONFIG_ALTIVEC */ diff -puN arch/ppc/platforms/pmac_setup.c~cpu-has-feature arch/ppc/platforms/pmac_setup.c --- linux-2.5/arch/ppc/platforms/pmac_setup.c~cpu-has-feature 2005-02-04 00:56:44.000000000 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_setup.c 2005-02-04 00:57:33.000000000 -0600 @@ -274,7 +274,7 @@ pmac_setup_arch(void) pmac_find_bridges(); /* Checks "l2cr-value" property in the registry */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { + if (CPU_HAS_FEATURE(L2CR)) { struct device_node *np = find_devices("cpus"); if (np == 0) np = find_type_devices("cpu"); diff -puN arch/ppc/platforms/pmac_smp.c~cpu-has-feature arch/ppc/platforms/pmac_smp.c --- linux-2.5/arch/ppc/platforms/pmac_smp.c~cpu-has-feature 2005-02-04 00:56:46.000000000 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_smp.c 2005-02-04 00:57:55.000000000 -0600 @@ -119,7 +119,7 @@ static volatile int sec_tb_reset = 0; static void __init core99_init_caches(int cpu) { - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) + if (!CPU_HAS_FEATURE(L2CR)) return; if (cpu == 0) { @@ -132,7 +132,7 @@ static void __init core99_init_caches(in printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); } - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)) + if (!CPU_HAS_FEATURE(L3CR)) return; if (cpu == 0){ diff -puN arch/ppc/platforms/sandpoint.c~cpu-has-feature arch/ppc/platforms/sandpoint.c --- linux-2.5/arch/ppc/platforms/sandpoint.c~cpu-has-feature 2005-02-04 00:56:53.000000000 -0600 +++ linux-2.5-olof/arch/ppc/platforms/sandpoint.c 2005-02-04 00:58:28.000000000 -0600 @@ -319,10 +319,10 @@ sandpoint_setup_arch(void) * We will do this now with good known values. Future versions * of DINK32 are supposed to get this correct. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) + if (CPU_HAS_FEATURE(SPEC7450)) /* 745x is different. We only want to pass along enable. */ _set_L2CR(L2CR_L2E); - else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) + else if (CPU_HAS_FEATURE(L2CR)) /* All modules have 1MB of L2. We also assume that an * L2 divisor of 3 will work. */ @@ -330,7 +330,7 @@ sandpoint_setup_arch(void) | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF); #if 0 /* Untested right now. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR) { + if (CPU_HAS_FEATURE(L3CR)) { /* Magic value. */ _set_L3CR(0x8f032000); } diff -puN arch/ppc/kernel/ppc_htab.c~cpu-has-feature arch/ppc/kernel/ppc_htab.c --- linux-2.5/arch/ppc/kernel/ppc_htab.c~cpu-has-feature 2005-02-04 00:59:10.000000000 -0600 +++ linux-2.5-olof/arch/ppc/kernel/ppc_htab.c 2005-02-04 01:00:12.000000000 -0600 @@ -108,7 +108,7 @@ static int ppc_htab_show(struct seq_file PTE *ptr; #endif /* CONFIG_PPC_STD_MMU */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { + if (CPU_HAS_FEATURE(604_PERF_MON)) { mmcr0 = mfspr(SPRN_MMCR0); pmc1 = mfspr(SPRN_PMC1); pmc2 = mfspr(SPRN_PMC2); @@ -209,7 +209,7 @@ static ssize_t ppc_htab_write(struct fil if ( !strncmp( buffer, "reset", 5) ) { - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { + if (CPU_HAS_FEATURE(604_PERF_MON)) { /* reset PMC1 and PMC2 */ mtspr(SPRN_PMC1, 0); mtspr(SPRN_PMC2, 0); @@ -221,7 +221,7 @@ static ssize_t ppc_htab_write(struct fil } /* Everything below here requires the performance monitor feature. */ - if ( !cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON ) + if (!CPU_HAS_FEATURE(604_PERF_MON)) return count; /* turn off performance monitoring */ @@ -339,7 +339,7 @@ int proc_dol2crvec(ctl_table *table, int "0.5", "1.0", "(reserved2)", "(reserved3)" }; - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) + if (!CPU_HAS_FEATURE(L2CR)) return -EFAULT; if ( /*!table->maxlen ||*/ (*ppos && !write)) { diff -puN drivers/md/raid6altivec.uc~cpu-has-feature drivers/md/raid6altivec.uc --- linux-2.5/drivers/md/raid6altivec.uc~cpu-has-feature 2005-02-04 01:08:58.808596448 -0600 +++ linux-2.5-olof/drivers/md/raid6altivec.uc 2005-02-04 01:09:35.001094352 -0600 @@ -108,7 +108,7 @@ int raid6_have_altivec(void); int raid6_have_altivec(void) { /* This assumes either all CPUs have Altivec or none does */ - return cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC; + return CPU_HAS_FEATURE(ALTIVEC): } #endif _ From penberg at gmail.com Fri Feb 4 19:17:48 2005 From: penberg at gmail.com (Pekka Enberg) Date: Fri, 4 Feb 2005 10:17:48 +0200 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <20050204072254.GA17565@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> Message-ID: <84144f0205020400172d89eddf@mail.gmail.com> Hi, On Fri, 4 Feb 2005 01:22:54 -0600, Olof Johansson wrote: > +#define CPU_HAS_FEATURE(x) (cur_cpu_spec->cpu_features & CPU_FTR_##x) > + Please drop the CPU_FTR_##x macro magic as it makes grepping more complicated. If the enum names are too long, just do s/CPU_FTR_/CPU_/g or something similar. Also, could you please make this a static inline function? Pekka From arnd at arndb.de Fri Feb 4 23:36:55 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 4 Feb 2005 13:36:55 +0100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <20050204072254.GA17565@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> Message-ID: <200502041336.59892.arnd@arndb.de> On Freedag 04 Februar 2005 08:22, Olof Johansson wrote: > It's getting pretty old to have see and type cur_cpu_spec->cpu_features > & CPU_FTR_, when a shorter and less TLA-ridden macro is more > readable. > > This also takes care of the differences between PPC and PPC64 cpu > features for the common code; most places in PPC could be replaced with > the macro as well. I have a somewhat similar patch that does the same to the systemcfg->platform checks. I'm not sure if we should use the same inline function for both checks, but I do think that they should be used in a similar way, e.g. CPU_HAS_FEATURE(x) and PLATFORM_HAS_FEATURE(x). My implementation of the platform checks tries to be extra clever by turning runtime checks into compile time checks if possible. This reduces code size and in some cases execution speed. It can also be used to replace compile time checks, i.e. it allows us to write static inline unsigned int readl(const volatile void __iomem *addr) { if (platform_is(PLATFORM_PPC_ISERIES)) return iSeries_readl(addr); if (platform_possible(PLATFORM_PPC_PSERIES)) return eeh_readl(addr); return in_le32(); } which will always result in the shortest code for any combination of CONFIG_PPC_ISERIES, CONFIG_PPC_PSERIES and the other platforms. The required code for this is roughly enum { PPC64_PLATFORM_POSSIBLE = #ifdef CONFIG_PPC_ISERIES PLATFORM_ISERIES | #endif #ifdef CONFIG_PPC_PSERIES PLATFORM_PSERIES | #endif #ifdef CONFIG_PPC_PSERIES PLATFORM_PSERIES_LPAR | #endif #ifdef CONFIG_PPC_POWERMAC PLATFORM_POWERMAC | #endif #ifdef CONFIG_PPC_MAPLE PLATFORM_MAPLE | #endif 0, PPC64_PLATFORM_ONLY = #ifdef CONFIG_PPC_ISERIES PLATFORM_ISERIES & #endif #ifdef CONFIG_PPC_PSERIES PLATFORM_PSERIES & #endif #ifdef CONFIG_PPC_POWERMAC PLATFORM_POWERMAC & #endif #ifdef CONFIG_PPC_MAPLE PLATFORM_MAPLE & #endif -1ul, }; static inline platform_is(unsigned long platform) { return ((PPC64_PLATFORM_ONLY & platform) || (PPC64_PLATFORM_POSSIBLE & platform & systemcfg->platform)); } static inline platform_possible(unsigned long platform) { reutrn !!(PPC64_PLATFORM_POSSIBLE & platform); } The same stuff is obviously possible for cur_cpu_spec->cpu_features as well. Do you think that it will help there? Arnd <>< -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050204/7e91e399/attachment.pgp From trini at kernel.crashing.org Sat Feb 5 01:45:32 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Fri, 4 Feb 2005 07:45:32 -0700 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <20050204072254.GA17565@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> Message-ID: <20050204144532.GN15359@smtp.west.cox.net> On Fri, Feb 04, 2005 at 01:22:54AM -0600, Olof Johansson wrote: > Hi, > > It's getting pretty old to have see and type cur_cpu_spec->cpu_features > & CPU_FTR_, when a shorter and less TLA-ridden macro is more > readable. > > This also takes care of the differences between PPC and PPC64 cpu > features for the common code; most places in PPC could be replaced with > the macro as well. It'd be nice if someone went and changed ppc32's cpu feature from an array and matched ppc64, while we're in here... -- Tom Rini http://gate.crashing.org/~trini/ From olof at austin.ibm.com Sat Feb 5 04:20:41 2005 From: olof at austin.ibm.com (Olof Johansson) Date: Fri, 4 Feb 2005 11:20:41 -0600 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <84144f0205020400172d89eddf@mail.gmail.com> References: <20050204072254.GA17565@austin.ibm.com> <84144f0205020400172d89eddf@mail.gmail.com> Message-ID: <20050204172041.GA17586@austin.ibm.com> On Fri, Feb 04, 2005 at 10:17:48AM +0200, Pekka Enberg wrote: > Please drop the CPU_FTR_##x macro magic as it makes grepping more > complicated. If the enum names are too long, just do s/CPU_FTR_/CPU_/g > or something similar. Also, could you please make this a static inline > function? I considered that for a while, but decided against it because: * cpu-has-feature(cpu-feature-foo) v cpu-has-feature(foo): I picked the latter for readability. * Renaming CPU_FTR_ -> CPU_ makes it less obvious that it's actually a cpu feature it's describing (i.e. CPU_ALTIVEC vs CPU_FTR_ALTIVEC). * Renaming would clobber the namespace, CPU_* definitions are used in other places in the tree. * Can't make it an inline and still use the preprocessor concatenation. That being said, you do have a point about grepability. However, personally I'd be more likely to look for CPU_HAS_FEATURE than the feature itself when reading the code, and would find that easily. The other way around (finding all uses of a feature) is harder, but the concatenation macro is right below the bit definitions and easy to spot. -Olof From olof at austin.ibm.com Sat Feb 5 05:35:14 2005 From: olof at austin.ibm.com (Olof Johansson) Date: Fri, 4 Feb 2005 12:35:14 -0600 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <200502041336.59892.arnd@arndb.de> References: <20050204072254.GA17565@austin.ibm.com> <200502041336.59892.arnd@arndb.de> Message-ID: <20050204183514.GB17586@austin.ibm.com> On Fri, Feb 04, 2005 at 01:36:55PM +0100, Arnd Bergmann wrote: > I have a somewhat similar patch that does the same to the > systemcfg->platform checks. I'm not sure if we should use the same inline > function for both checks, but I do think that they should be used in a > similar way, e.g. CPU_HAS_FEATURE(x) and PLATFORM_HAS_FEATURE(x). Yep. Firmware features are also on the list. I figured I'd do CPU features first though since they are the ones that started bugging me. > The same stuff is obviously possible for cur_cpu_spec->cpu_features as well. > Do you think that it will help there? Nice. It won't be quite as easy to do compile-time for cpu features. pSeries will need all cpus enabled since we have them all on various machines, etc. I guess Powermac/Maple could benefit from it. In the end it depends on how hairy the implementation would get vs performance improvement. -Olof From arnd at arndb.de Sat Feb 5 05:57:06 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 4 Feb 2005 19:57:06 +0100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <20050204183514.GB17586@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> <200502041336.59892.arnd@arndb.de> <20050204183514.GB17586@austin.ibm.com> Message-ID: <200502041957.06979.arnd@arndb.de> On Freedag 04 Februar 2005 19:35, Olof Johansson wrote: > pSeries will need all cpus enabled since we have them all on various > machines, etc. I guess Powermac/Maple could benefit from it. Even on pSeries, we already have CONFIG_POWER4_ONLY, which could be used to optimize away some of the checks at compile time. I think it makes sense to extend this a bit to look more like the CPU selection on i386 or s390 where can set the oldest CPU you want to support. This also fits nicely with the gcc -mcpu= options. > In the end it depends on how hairy the implementation would get vs > performance improvement. Fortunately, that optimization should be easy to do on top of your patch, so we don't have to decide now. Arnd <>< -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050204/bc4e5ab1/attachment.pgp From cfriesen at nortel.com Sat Feb 5 07:14:11 2005 From: cfriesen at nortel.com (Chris Friesen) Date: Fri, 04 Feb 2005 14:14:11 -0600 Subject: question on symbol exports In-Reply-To: <20050204203050.GA5889@dmt.cnet> References: <41FECA18.50609@nortelnetworks.com> <1107243398.4208.47.camel@laptopd505.fenrus.org> <41FFA21C.8060203@nortelnetworks.com> <1107273017.4208.132.camel@laptopd505.fenrus.org> <20050204203050.GA5889@dmt.cnet> Message-ID: <4203D793.1040604@nortel.com> I've added the ppc64 list to the addressees, in case they are interested. Marcelo Tosatti wrote: > On Tue, Feb 01, 2005 at 04:50:16PM +0100, Arjan van de Ven wrote: >>afaik one doesn't need to do a tlb flush in code that clears the dirty >>bit, as long as you use the proper vm functions to do so. >>(if those need a tlb flush, those are supposed to do that for you >>afaik). > Yep, and "proper VM function" is include/asm-generic/pgtable.h::ptep_clear_flush_dirty(), > which on PPC flushes the TLB. It turns out that to call ptep_clear_flush_dirty() on ppc64 from a module I needed to export the following symbols: __flush_tlb_pending ppc64_tlb_batch hpte_update >>Also note that your code isn't dealing with 4 level pagetables.... And >>pagetable walking in drivers is basically almost always a mistake and a >>sign that something is wrong. > Or a sign that the core kernel lacks helper functions :) Absolutely. It'd be so nice if there was a simple va_to_ptep() helper function available. Chris From benh at kernel.crashing.org Sat Feb 5 10:49:49 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Sat, 05 Feb 2005 10:49:49 +1100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <200502041336.59892.arnd@arndb.de> References: <20050204072254.GA17565@austin.ibm.com> <200502041336.59892.arnd@arndb.de> Message-ID: <1107560989.2189.119.camel@gaston> On Fri, 2005-02-04 at 13:36 +0100, Arnd Bergmann wrote: > On Freedag 04 Februar 2005 08:22, Olof Johansson wrote: > > It's getting pretty old to have see and type cur_cpu_spec->cpu_features > > & CPU_FTR_, when a shorter and less TLA-ridden macro is more > > readable. > > > > This also takes care of the differences between PPC and PPC64 cpu > > features for the common code; most places in PPC could be replaced with > > the macro as well. > > I have a somewhat similar patch that does the same to the > systemcfg->platform checks. I'm not sure if we should use the same inline > function for both checks, but I do think that they should be used in a > similar way, e.g. CPU_HAS_FEATURE(x) and PLATFORM_HAS_FEATURE(x). Note that I would prefer cpu_has_feature(), it doesn't strictly have to be a macro and has function semantics anyway. > My implementation of the platform checks tries to be extra clever by turning > runtime checks into compile time checks if possible. This reduces code size > and in some cases execution speed. It can also be used to replace compile > time checks, i.e. it allows us to write > > static inline unsigned int readl(const volatile void __iomem *addr) > { > if (platform_is(PLATFORM_PPC_ISERIES)) > return iSeries_readl(addr); > if (platform_possible(PLATFORM_PPC_PSERIES)) > return eeh_readl(addr); > return in_le32(); > } > > which will always result in the shortest code for any combination of > CONFIG_PPC_ISERIES, CONFIG_PPC_PSERIES and the other platforms. That's a good idea ! > The required code for this is roughly > > enum { > PPC64_PLATFORM_POSSIBLE = > #ifdef CONFIG_PPC_ISERIES > PLATFORM_ISERIES | > #endif > #ifdef CONFIG_PPC_PSERIES > PLATFORM_PSERIES | > #endif > #ifdef CONFIG_PPC_PSERIES > PLATFORM_PSERIES_LPAR | > #endif > #ifdef CONFIG_PPC_POWERMAC > PLATFORM_POWERMAC | > #endif > #ifdef CONFIG_PPC_MAPLE > PLATFORM_MAPLE | > #endif > 0, > PPC64_PLATFORM_ONLY = > #ifdef CONFIG_PPC_ISERIES > PLATFORM_ISERIES & > #endif > #ifdef CONFIG_PPC_PSERIES > PLATFORM_PSERIES & > #endif > #ifdef CONFIG_PPC_POWERMAC > PLATFORM_POWERMAC & > #endif > #ifdef CONFIG_PPC_MAPLE > PLATFORM_MAPLE & > #endif > -1ul, > }; > > static inline platform_is(unsigned long platform) > { > return ((PPC64_PLATFORM_ONLY & platform) > || (PPC64_PLATFORM_POSSIBLE & platform & systemcfg->platform)); > } > > static inline platform_possible(unsigned long platform) > { > reutrn !!(PPC64_PLATFORM_POSSIBLE & platform); > } > > The same stuff is obviously possible for cur_cpu_spec->cpu_features as well. > Do you think that it will help there? > > Arnd <>< > _______________________________________________ > Linuxppc64-dev mailing list > Linuxppc64-dev at ozlabs.org > https://ozlabs.org/cgi-bin/mailman/listinfo/linuxppc64-dev -- Benjamin Herrenschmidt From benh at kernel.crashing.org Sat Feb 5 10:50:44 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Sat, 05 Feb 2005 10:50:44 +1100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <20050204183514.GB17586@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> <200502041336.59892.arnd@arndb.de> <20050204183514.GB17586@austin.ibm.com> Message-ID: <1107561044.2189.120.camel@gaston> On Fri, 2005-02-04 at 12:35 -0600, Olof Johansson wrote: > On Fri, Feb 04, 2005 at 01:36:55PM +0100, Arnd Bergmann wrote: > > I have a somewhat similar patch that does the same to the > > systemcfg->platform checks. I'm not sure if we should use the same inline > > function for both checks, but I do think that they should be used in a > > similar way, e.g. CPU_HAS_FEATURE(x) and PLATFORM_HAS_FEATURE(x). > > Yep. Firmware features are also on the list. I figured I'd do CPU features > first though since they are the ones that started bugging me. > > > The same stuff is obviously possible for cur_cpu_spec->cpu_features as well. > > Do you think that it will help there? > > Nice. It won't be quite as easy to do compile-time for cpu features. > pSeries will need all cpus enabled since we have them all on various > machines, etc. I guess Powermac/Maple could benefit from it. In the > end it depends on how hairy the implementation would get vs performance > improvement. One other thing we did on ppc32 was to have separate ELF sections for pmac, chrp and prep specific code & get rid of them after boot... It may be worth bringing this back in... Ben. From arnd at arndb.de Sat Feb 5 11:22:21 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Sat, 5 Feb 2005 01:22:21 +0100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <1107560989.2189.119.camel@gaston> References: <20050204072254.GA17565@austin.ibm.com> <200502041336.59892.arnd@arndb.de> <1107560989.2189.119.camel@gaston> Message-ID: <200502050122.27254.arnd@arndb.de> On S?nnavend 05 Februar 2005 00:49, Benjamin Herrenschmidt wrote: > On Fri, 2005-02-04 at 13:36 +0100, Arnd Bergmann wrote: > > I have a somewhat similar patch that does the same to the > > systemcfg->platform checks. I'm not sure if we should use the same inline > > function for both checks, but I do think that they should be used in a > > similar way, e.g. CPU_HAS_FEATURE(x) and PLATFORM_HAS_FEATURE(x). > > Note that I would prefer cpu_has_feature(), it doesn't strictly have to > be a macro and has function semantics anyway. > > [ ... ] > > which will always result in the shortest code for any combination of > > CONFIG_PPC_ISERIES, CONFIG_PPC_PSERIES and the other platforms. > > That's a good idea ! This is the patch to evaluate CPU_HAS_FEATURE() at compile time whenever possible. Testing showed that vmlinux shrinks around 4000 bytes with g5_defconfig. I also checked that pSeries code is completely unaltered semantically when support for all CPU types is enabled, although a few instructions are emitted in a different order by gcc. I have made cpu_has_feature() an inline function that expects the full name of a feature bit while the CPU_HAS_FEATURE() macro still behaves the same way as in Olofs original patch for now. I'm not sure if I got the Kconfig dependencies right, maybe you can check them. Signed-off-by: Arnd Bergmann --- Index: linux-2.6-64/include/asm-ppc64/cputable.h =================================================================== --- linux-2.6-64.orig/include/asm-ppc64/cputable.h 2005-02-05 01:24:58.975674192 +0100 +++ linux-2.6-64/include/asm-ppc64/cputable.h 2005-02-05 01:26:17.328762712 +0100 @@ -66,9 +66,6 @@ extern struct cpu_spec cpu_specs[]; extern struct cpu_spec *cur_cpu_spec; -#define CPU_HAS_FEATURE(x) (cur_cpu_spec->cpu_features & CPU_FTR_##x) - - /* firmware feature bitmask values */ #define FIRMWARE_MAX_FEATURES 63 @@ -154,6 +151,80 @@ #define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE) #endif +/* We only set the altivec features if the kernel was compiled with altivec + * support + */ +#ifdef CONFIG_ALTIVEC +#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC +#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC +#else +#define CPU_FTR_ALTIVEC_COMP 0 +#define PPC_FEATURE_HAS_ALTIVEC_COMP 0 +#endif + +enum { + CPU_FTR_POWER3 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PMC8, + CPU_FTR_RS64 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PMC8 | + CPU_FTR_MMCRA, + CPU_FTR_POWER4 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_PMC8 | CPU_FTR_MMCRA, + CPU_FTR_PPC970 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | + CPU_FTR_PMC8 | CPU_FTR_MMCRA, + CPU_FTR_POWER5 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_MMCRA | CPU_FTR_SMT | CPU_FTR_COHERENT_ICACHE | + CPU_FTR_LOCKLESS_TLBIE | CPU_FTR_MMCRA_SIHV, + CPU_FTR_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2, + CPU_FTR_POSSIBLE = +#ifdef CONFIG_CPU_POWER3 + CPU_FTR_POWER3 | +#endif +#ifdef CONFIG_CPU_RS64 + CPU_FTR_RS64 | +#endif +#ifdef CONFIG_CPU_POWER4 + CPU_FTR_POWER4 | +#endif +#ifdef CONFIG_CPU_PPC970 + CPU_FTR_PPC970 | +#endif +#ifdef CONFIG_CPU_POWER5 + CPU_FTR_POWER5 | +#endif + 0, + CPU_FTR_ALWAYS = +#ifdef CONFIG_CPU_POWER3 + CPU_FTR_POWER3 & +#endif +#ifdef CONFIG_CPU_RS64 + CPU_FTR_RS64 & +#endif +#ifdef CONFIG_CPU_POWER4 + CPU_FTR_POWER4 & +#endif +#ifdef CONFIG_CPU_PPC970 + CPU_FTR_PPC970 & +#endif +#ifdef CONFIG_CPU_POWER5 + CPU_FTR_POWER5 & +#endif + CPU_FTR_POSSIBLE, +}; + +static inline int cpu_has_feature(unsigned long feature) +{ + return (CPU_FTR_ALWAYS & feature) || + (CPU_FTR_POSSIBLE & feature & cur_cpu_spec->cpu_features); +} + +#define CPU_HAS_FEATURE(x) cpu_has_feature(CPU_FTR_##x) + #define COMMON_PPC64_FW (0) #endif Index: linux-2.6-64/arch/ppc64/Kconfig =================================================================== --- linux-2.6-64.orig/arch/ppc64/Kconfig 2005-02-05 01:24:31.098912104 +0100 +++ linux-2.6-64/arch/ppc64/Kconfig 2005-02-05 01:25:01.430301032 +0100 @@ -107,6 +107,31 @@ bool default y +config CPU_POWER3 + bool + default y + depends on (PPC_ISERIES || PPC_PSERIES) && !POWER4_ONLY + +config CPU_RS64 + bool + default y + depends on (PPC_ISERIES || PPC_PSERIES) && !POWER4_ONLY + +config CPU_POWER4 + bool + default y + depends on PPC_ISERIES || PPC_PSERIES + +config CPU_PPC970 + bool + default y + depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE + +config CPU_POWER5 + bool + default y + depends on PPC_PSERIES + # VMX is pSeries only for now until somebody writes the iSeries # exception vectors for it config ALTIVEC Index: linux-2.6-64/arch/ppc64/kernel/cputable.c =================================================================== --- linux-2.6-64.orig/arch/ppc64/kernel/cputable.c 2005-02-05 01:24:31.098912104 +0100 +++ linux-2.6-64/arch/ppc64/kernel/cputable.c 2005-02-05 01:25:01.431300880 +0100 @@ -33,137 +33,94 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); -/* We only set the altivec features if the kernel was compiled with altivec - * support - */ -#ifdef CONFIG_ALTIVEC -#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC -#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC -#else -#define CPU_FTR_ALTIVEC_COMP 0 -#define PPC_FEATURE_HAS_ALTIVEC_COMP 0 -#endif - struct cpu_spec cpu_specs[] = { { /* Power3 */ 0xffff0000, 0x00400000, "POWER3 (630)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8, - COMMON_USER_PPC64, + CPU_FTR_POWER3, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, COMMON_PPC64_FW }, { /* Power3+ */ 0xffff0000, 0x00410000, "POWER3 (630+)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8, - COMMON_USER_PPC64, + CPU_FTR_POWER3, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, COMMON_PPC64_FW }, { /* Northstar */ 0xffff0000, 0x00330000, "RS64-II (northstar)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, + CPU_FTR_RS64, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, COMMON_PPC64_FW }, { /* Pulsar */ 0xffff0000, 0x00340000, "RS64-III (pulsar)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, + CPU_FTR_RS64, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, COMMON_PPC64_FW }, { /* I-star */ 0xffff0000, 0x00360000, "RS64-III (icestar)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, + CPU_FTR_RS64, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, COMMON_PPC64_FW }, { /* S-star */ 0xffff0000, 0x00370000, "RS64-IV (sstar)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, + CPU_FTR_RS64, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, COMMON_PPC64_FW }, { /* Power4 */ 0xffff0000, 0x00350000, "POWER4 (gp)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, + CPU_FTR_POWER4, COMMON_USER_PPC64, 128, 128, __setup_cpu_power4, COMMON_PPC64_FW }, { /* Power4+ */ 0xffff0000, 0x00380000, "POWER4+ (gq)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64, + CPU_FTR_POWER4, COMMON_USER_PPC64, 128, 128, __setup_cpu_power4, COMMON_PPC64_FW }, { /* PPC970 */ 0xffff0000, 0x00390000, "PPC970", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, + CPU_FTR_PPC970, COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, 128, 128, __setup_cpu_ppc970, COMMON_PPC64_FW }, { /* PPC970FX */ 0xffff0000, 0x003c0000, "PPC970FX", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | - CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, - COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, + CPU_FTR_PPC970, COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, 128, 128, __setup_cpu_ppc970, COMMON_PPC64_FW }, { /* Power5 */ 0xffff0000, 0x003a0000, "POWER5 (gr)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | - CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | - CPU_FTR_MMCRA_SIHV, - COMMON_USER_PPC64, + CPU_FTR_POWER5, COMMON_USER_PPC64, 128, 128, __setup_cpu_power4, COMMON_PPC64_FW }, { /* Power5 */ 0xffff0000, 0x003b0000, "POWER5 (gs)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | - CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | - CPU_FTR_MMCRA_SIHV, - COMMON_USER_PPC64, + CPU_FTR_POWER5, COMMON_USER_PPC64, 128, 128, __setup_cpu_power4, COMMON_PPC64_FW }, { /* default match */ 0x00000000, 0x00000000, "POWER4 (compatible)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2, - COMMON_USER_PPC64, + CPU_FTR_COMPATIBLE, COMMON_USER_PPC64, 128, 128, __setup_cpu_power4, COMMON_PPC64_FW -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050205/a92c1465/attachment.pgp From benh at kernel.crashing.org Sat Feb 5 12:47:05 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Sat, 05 Feb 2005 12:47:05 +1100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <200502050122.27254.arnd@arndb.de> References: <20050204072254.GA17565@austin.ibm.com> <200502041336.59892.arnd@arndb.de> <1107560989.2189.119.camel@gaston> <200502050122.27254.arnd@arndb.de> Message-ID: <1107568025.2189.136.camel@gaston> > This is the patch to evaluate CPU_HAS_FEATURE() at compile time whenever > possible. Testing showed that vmlinux shrinks around 4000 bytes with > g5_defconfig. I also checked that pSeries code is completely unaltered > semantically when support for all CPU types is enabled, although a few > instructions are emitted in a different order by gcc. > > I have made cpu_has_feature() an inline function that expects the full > name of a feature bit while the CPU_HAS_FEATURE() macro still behaves > the same way as in Olofs original patch for now. Note that this doesn't the asm part of it, where feature "sections" are nop'ed out... it may be interesting to get rid of the nops too here, oh well, that's too complicated for now. Ben. From anton at samba.org Sat Feb 5 12:34:26 2005 From: anton at samba.org (Anton Blanchard) Date: Sat, 5 Feb 2005 12:34:26 +1100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <200502050122.27254.arnd@arndb.de> References: <20050204072254.GA17565@austin.ibm.com> <200502041336.59892.arnd@arndb.de> <1107560989.2189.119.camel@gaston> <200502050122.27254.arnd@arndb.de> Message-ID: <20050205013426.GC11318@krispykreme.ozlabs.ibm.com> Hi, > This is the patch to evaluate CPU_HAS_FEATURE() at compile time whenever > possible. Testing showed that vmlinux shrinks around 4000 bytes with > g5_defconfig. I also checked that pSeries code is completely unaltered > semantically when support for all CPU types is enabled, although a few > instructions are emitted in a different order by gcc. > > I have made cpu_has_feature() an inline function that expects the full > name of a feature bit while the CPU_HAS_FEATURE() macro still behaves > the same way as in Olofs original patch for now. Interesting :) However we already get bug reports with the current CONFIG_POWER4_ONLY option. I worry about adding more options that users could get wrong unless there is a noticeable improvement in performance. Anton From penberg at cs.helsinki.fi Sat Feb 5 18:48:19 2005 From: penberg at cs.helsinki.fi (Pekka Enberg) Date: Sat, 05 Feb 2005 09:48:19 +0200 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <20050204172041.GA17586@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> <84144f0205020400172d89eddf@mail.gmail.com> <20050204172041.GA17586@austin.ibm.com> Message-ID: <1107589699.17616.4.camel@localhost> On Fri, 2005-02-04 at 11:20 -0600, Olof Johansson wrote: > * cpu-has-feature(cpu-feature-foo) v cpu-has-feature(foo): I picked the > latter for readability. > * Renaming CPU_FTR_ -> CPU_ makes it less obvious that > it's actually a cpu feature it's describing (i.e. CPU_ALTIVEC vs > CPU_FTR_ALTIVEC). > * Renaming would clobber the namespace, CPU_* definitions are used in > other places in the tree. > * Can't make it an inline and still use the preprocessor concatenation. Seriously, if readability is your argument, macro magic is not the answer. Ok, we can't clobber the CPU_ definitions, so pick another prefix. If you want readability, please consider using named enums: enum cpu_feature { CF_ALTIVEC = /* ... */ }; static inline int cpu_has_feature(enum cpu_feature cf) { } Pekka From benh at kernel.crashing.org Sat Feb 5 20:08:53 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Sat, 05 Feb 2005 20:08:53 +1100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <20050204172041.GA17586@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> <84144f0205020400172d89eddf@mail.gmail.com> <20050204172041.GA17586@austin.ibm.com> Message-ID: <1107594534.30270.3.camel@gaston> On Fri, 2005-02-04 at 11:20 -0600, Olof Johansson wrote: > On Fri, Feb 04, 2005 at 10:17:48AM +0200, Pekka Enberg wrote: > > Please drop the CPU_FTR_##x macro magic as it makes grepping more > > complicated. If the enum names are too long, just do s/CPU_FTR_/CPU_/g > > or something similar. Also, could you please make this a static inline > > function? I tend to agree with Pekka... > I considered that for a while, but decided against it because: > > * cpu-has-feature(cpu-feature-foo) v cpu-has-feature(foo): I picked the > latter for readability. I don't think it really matters compared to the usefullness of grep, and is still more readable than the old way... > * Renaming CPU_FTR_ -> CPU_ makes it less obvious that > it's actually a cpu feature it's describing (i.e. CPU_ALTIVEC vs > CPU_FTR_ALTIVEC). Agreed. > * Renaming would clobber the namespace, CPU_* definitions are used in > other places in the tree. > * Can't make it an inline and still use the preprocessor concatenation. I'd like to keep the constants as-is and have the stuff inline with no macro trick as Pekka suggest since I did use grep on those things quite often. > That being said, you do have a point about grepability. However, > personally I'd be more likely to look for CPU_HAS_FEATURE than the > feature itself when reading the code, and would find that easily. The > other way around (finding all uses of a feature) is harder, but the > concatenation macro is right below the bit definitions and easy to spot. No, when I grep, i'm looking for the feature itself... Ben. From benh at kernel.crashing.org Sat Feb 5 20:19:08 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Sat, 05 Feb 2005 20:19:08 +1100 Subject: question on symbol exports In-Reply-To: <4203D793.1040604@nortel.com> References: <41FECA18.50609@nortelnetworks.com> <1107243398.4208.47.camel@laptopd505.fenrus.org> <41FFA21C.8060203@nortelnetworks.com> <1107273017.4208.132.camel@laptopd505.fenrus.org> <20050204203050.GA5889@dmt.cnet> <4203D793.1040604@nortel.com> Message-ID: <1107595148.30302.5.camel@gaston> > It turns out that to call ptep_clear_flush_dirty() on ppc64 from a > module I needed to export the following symbols: > > __flush_tlb_pending > ppc64_tlb_batch > hpte_update Any reason why you need to call that from a module ? Is the module GPL'd ? Ben. From arnd at arndb.de Sat Feb 5 22:04:34 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Sat, 5 Feb 2005 12:04:34 +0100 Subject: [PATCH] PPC/PPC64: Introduce CPU_HAS_FEATURE() macro In-Reply-To: <20050205013426.GC11318@krispykreme.ozlabs.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> <200502050122.27254.arnd@arndb.de> <20050205013426.GC11318@krispykreme.ozlabs.ibm.com> Message-ID: <200502051204.38965.arnd@arndb.de> On S?nnavend 05 Februar 2005 02:34, Anton Blanchard wrote: > Interesting :) However we already get bug reports with the current > CONFIG_POWER4_ONLY option. I worry about adding more options that users > could get wrong unless there is a noticeable improvement in performance. > The patch that I posted doesn't add any new user selectable options, it only limits the supported CPUs to the ones that are available on the supported platforms. If you select powermac or maple, the only supported CPU will be PowerPC970, so the C compiler can optimize away all runtime checks for CPU features. I don't expect much noticeable performance advantage from the patch, but it allows to make some of the source code nicer. E.g. you can replace every instance of '#ifdef CONFIG_ALTIVEC' with 'if (CPU_FTR_POSSIBLE & CPU_FTR_ALTIVEC)' or an inline function wrapping that. Arnd <>< -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050205/d97757b1/attachment.pgp From olof at austin.ibm.com Sun Feb 6 05:46:47 2005 From: olof at austin.ibm.com (Olof Johansson) Date: Sat, 5 Feb 2005 12:46:47 -0600 Subject: [PATCH] PPC/PPC64: Abstract cpu_feature checks. In-Reply-To: <20050204072254.GA17565@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> Message-ID: <20050205184647.GA17417@austin.ibm.com> Abstract most manual mask checks of cpu_features with cpu_has_feature() Signed-off-by: Olof Johansson --- linux-2.5-olof/arch/ppc/kernel/ppc_htab.c | 8 +++--- linux-2.5-olof/arch/ppc/kernel/setup.c | 4 +-- linux-2.5-olof/arch/ppc/kernel/temp.c | 2 - linux-2.5-olof/arch/ppc/mm/mmu_decl.h | 2 - linux-2.5-olof/arch/ppc/mm/ppc_mmu.c | 4 +-- linux-2.5-olof/arch/ppc/platforms/pmac_cpufreq.c | 2 - linux-2.5-olof/arch/ppc/platforms/pmac_setup.c | 2 - linux-2.5-olof/arch/ppc/platforms/pmac_smp.c | 4 +-- linux-2.5-olof/arch/ppc/platforms/sandpoint.c | 6 ++--- linux-2.5-olof/arch/ppc64/kernel/align.c | 2 - linux-2.5-olof/arch/ppc64/kernel/iSeries_setup.c | 2 - linux-2.5-olof/arch/ppc64/kernel/pSeries_lpar.c | 2 - linux-2.5-olof/arch/ppc64/kernel/process.c | 4 +-- linux-2.5-olof/arch/ppc64/kernel/setup.c | 6 ++--- linux-2.5-olof/arch/ppc64/kernel/smp.c | 2 - linux-2.5-olof/arch/ppc64/kernel/sysfs.c | 22 +++++++++---------- linux-2.5-olof/arch/ppc64/mm/hash_native.c | 14 ++++++------ linux-2.5-olof/arch/ppc64/mm/hash_utils.c | 2 - linux-2.5-olof/arch/ppc64/mm/hugetlbpage.c | 2 - linux-2.5-olof/arch/ppc64/mm/init.c | 10 ++++---- linux-2.5-olof/arch/ppc64/mm/slb.c | 4 +-- linux-2.5-olof/arch/ppc64/mm/stab.c | 2 - linux-2.5-olof/arch/ppc64/oprofile/op_model_power4.c | 2 - linux-2.5-olof/arch/ppc64/oprofile/op_model_rs64.c | 2 - linux-2.5-olof/arch/ppc64/xmon/xmon.c | 8 +++--- linux-2.5-olof/drivers/macintosh/via-pmu.c | 2 - linux-2.5-olof/drivers/md/raid6altivec.uc | 2 - linux-2.5-olof/include/asm-ppc/cputable.h | 5 ++++ linux-2.5-olof/include/asm-ppc64/cacheflush.h | 2 - linux-2.5-olof/include/asm-ppc64/cputable.h | 5 ++++ linux-2.5-olof/include/asm-ppc64/mmu_context.h | 4 +-- linux-2.5-olof/include/asm-ppc64/page.h | 2 - 32 files changed, 76 insertions(+), 66 deletions(-) diff -puN include/asm-ppc64/cputable.h~cpu-has-feature include/asm-ppc64/cputable.h --- linux-2.5/include/asm-ppc64/cputable.h~cpu-has-feature 2005-02-05 11:11:03.478617416 -0600 +++ linux-2.5-olof/include/asm-ppc64/cputable.h 2005-02-05 11:22:32.309899144 -0600 @@ -66,6 +66,11 @@ struct cpu_spec { extern struct cpu_spec cpu_specs[]; extern struct cpu_spec *cur_cpu_spec; +static inline unsigned long cpu_has_feature(feature) +{ + return cur_cpu_spec->cpu_features & feature; +} + /* firmware feature bitmask values */ #define FIRMWARE_MAX_FEATURES 63 diff -puN arch/ppc64/kernel/align.c~cpu-has-feature arch/ppc64/kernel/align.c --- linux-2.5/arch/ppc64/kernel/align.c~cpu-has-feature 2005-02-05 11:11:03.521610880 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/align.c 2005-02-05 11:11:04.117520288 -0600 @@ -238,7 +238,7 @@ fix_alignment(struct pt_regs *regs) dsisr = regs->dsisr; - if (cur_cpu_spec->cpu_features & CPU_FTR_NODSISRALIGN) { + if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) { unsigned int real_instr; if (__get_user(real_instr, (unsigned int __user *)regs->nip)) return 0; diff -puN arch/ppc64/kernel/iSeries_setup.c~cpu-has-feature arch/ppc64/kernel/iSeries_setup.c --- linux-2.5/arch/ppc64/kernel/iSeries_setup.c~cpu-has-feature 2005-02-05 11:11:03.525610272 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/iSeries_setup.c 2005-02-05 11:11:04.118520136 -0600 @@ -267,7 +267,7 @@ unsigned long iSeries_process_mainstore_ unsigned long i; unsigned long mem_blocks = 0; - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (cpu_has_feature(CPU_FTR_SLB)) mem_blocks = iSeries_process_Regatta_mainstore_vpd(mb_array, max_entries); else diff -puN arch/ppc64/kernel/idle.c~cpu-has-feature arch/ppc64/kernel/idle.c diff -puN arch/ppc64/kernel/process.c~cpu-has-feature arch/ppc64/kernel/process.c --- linux-2.5/arch/ppc64/kernel/process.c~cpu-has-feature 2005-02-05 11:11:03.600598872 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/process.c 2005-02-05 11:11:04.119519984 -0600 @@ -388,12 +388,12 @@ copy_thread(int nr, unsigned long clone_ kregs = (struct pt_regs *) sp; sp -= STACK_FRAME_OVERHEAD; p->thread.ksp = sp; - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { + if (cpu_has_feature(CPU_FTR_SLB)) { unsigned long sp_vsid = get_kernel_vsid(sp); sp_vsid <<= SLB_VSID_SHIFT; sp_vsid |= SLB_VSID_KERNEL; - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) sp_vsid |= SLB_VSID_L; p->thread.ksp_vsid = sp_vsid; diff -puN arch/ppc64/kernel/smp.c~cpu-has-feature arch/ppc64/kernel/smp.c --- linux-2.5/arch/ppc64/kernel/smp.c~cpu-has-feature 2005-02-05 11:11:03.606597960 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/smp.c 2005-02-05 11:11:04.120519832 -0600 @@ -416,7 +416,7 @@ int __devinit __cpu_up(unsigned int cpu) paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; - if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) { + if (!cpu_has_feature(CPU_FTR_SLB)) { void *tmp; /* maximum of 48 CPUs on machines with a segment table */ diff -puN arch/ppc64/kernel/sysfs.c~cpu-has-feature arch/ppc64/kernel/sysfs.c --- linux-2.5/arch/ppc64/kernel/sysfs.c~cpu-has-feature 2005-02-05 11:11:03.609597504 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/sysfs.c 2005-02-05 11:11:04.121519680 -0600 @@ -63,7 +63,7 @@ static int __init smt_setup(void) unsigned int *val; unsigned int cpu; - if (!cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (!cpu_has_feature(CPU_FTR_SMT)) return 1; options = find_path_device("/options"); @@ -86,7 +86,7 @@ static int __init setup_smt_snooze_delay unsigned int cpu; int snooze; - if (!cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (!cpu_has_feature(CPU_FTR_SMT)) return 1; smt_snooze_cmdline = 1; @@ -167,7 +167,7 @@ void ppc64_enable_pmcs(void) * On SMT machines we have to set the run latch in the ctrl register * in order to make PMC6 spin. */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) { + if (cpu_has_feature(CPU_FTR_SMT)) { ctrl = mfspr(CTRLF); ctrl |= RUNLATCH; mtspr(CTRLT, ctrl); @@ -266,7 +266,7 @@ static void register_cpu_online(unsigned struct sys_device *s = &c->sysdev; #ifndef CONFIG_PPC_ISERIES - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) sysdev_create_file(s, &attr_smt_snooze_delay); #endif @@ -275,7 +275,7 @@ static void register_cpu_online(unsigned sysdev_create_file(s, &attr_mmcr0); sysdev_create_file(s, &attr_mmcr1); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (cpu_has_feature(CPU_FTR_MMCRA)) sysdev_create_file(s, &attr_mmcra); sysdev_create_file(s, &attr_pmc1); @@ -285,12 +285,12 @@ static void register_cpu_online(unsigned sysdev_create_file(s, &attr_pmc5); sysdev_create_file(s, &attr_pmc6); - if (cur_cpu_spec->cpu_features & CPU_FTR_PMC8) { + if (cpu_has_feature(CPU_FTR_PMC8)) { sysdev_create_file(s, &attr_pmc7); sysdev_create_file(s, &attr_pmc8); } - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) sysdev_create_file(s, &attr_purr); } @@ -303,7 +303,7 @@ static void unregister_cpu_online(unsign BUG_ON(c->no_control); #ifndef CONFIG_PPC_ISERIES - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) sysdev_remove_file(s, &attr_smt_snooze_delay); #endif @@ -312,7 +312,7 @@ static void unregister_cpu_online(unsign sysdev_remove_file(s, &attr_mmcr0); sysdev_remove_file(s, &attr_mmcr1); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (cpu_has_feature(CPU_FTR_MMCRA)) sysdev_remove_file(s, &attr_mmcra); sysdev_remove_file(s, &attr_pmc1); @@ -322,12 +322,12 @@ static void unregister_cpu_online(unsign sysdev_remove_file(s, &attr_pmc5); sysdev_remove_file(s, &attr_pmc6); - if (cur_cpu_spec->cpu_features & CPU_FTR_PMC8) { + if (cpu_has_feature(CPU_FTR_PMC8)) { sysdev_remove_file(s, &attr_pmc7); sysdev_remove_file(s, &attr_pmc8); } - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) sysdev_remove_file(s, &attr_purr); } #endif /* CONFIG_HOTPLUG_CPU */ diff -puN arch/ppc64/mm/hash_native.c~cpu-has-feature arch/ppc64/mm/hash_native.c --- linux-2.5/arch/ppc64/mm/hash_native.c~cpu-has-feature 2005-02-05 11:11:03.653590816 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hash_native.c 2005-02-05 11:11:04.122519528 -0600 @@ -217,10 +217,10 @@ static long native_hpte_updatepp(unsigne } /* Ensure it is out of the tlb too */ - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) { tlbiel(va); } else { - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (lock_tlbie) spin_lock(&native_tlbie_lock); @@ -245,7 +245,7 @@ static void native_hpte_updateboltedpp(u unsigned long vsid, va, vpn, flags = 0; long slot; HPTE *hptep; - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); vsid = get_kernel_vsid(ea); va = (vsid << 28) | (ea & 0x0fffffff); @@ -273,7 +273,7 @@ static void native_hpte_invalidate(unsig Hpte_dword0 dw0; unsigned long avpn = va >> 23; unsigned long flags; - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (large) avpn &= ~0x1UL; @@ -292,7 +292,7 @@ static void native_hpte_invalidate(unsig } /* Invalidate the tlb */ - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) { tlbiel(va); } else { if (lock_tlbie) @@ -360,7 +360,7 @@ static void native_flush_hash_range(unsi j++; } - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) { asm volatile("ptesync":::"memory"); for (i = 0; i < j; i++) @@ -368,7 +368,7 @@ static void native_flush_hash_range(unsi asm volatile("ptesync":::"memory"); } else { - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (lock_tlbie) spin_lock(&native_tlbie_lock); diff -puN arch/ppc64/mm/hash_utils.c~cpu-has-feature arch/ppc64/mm/hash_utils.c --- linux-2.5/arch/ppc64/mm/hash_utils.c~cpu-has-feature 2005-02-05 11:11:03.656590360 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hash_utils.c 2005-02-05 11:11:04.123519376 -0600 @@ -190,7 +190,7 @@ void __init htab_initialize(void) * _NOT_ map it to avoid cache paradoxes as it's remapped non * cacheable later on */ - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) use_largepages = 1; /* create bolted the linear mapping in the hash table */ diff -puN arch/ppc64/mm/hugetlbpage.c~cpu-has-feature arch/ppc64/mm/hugetlbpage.c --- linux-2.5/arch/ppc64/mm/hugetlbpage.c~cpu-has-feature 2005-02-05 11:11:03.674587624 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hugetlbpage.c 2005-02-05 11:11:04.123519376 -0600 @@ -705,7 +705,7 @@ unsigned long hugetlb_get_unmapped_area( if (len & ~HPAGE_MASK) return -EINVAL; - if (!(cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)) + if (!cpu_has_feature(CPU_FTR_16M_PAGE)) return -EINVAL; if (test_thread_flag(TIF_32BIT)) { diff -puN arch/ppc64/mm/init.c~cpu-has-feature arch/ppc64/mm/init.c --- linux-2.5/arch/ppc64/mm/init.c~cpu-has-feature 2005-02-05 11:11:03.680586712 -0600 +++ linux-2.5-olof/arch/ppc64/mm/init.c 2005-02-05 11:11:04.124519224 -0600 @@ -752,7 +752,7 @@ void __init mem_init(void) */ void flush_dcache_page(struct page *page) { - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) return; /* avoid an atomic op if possible */ if (test_bit(PG_arch_1, &page->flags)) @@ -763,7 +763,7 @@ void clear_user_page(void *page, unsigne { clear_page(page); - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) return; /* * We shouldnt have to do this, but some versions of glibc @@ -796,7 +796,7 @@ void copy_user_page(void *vto, void *vfr return; #endif - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) return; /* avoid an atomic op if possible */ @@ -832,8 +832,8 @@ void update_mmu_cache(struct vm_area_str unsigned long flags; /* handle i-cache coherency */ - if (!(cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) && - !(cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)) { + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && + !cpu_has_feature(CPU_FTR_NOEXECUTE)) { unsigned long pfn = pte_pfn(pte); if (pfn_valid(pfn)) { struct page *page = pfn_to_page(pfn); diff -puN arch/ppc64/mm/slb.c~cpu-has-feature arch/ppc64/mm/slb.c --- linux-2.5/arch/ppc64/mm/slb.c~cpu-has-feature 2005-02-05 11:11:03.683586256 -0600 +++ linux-2.5-olof/arch/ppc64/mm/slb.c 2005-02-05 11:11:04.125519072 -0600 @@ -51,7 +51,7 @@ static void slb_flush_and_rebolt(void) WARN_ON(!irqs_disabled()); - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) ksp_flags |= SLB_VSID_L; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); @@ -139,7 +139,7 @@ void slb_initialize(void) unsigned long flags = SLB_VSID_KERNEL; /* Invalidate the entire SLB (even slot 0) & all the ERATS */ - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) flags |= SLB_VSID_L; asm volatile("isync":::"memory"); diff -puN arch/ppc64/mm/stab.c~cpu-has-feature arch/ppc64/mm/stab.c --- linux-2.5/arch/ppc64/mm/stab.c~cpu-has-feature 2005-02-05 11:11:03.704583064 -0600 +++ linux-2.5-olof/arch/ppc64/mm/stab.c 2005-02-05 11:11:04.125519072 -0600 @@ -227,7 +227,7 @@ void stab_initialize(unsigned long stab) { unsigned long vsid = get_kernel_vsid(KERNELBASE); - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { + if (cpu_has_feature(CPU_FTR_SLB)) { slb_initialize(); } else { asm volatile("isync; slbia; isync":::"memory"); diff -puN arch/ppc64/oprofile/op_model_power4.c~cpu-has-feature arch/ppc64/oprofile/op_model_power4.c --- linux-2.5/arch/ppc64/oprofile/op_model_power4.c~cpu-has-feature 2005-02-05 11:11:03.764573944 -0600 +++ linux-2.5-olof/arch/ppc64/oprofile/op_model_power4.c 2005-02-05 11:11:04.126518920 -0600 @@ -54,7 +54,7 @@ static void power4_reg_setup(struct op_c * * It has been verified to work on POWER5 so we enable it there. */ - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA_SIHV) + if (cpu_has_feature(CPU_FTR_MMCRA_SIHV)) mmcra_has_sihv = 1; /* diff -puN arch/ppc64/oprofile/op_model_rs64.c~cpu-has-feature arch/ppc64/oprofile/op_model_rs64.c --- linux-2.5/arch/ppc64/oprofile/op_model_rs64.c~cpu-has-feature 2005-02-05 11:11:03.768573336 -0600 +++ linux-2.5-olof/arch/ppc64/oprofile/op_model_rs64.c 2005-02-05 11:11:04.126518920 -0600 @@ -114,7 +114,7 @@ static void rs64_cpu_setup(void *unused) /* reset MMCR1, MMCRA */ mtspr(SPRN_MMCR1, 0); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (cpu_has_feature(CPU_FTR_MMCRA)) mtspr(SPRN_MMCRA, 0); mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE; diff -puN arch/ppc64/xmon/xmon.c~cpu-has-feature arch/ppc64/xmon/xmon.c --- linux-2.5/arch/ppc64/xmon/xmon.c~cpu-has-feature 2005-02-05 11:11:03.814566344 -0600 +++ linux-2.5-olof/arch/ppc64/xmon/xmon.c 2005-02-05 11:11:04.128518616 -0600 @@ -723,7 +723,7 @@ static void insert_cpu_bpts(void) { if (dabr.enabled) set_controlled_dabr(dabr.address | (dabr.enabled & 7)); - if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR)) + if (iabr && cpu_has_feature(CPU_FTR_IABR)) set_iabr(iabr->address | (iabr->enabled & (BP_IABR|BP_IABR_TE))); } @@ -751,7 +751,7 @@ static void remove_bpts(void) static void remove_cpu_bpts(void) { set_controlled_dabr(0); - if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR)) + if (cpu_has_feature(CPU_FTR_IABR)) set_iabr(0); } @@ -1098,7 +1098,7 @@ bpt_cmds(void) break; case 'i': /* bi - hardware instr breakpoint */ - if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) { + if (!cpu_has_feature(CPU_FTR_IABR)) { printf("Hardware instruction breakpoint " "not supported on this cpu\n"); break; @@ -2496,7 +2496,7 @@ void xmon_init(void) void dump_segments(void) { - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (cpu_has_feature(CPU_FTR_SLB)) dump_slb(); else dump_stab(); diff -puN include/asm-ppc64/cacheflush.h~cpu-has-feature include/asm-ppc64/cacheflush.h --- linux-2.5/include/asm-ppc64/cacheflush.h~cpu-has-feature 2005-02-05 11:11:03.836563000 -0600 +++ linux-2.5-olof/include/asm-ppc64/cacheflush.h 2005-02-05 11:11:04.129518464 -0600 @@ -40,7 +40,7 @@ extern void __flush_dcache_icache(void * static inline void flush_icache_range(unsigned long start, unsigned long stop) { - if (!(cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE)) + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) __flush_icache_range(start, stop); } diff -puN include/asm-ppc64/mmu_context.h~cpu-has-feature include/asm-ppc64/mmu_context.h --- linux-2.5/include/asm-ppc64/mmu_context.h~cpu-has-feature 2005-02-05 11:11:03.841562240 -0600 +++ linux-2.5-olof/include/asm-ppc64/mmu_context.h 2005-02-05 11:11:04.129518464 -0600 @@ -59,11 +59,11 @@ static inline void switch_mm(struct mm_s return; #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) asm volatile ("dssall"); #endif /* CONFIG_ALTIVEC */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (cpu_has_feature(CPU_FTR_SLB)) switch_slb(tsk, next); else switch_stab(tsk, next); diff -puN include/asm-ppc64/page.h~cpu-has-feature include/asm-ppc64/page.h --- linux-2.5/include/asm-ppc64/page.h~cpu-has-feature 2005-02-05 11:11:03.845561632 -0600 +++ linux-2.5-olof/include/asm-ppc64/page.h 2005-02-05 11:11:04.130518312 -0600 @@ -67,7 +67,7 @@ #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #define in_hugepage_area(context, addr) \ - ((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) && \ + (cpu_has_feature(CPU_FTR_16M_PAGE) && \ ( (((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \ ( ((addr) < 0x100000000L) && \ ((1 << GET_ESID(addr)) & (context).htlb_segs) ) ) ) diff -puN arch/ppc64/kernel/pSeries_lpar.c~cpu-has-feature arch/ppc64/kernel/pSeries_lpar.c --- linux-2.5/arch/ppc64/kernel/pSeries_lpar.c~cpu-has-feature 2005-02-05 11:11:03.848561176 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/pSeries_lpar.c 2005-02-05 11:11:04.130518312 -0600 @@ -505,7 +505,7 @@ void pSeries_lpar_flush_hash_range(unsig int i; unsigned long flags = 0; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (lock_tlbie) spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); diff -puN arch/ppc64/kernel/setup.c~cpu-has-feature arch/ppc64/kernel/setup.c --- linux-2.5/arch/ppc64/kernel/setup.c~cpu-has-feature 2005-02-05 11:11:03.853560416 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/setup.c 2005-02-05 11:11:04.132518008 -0600 @@ -315,7 +315,7 @@ static void __init setup_cpu_maps(void) maxcpus = ireg[num_addr_cell + num_size_cell]; /* Double maxcpus for processors which have SMT capability */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) maxcpus *= 2; if (maxcpus > NR_CPUS) { @@ -339,7 +339,7 @@ static void __init setup_cpu_maps(void) */ for_each_cpu(cpu) { cpu_set(cpu, cpu_sibling_map[cpu]); - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); } @@ -767,7 +767,7 @@ static int show_cpuinfo(struct seq_file seq_printf(m, "unknown (%08x)", pvr); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) seq_printf(m, ", altivec supported"); #endif /* CONFIG_ALTIVEC */ diff -puN drivers/macintosh/via-pmu.c~cpu-has-feature drivers/macintosh/via-pmu.c --- linux-2.5/drivers/macintosh/via-pmu.c~cpu-has-feature 2005-02-05 11:11:03.895554032 -0600 +++ linux-2.5-olof/drivers/macintosh/via-pmu.c 2005-02-05 11:11:04.134517704 -0600 @@ -2389,7 +2389,7 @@ pmac_suspend_devices(void) enable_kernel_fp(); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) enable_kernel_altivec(); #endif /* CONFIG_ALTIVEC */ diff -puN include/asm-ppc/cputable.h~cpu-has-feature include/asm-ppc/cputable.h --- linux-2.5/include/asm-ppc/cputable.h~cpu-has-feature 2005-02-05 11:11:03.919550384 -0600 +++ linux-2.5-olof/include/asm-ppc/cputable.h 2005-02-05 11:22:58.928852448 -0600 @@ -61,6 +61,11 @@ struct cpu_spec { extern struct cpu_spec cpu_specs[]; extern struct cpu_spec *cur_cpu_spec[]; +static inline unsigned int cpu_has_feature(feature) +{ + return cur_cpu_spec[0]->cpu_features & feature; +} + #endif /* __ASSEMBLY__ */ /* CPU kernel features */ diff -puN arch/ppc/mm/ppc_mmu.c~cpu-has-feature arch/ppc/mm/ppc_mmu.c --- linux-2.5/arch/ppc/mm/ppc_mmu.c~cpu-has-feature 2005-02-05 11:11:03.976541720 -0600 +++ linux-2.5-olof/arch/ppc/mm/ppc_mmu.c 2005-02-05 11:11:04.136517400 -0600 @@ -138,7 +138,7 @@ void __init setbat(int index, unsigned l union ubat *bat = BATS[index]; if (((flags & _PAGE_NO_CACHE) == 0) && - (cur_cpu_spec[0]->cpu_features & CPU_FTR_NEED_COHERENT)) + cpu_has_feature(CPU_FTR_NEED_COHERENT)) flags |= _PAGE_COHERENT; bl = (size >> 17) - 1; @@ -191,7 +191,7 @@ void __init MMU_init_hw(void) extern unsigned int hash_page[]; extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[]; - if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0) { + if (!cpu_has_feature(CPU_FTR_HPTE_TABLE)) { /* * Put a blr (procedure return) instruction at the * start of hash_page, since we can still get DSI diff -puN arch/ppc/mm/mmu_decl.h~cpu-has-feature arch/ppc/mm/mmu_decl.h --- linux-2.5/arch/ppc/mm/mmu_decl.h~cpu-has-feature 2005-02-05 11:11:03.979541264 -0600 +++ linux-2.5-olof/arch/ppc/mm/mmu_decl.h 2005-02-05 11:11:04.136517400 -0600 @@ -75,7 +75,7 @@ static inline void flush_HPTE(unsigned c unsigned long pdval) { if ((Hash != 0) && - (cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE)) + cpu_has_feature(CPU_FTR_HPTE_TABLE)) flush_hash_pages(0, va, pdval, 1); else _tlbie(va); diff -puN arch/ppc/kernel/setup.c~cpu-has-feature arch/ppc/kernel/setup.c --- linux-2.5/arch/ppc/kernel/setup.c~cpu-has-feature 2005-02-05 11:11:04.018535336 -0600 +++ linux-2.5-olof/arch/ppc/kernel/setup.c 2005-02-05 11:11:04.137517248 -0600 @@ -619,7 +619,7 @@ machine_init(unsigned long r3, unsigned /* Checks "l2cr=xxxx" command-line option */ int __init ppc_setup_l2cr(char *str) { - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { + if (cpu_has_feature(CPU_FTR_L2CR)) { unsigned long val = simple_strtoul(str, NULL, 0); printk(KERN_INFO "l2cr set to %lx\n", val); _set_L2CR(0); /* force invalidate by disable cache */ @@ -720,7 +720,7 @@ void __init setup_arch(char **cmdline_p) * Systems with OF can look in the properties on the cpu node(s) * for a possibly more accurate value. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPLIT_ID_CACHE) { + if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { dcache_bsize = cur_cpu_spec[0]->dcache_bsize; icache_bsize = cur_cpu_spec[0]->icache_bsize; ucache_bsize = 0; diff -puN arch/ppc/kernel/temp.c~cpu-has-feature arch/ppc/kernel/temp.c --- linux-2.5/arch/ppc/kernel/temp.c~cpu-has-feature 2005-02-05 11:11:04.024534424 -0600 +++ linux-2.5-olof/arch/ppc/kernel/temp.c 2005-02-05 11:11:04.137517248 -0600 @@ -223,7 +223,7 @@ int __init TAU_init(void) /* We assume in SMP that if one CPU has TAU support, they * all have it --BenH */ - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_TAU)) { + if (!cpu_has_feature(CPU_FTR_TAU)) { printk("Thermal assist unit not available\n"); tau_initialized = 0; return 1; diff -puN arch/ppc/platforms/pmac_cpufreq.c~cpu-has-feature arch/ppc/platforms/pmac_cpufreq.c --- linux-2.5/arch/ppc/platforms/pmac_cpufreq.c~cpu-has-feature 2005-02-05 11:11:04.064528344 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_cpufreq.c 2005-02-05 11:11:04.138517096 -0600 @@ -230,7 +230,7 @@ static int __pmac pmu_set_cpu_speed(int enable_kernel_fp(); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) enable_kernel_altivec(); #endif /* CONFIG_ALTIVEC */ diff -puN arch/ppc/platforms/pmac_setup.c~cpu-has-feature arch/ppc/platforms/pmac_setup.c --- linux-2.5/arch/ppc/platforms/pmac_setup.c~cpu-has-feature 2005-02-05 11:11:04.068527736 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_setup.c 2005-02-05 11:11:04.139516944 -0600 @@ -274,7 +274,7 @@ pmac_setup_arch(void) pmac_find_bridges(); /* Checks "l2cr-value" property in the registry */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { + if (cpu_has_feature(CPU_FTR_L2CR)) { struct device_node *np = find_devices("cpus"); if (np == 0) np = find_type_devices("cpu"); diff -puN arch/ppc/platforms/pmac_smp.c~cpu-has-feature arch/ppc/platforms/pmac_smp.c --- linux-2.5/arch/ppc/platforms/pmac_smp.c~cpu-has-feature 2005-02-05 11:11:04.071527280 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_smp.c 2005-02-05 11:11:04.139516944 -0600 @@ -119,7 +119,7 @@ static volatile int sec_tb_reset = 0; static void __init core99_init_caches(int cpu) { - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) + if (!cpu_has_feature(CPU_FTR_L2CR)) return; if (cpu == 0) { @@ -132,7 +132,7 @@ static void __init core99_init_caches(in printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); } - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)) + if (!cpu_has_feature(CPU_FTR_L3CR)) return; if (cpu == 0){ diff -puN arch/ppc/platforms/sandpoint.c~cpu-has-feature arch/ppc/platforms/sandpoint.c --- linux-2.5/arch/ppc/platforms/sandpoint.c~cpu-has-feature 2005-02-05 11:11:04.074526824 -0600 +++ linux-2.5-olof/arch/ppc/platforms/sandpoint.c 2005-02-05 11:11:04.140516792 -0600 @@ -319,10 +319,10 @@ sandpoint_setup_arch(void) * We will do this now with good known values. Future versions * of DINK32 are supposed to get this correct. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) + if (cpu_has_feature(CPU_FTR_SPEC7450)) /* 745x is different. We only want to pass along enable. */ _set_L2CR(L2CR_L2E); - else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) + else if (cpu_has_feature(CPU_FTR_L2CR)) /* All modules have 1MB of L2. We also assume that an * L2 divisor of 3 will work. */ @@ -330,7 +330,7 @@ sandpoint_setup_arch(void) | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF); #if 0 /* Untested right now. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR) { + if (cpu_has_feature(CPU_FTR_L3CR)) { /* Magic value. */ _set_L3CR(0x8f032000); } diff -puN arch/ppc/kernel/ppc_htab.c~cpu-has-feature arch/ppc/kernel/ppc_htab.c --- linux-2.5/arch/ppc/kernel/ppc_htab.c~cpu-has-feature 2005-02-05 11:11:04.077526368 -0600 +++ linux-2.5-olof/arch/ppc/kernel/ppc_htab.c 2005-02-05 11:11:04.141516640 -0600 @@ -108,7 +108,7 @@ static int ppc_htab_show(struct seq_file PTE *ptr; #endif /* CONFIG_PPC_STD_MMU */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { + if (cpu_has_feature(CPU_FTR_604_PERF_MON)) { mmcr0 = mfspr(SPRN_MMCR0); pmc1 = mfspr(SPRN_PMC1); pmc2 = mfspr(SPRN_PMC2); @@ -209,7 +209,7 @@ static ssize_t ppc_htab_write(struct fil if ( !strncmp( buffer, "reset", 5) ) { - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { + if (cpu_has_feature(CPU_FTR_604_PERF_MON)) { /* reset PMC1 and PMC2 */ mtspr(SPRN_PMC1, 0); mtspr(SPRN_PMC2, 0); @@ -221,7 +221,7 @@ static ssize_t ppc_htab_write(struct fil } /* Everything below here requires the performance monitor feature. */ - if ( !cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON ) + if (!cpu_has_feature(CPU_FTR_604_PERF_MON)) return count; /* turn off performance monitoring */ @@ -339,7 +339,7 @@ int proc_dol2crvec(ctl_table *table, int "0.5", "1.0", "(reserved2)", "(reserved3)" }; - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) + if (!cpu_has_feature(CPU_FTR_L2CR)) return -EFAULT; if ( /*!table->maxlen ||*/ (*ppos && !write)) { diff -puN drivers/md/raid6altivec.uc~cpu-has-feature drivers/md/raid6altivec.uc --- linux-2.5/drivers/md/raid6altivec.uc~cpu-has-feature 2005-02-05 11:11:04.081525760 -0600 +++ linux-2.5-olof/drivers/md/raid6altivec.uc 2005-02-05 11:11:05.007385008 -0600 @@ -108,7 +108,7 @@ int raid6_have_altivec(void); int raid6_have_altivec(void) { /* This assumes either all CPUs have Altivec or none does */ - return cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC; + return cpu_has_feature(CPU_FTR_ALTIVEC): } #endif _ From olof at austin.ibm.com Sun Feb 6 14:26:45 2005 From: olof at austin.ibm.com (Olof Johansson) Date: Sat, 5 Feb 2005 21:26:45 -0600 Subject: [PATCH] PPC/PPC64: Abstract cpu_feature checks. In-Reply-To: <20050205184647.GA17417@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> <20050205184647.GA17417@austin.ibm.com> Message-ID: <20050206032645.GA18845@austin.ibm.com> Doh, forgot to do a final refpatch after fixing build error. I blame it on lack of morning coffee. Here's a proper version: Abstract most manual mask checks of cpu_features with cpu_has_feature() Signed-off-by: Olof Johansson --- linux-2.5-olof/arch/ppc/kernel/ppc_htab.c | 8 +++--- linux-2.5-olof/arch/ppc/kernel/setup.c | 4 +-- linux-2.5-olof/arch/ppc/kernel/temp.c | 2 - linux-2.5-olof/arch/ppc/mm/mmu_decl.h | 2 - linux-2.5-olof/arch/ppc/mm/ppc_mmu.c | 4 +-- linux-2.5-olof/arch/ppc/platforms/pmac_cpufreq.c | 2 - linux-2.5-olof/arch/ppc/platforms/pmac_setup.c | 2 - linux-2.5-olof/arch/ppc/platforms/pmac_smp.c | 4 +-- linux-2.5-olof/arch/ppc/platforms/sandpoint.c | 6 ++--- linux-2.5-olof/arch/ppc64/kernel/align.c | 2 - linux-2.5-olof/arch/ppc64/kernel/iSeries_setup.c | 2 - linux-2.5-olof/arch/ppc64/kernel/pSeries_lpar.c | 2 - linux-2.5-olof/arch/ppc64/kernel/process.c | 4 +-- linux-2.5-olof/arch/ppc64/kernel/setup.c | 6 ++--- linux-2.5-olof/arch/ppc64/kernel/smp.c | 2 - linux-2.5-olof/arch/ppc64/kernel/sysfs.c | 22 +++++++++---------- linux-2.5-olof/arch/ppc64/mm/hash_native.c | 14 ++++++------ linux-2.5-olof/arch/ppc64/mm/hash_utils.c | 2 - linux-2.5-olof/arch/ppc64/mm/hugetlbpage.c | 2 - linux-2.5-olof/arch/ppc64/mm/init.c | 10 ++++---- linux-2.5-olof/arch/ppc64/mm/slb.c | 4 +-- linux-2.5-olof/arch/ppc64/mm/stab.c | 2 - linux-2.5-olof/arch/ppc64/oprofile/op_model_power4.c | 2 - linux-2.5-olof/arch/ppc64/oprofile/op_model_rs64.c | 2 - linux-2.5-olof/arch/ppc64/xmon/xmon.c | 8 +++--- linux-2.5-olof/drivers/macintosh/via-pmu.c | 2 - linux-2.5-olof/drivers/md/raid6altivec.uc | 2 - linux-2.5-olof/include/asm-ppc/cputable.h | 5 ++++ linux-2.5-olof/include/asm-ppc64/cacheflush.h | 2 - linux-2.5-olof/include/asm-ppc64/cputable.h | 5 ++++ linux-2.5-olof/include/asm-ppc64/mmu_context.h | 4 +-- linux-2.5-olof/include/asm-ppc64/page.h | 2 - 32 files changed, 76 insertions(+), 66 deletions(-) diff -puN include/asm-ppc64/cputable.h~cpu-has-feature include/asm-ppc64/cputable.h --- linux-2.5/include/asm-ppc64/cputable.h~cpu-has-feature 2005-02-05 11:11:03.478617416 -0600 +++ linux-2.5-olof/include/asm-ppc64/cputable.h 2005-02-05 21:14:05.873057376 -0600 @@ -66,6 +66,11 @@ struct cpu_spec { extern struct cpu_spec cpu_specs[]; extern struct cpu_spec *cur_cpu_spec; +static inline unsigned long cpu_has_feature(unsigned long feature) +{ + return cur_cpu_spec->cpu_features & feature; +} + /* firmware feature bitmask values */ #define FIRMWARE_MAX_FEATURES 63 diff -puN arch/ppc64/kernel/align.c~cpu-has-feature arch/ppc64/kernel/align.c --- linux-2.5/arch/ppc64/kernel/align.c~cpu-has-feature 2005-02-05 11:11:03.521610880 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/align.c 2005-02-05 11:11:04.117520288 -0600 @@ -238,7 +238,7 @@ fix_alignment(struct pt_regs *regs) dsisr = regs->dsisr; - if (cur_cpu_spec->cpu_features & CPU_FTR_NODSISRALIGN) { + if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) { unsigned int real_instr; if (__get_user(real_instr, (unsigned int __user *)regs->nip)) return 0; diff -puN arch/ppc64/kernel/iSeries_setup.c~cpu-has-feature arch/ppc64/kernel/iSeries_setup.c --- linux-2.5/arch/ppc64/kernel/iSeries_setup.c~cpu-has-feature 2005-02-05 11:11:03.525610272 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/iSeries_setup.c 2005-02-05 11:11:04.118520136 -0600 @@ -267,7 +267,7 @@ unsigned long iSeries_process_mainstore_ unsigned long i; unsigned long mem_blocks = 0; - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (cpu_has_feature(CPU_FTR_SLB)) mem_blocks = iSeries_process_Regatta_mainstore_vpd(mb_array, max_entries); else diff -puN arch/ppc64/kernel/idle.c~cpu-has-feature arch/ppc64/kernel/idle.c diff -puN arch/ppc64/kernel/process.c~cpu-has-feature arch/ppc64/kernel/process.c --- linux-2.5/arch/ppc64/kernel/process.c~cpu-has-feature 2005-02-05 11:11:03.600598872 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/process.c 2005-02-05 11:11:04.119519984 -0600 @@ -388,12 +388,12 @@ copy_thread(int nr, unsigned long clone_ kregs = (struct pt_regs *) sp; sp -= STACK_FRAME_OVERHEAD; p->thread.ksp = sp; - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { + if (cpu_has_feature(CPU_FTR_SLB)) { unsigned long sp_vsid = get_kernel_vsid(sp); sp_vsid <<= SLB_VSID_SHIFT; sp_vsid |= SLB_VSID_KERNEL; - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) sp_vsid |= SLB_VSID_L; p->thread.ksp_vsid = sp_vsid; diff -puN arch/ppc64/kernel/smp.c~cpu-has-feature arch/ppc64/kernel/smp.c --- linux-2.5/arch/ppc64/kernel/smp.c~cpu-has-feature 2005-02-05 11:11:03.606597960 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/smp.c 2005-02-05 11:11:04.120519832 -0600 @@ -416,7 +416,7 @@ int __devinit __cpu_up(unsigned int cpu) paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; - if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) { + if (!cpu_has_feature(CPU_FTR_SLB)) { void *tmp; /* maximum of 48 CPUs on machines with a segment table */ diff -puN arch/ppc64/kernel/sysfs.c~cpu-has-feature arch/ppc64/kernel/sysfs.c --- linux-2.5/arch/ppc64/kernel/sysfs.c~cpu-has-feature 2005-02-05 11:11:03.609597504 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/sysfs.c 2005-02-05 11:11:04.121519680 -0600 @@ -63,7 +63,7 @@ static int __init smt_setup(void) unsigned int *val; unsigned int cpu; - if (!cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (!cpu_has_feature(CPU_FTR_SMT)) return 1; options = find_path_device("/options"); @@ -86,7 +86,7 @@ static int __init setup_smt_snooze_delay unsigned int cpu; int snooze; - if (!cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (!cpu_has_feature(CPU_FTR_SMT)) return 1; smt_snooze_cmdline = 1; @@ -167,7 +167,7 @@ void ppc64_enable_pmcs(void) * On SMT machines we have to set the run latch in the ctrl register * in order to make PMC6 spin. */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) { + if (cpu_has_feature(CPU_FTR_SMT)) { ctrl = mfspr(CTRLF); ctrl |= RUNLATCH; mtspr(CTRLT, ctrl); @@ -266,7 +266,7 @@ static void register_cpu_online(unsigned struct sys_device *s = &c->sysdev; #ifndef CONFIG_PPC_ISERIES - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) sysdev_create_file(s, &attr_smt_snooze_delay); #endif @@ -275,7 +275,7 @@ static void register_cpu_online(unsigned sysdev_create_file(s, &attr_mmcr0); sysdev_create_file(s, &attr_mmcr1); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (cpu_has_feature(CPU_FTR_MMCRA)) sysdev_create_file(s, &attr_mmcra); sysdev_create_file(s, &attr_pmc1); @@ -285,12 +285,12 @@ static void register_cpu_online(unsigned sysdev_create_file(s, &attr_pmc5); sysdev_create_file(s, &attr_pmc6); - if (cur_cpu_spec->cpu_features & CPU_FTR_PMC8) { + if (cpu_has_feature(CPU_FTR_PMC8)) { sysdev_create_file(s, &attr_pmc7); sysdev_create_file(s, &attr_pmc8); } - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) sysdev_create_file(s, &attr_purr); } @@ -303,7 +303,7 @@ static void unregister_cpu_online(unsign BUG_ON(c->no_control); #ifndef CONFIG_PPC_ISERIES - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) sysdev_remove_file(s, &attr_smt_snooze_delay); #endif @@ -312,7 +312,7 @@ static void unregister_cpu_online(unsign sysdev_remove_file(s, &attr_mmcr0); sysdev_remove_file(s, &attr_mmcr1); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (cpu_has_feature(CPU_FTR_MMCRA)) sysdev_remove_file(s, &attr_mmcra); sysdev_remove_file(s, &attr_pmc1); @@ -322,12 +322,12 @@ static void unregister_cpu_online(unsign sysdev_remove_file(s, &attr_pmc5); sysdev_remove_file(s, &attr_pmc6); - if (cur_cpu_spec->cpu_features & CPU_FTR_PMC8) { + if (cpu_has_feature(CPU_FTR_PMC8)) { sysdev_remove_file(s, &attr_pmc7); sysdev_remove_file(s, &attr_pmc8); } - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) sysdev_remove_file(s, &attr_purr); } #endif /* CONFIG_HOTPLUG_CPU */ diff -puN arch/ppc64/mm/hash_native.c~cpu-has-feature arch/ppc64/mm/hash_native.c --- linux-2.5/arch/ppc64/mm/hash_native.c~cpu-has-feature 2005-02-05 11:11:03.653590816 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hash_native.c 2005-02-05 11:11:04.122519528 -0600 @@ -217,10 +217,10 @@ static long native_hpte_updatepp(unsigne } /* Ensure it is out of the tlb too */ - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) { tlbiel(va); } else { - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (lock_tlbie) spin_lock(&native_tlbie_lock); @@ -245,7 +245,7 @@ static void native_hpte_updateboltedpp(u unsigned long vsid, va, vpn, flags = 0; long slot; HPTE *hptep; - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); vsid = get_kernel_vsid(ea); va = (vsid << 28) | (ea & 0x0fffffff); @@ -273,7 +273,7 @@ static void native_hpte_invalidate(unsig Hpte_dword0 dw0; unsigned long avpn = va >> 23; unsigned long flags; - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (large) avpn &= ~0x1UL; @@ -292,7 +292,7 @@ static void native_hpte_invalidate(unsig } /* Invalidate the tlb */ - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) { tlbiel(va); } else { if (lock_tlbie) @@ -360,7 +360,7 @@ static void native_flush_hash_range(unsi j++; } - if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) { + if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) { asm volatile("ptesync":::"memory"); for (i = 0; i < j; i++) @@ -368,7 +368,7 @@ static void native_flush_hash_range(unsi asm volatile("ptesync":::"memory"); } else { - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (lock_tlbie) spin_lock(&native_tlbie_lock); diff -puN arch/ppc64/mm/hash_utils.c~cpu-has-feature arch/ppc64/mm/hash_utils.c --- linux-2.5/arch/ppc64/mm/hash_utils.c~cpu-has-feature 2005-02-05 11:11:03.656590360 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hash_utils.c 2005-02-05 11:11:04.123519376 -0600 @@ -190,7 +190,7 @@ void __init htab_initialize(void) * _NOT_ map it to avoid cache paradoxes as it's remapped non * cacheable later on */ - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) use_largepages = 1; /* create bolted the linear mapping in the hash table */ diff -puN arch/ppc64/mm/hugetlbpage.c~cpu-has-feature arch/ppc64/mm/hugetlbpage.c --- linux-2.5/arch/ppc64/mm/hugetlbpage.c~cpu-has-feature 2005-02-05 11:11:03.674587624 -0600 +++ linux-2.5-olof/arch/ppc64/mm/hugetlbpage.c 2005-02-05 11:11:04.123519376 -0600 @@ -705,7 +705,7 @@ unsigned long hugetlb_get_unmapped_area( if (len & ~HPAGE_MASK) return -EINVAL; - if (!(cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)) + if (!cpu_has_feature(CPU_FTR_16M_PAGE)) return -EINVAL; if (test_thread_flag(TIF_32BIT)) { diff -puN arch/ppc64/mm/init.c~cpu-has-feature arch/ppc64/mm/init.c --- linux-2.5/arch/ppc64/mm/init.c~cpu-has-feature 2005-02-05 11:11:03.680586712 -0600 +++ linux-2.5-olof/arch/ppc64/mm/init.c 2005-02-05 11:11:04.124519224 -0600 @@ -752,7 +752,7 @@ void __init mem_init(void) */ void flush_dcache_page(struct page *page) { - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) return; /* avoid an atomic op if possible */ if (test_bit(PG_arch_1, &page->flags)) @@ -763,7 +763,7 @@ void clear_user_page(void *page, unsigne { clear_page(page); - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) return; /* * We shouldnt have to do this, but some versions of glibc @@ -796,7 +796,7 @@ void copy_user_page(void *vto, void *vfr return; #endif - if (cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) return; /* avoid an atomic op if possible */ @@ -832,8 +832,8 @@ void update_mmu_cache(struct vm_area_str unsigned long flags; /* handle i-cache coherency */ - if (!(cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE) && - !(cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)) { + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && + !cpu_has_feature(CPU_FTR_NOEXECUTE)) { unsigned long pfn = pte_pfn(pte); if (pfn_valid(pfn)) { struct page *page = pfn_to_page(pfn); diff -puN arch/ppc64/mm/slb.c~cpu-has-feature arch/ppc64/mm/slb.c --- linux-2.5/arch/ppc64/mm/slb.c~cpu-has-feature 2005-02-05 11:11:03.683586256 -0600 +++ linux-2.5-olof/arch/ppc64/mm/slb.c 2005-02-05 11:11:04.125519072 -0600 @@ -51,7 +51,7 @@ static void slb_flush_and_rebolt(void) WARN_ON(!irqs_disabled()); - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) ksp_flags |= SLB_VSID_L; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); @@ -139,7 +139,7 @@ void slb_initialize(void) unsigned long flags = SLB_VSID_KERNEL; /* Invalidate the entire SLB (even slot 0) & all the ERATS */ - if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) flags |= SLB_VSID_L; asm volatile("isync":::"memory"); diff -puN arch/ppc64/mm/stab.c~cpu-has-feature arch/ppc64/mm/stab.c --- linux-2.5/arch/ppc64/mm/stab.c~cpu-has-feature 2005-02-05 11:11:03.704583064 -0600 +++ linux-2.5-olof/arch/ppc64/mm/stab.c 2005-02-05 11:11:04.125519072 -0600 @@ -227,7 +227,7 @@ void stab_initialize(unsigned long stab) { unsigned long vsid = get_kernel_vsid(KERNELBASE); - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { + if (cpu_has_feature(CPU_FTR_SLB)) { slb_initialize(); } else { asm volatile("isync; slbia; isync":::"memory"); diff -puN arch/ppc64/oprofile/op_model_power4.c~cpu-has-feature arch/ppc64/oprofile/op_model_power4.c --- linux-2.5/arch/ppc64/oprofile/op_model_power4.c~cpu-has-feature 2005-02-05 11:11:03.764573944 -0600 +++ linux-2.5-olof/arch/ppc64/oprofile/op_model_power4.c 2005-02-05 11:11:04.126518920 -0600 @@ -54,7 +54,7 @@ static void power4_reg_setup(struct op_c * * It has been verified to work on POWER5 so we enable it there. */ - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA_SIHV) + if (cpu_has_feature(CPU_FTR_MMCRA_SIHV)) mmcra_has_sihv = 1; /* diff -puN arch/ppc64/oprofile/op_model_rs64.c~cpu-has-feature arch/ppc64/oprofile/op_model_rs64.c --- linux-2.5/arch/ppc64/oprofile/op_model_rs64.c~cpu-has-feature 2005-02-05 11:11:03.768573336 -0600 +++ linux-2.5-olof/arch/ppc64/oprofile/op_model_rs64.c 2005-02-05 11:11:04.126518920 -0600 @@ -114,7 +114,7 @@ static void rs64_cpu_setup(void *unused) /* reset MMCR1, MMCRA */ mtspr(SPRN_MMCR1, 0); - if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA) + if (cpu_has_feature(CPU_FTR_MMCRA)) mtspr(SPRN_MMCRA, 0); mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE; diff -puN arch/ppc64/xmon/xmon.c~cpu-has-feature arch/ppc64/xmon/xmon.c --- linux-2.5/arch/ppc64/xmon/xmon.c~cpu-has-feature 2005-02-05 11:11:03.814566344 -0600 +++ linux-2.5-olof/arch/ppc64/xmon/xmon.c 2005-02-05 11:11:04.128518616 -0600 @@ -723,7 +723,7 @@ static void insert_cpu_bpts(void) { if (dabr.enabled) set_controlled_dabr(dabr.address | (dabr.enabled & 7)); - if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR)) + if (iabr && cpu_has_feature(CPU_FTR_IABR)) set_iabr(iabr->address | (iabr->enabled & (BP_IABR|BP_IABR_TE))); } @@ -751,7 +751,7 @@ static void remove_bpts(void) static void remove_cpu_bpts(void) { set_controlled_dabr(0); - if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR)) + if (cpu_has_feature(CPU_FTR_IABR)) set_iabr(0); } @@ -1098,7 +1098,7 @@ bpt_cmds(void) break; case 'i': /* bi - hardware instr breakpoint */ - if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) { + if (!cpu_has_feature(CPU_FTR_IABR)) { printf("Hardware instruction breakpoint " "not supported on this cpu\n"); break; @@ -2496,7 +2496,7 @@ void xmon_init(void) void dump_segments(void) { - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (cpu_has_feature(CPU_FTR_SLB)) dump_slb(); else dump_stab(); diff -puN include/asm-ppc64/cacheflush.h~cpu-has-feature include/asm-ppc64/cacheflush.h --- linux-2.5/include/asm-ppc64/cacheflush.h~cpu-has-feature 2005-02-05 11:11:03.836563000 -0600 +++ linux-2.5-olof/include/asm-ppc64/cacheflush.h 2005-02-05 11:11:04.129518464 -0600 @@ -40,7 +40,7 @@ extern void __flush_dcache_icache(void * static inline void flush_icache_range(unsigned long start, unsigned long stop) { - if (!(cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE)) + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) __flush_icache_range(start, stop); } diff -puN include/asm-ppc64/mmu_context.h~cpu-has-feature include/asm-ppc64/mmu_context.h --- linux-2.5/include/asm-ppc64/mmu_context.h~cpu-has-feature 2005-02-05 11:11:03.841562240 -0600 +++ linux-2.5-olof/include/asm-ppc64/mmu_context.h 2005-02-05 11:11:04.129518464 -0600 @@ -59,11 +59,11 @@ static inline void switch_mm(struct mm_s return; #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) asm volatile ("dssall"); #endif /* CONFIG_ALTIVEC */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) + if (cpu_has_feature(CPU_FTR_SLB)) switch_slb(tsk, next); else switch_stab(tsk, next); diff -puN include/asm-ppc64/page.h~cpu-has-feature include/asm-ppc64/page.h --- linux-2.5/include/asm-ppc64/page.h~cpu-has-feature 2005-02-05 11:11:03.845561632 -0600 +++ linux-2.5-olof/include/asm-ppc64/page.h 2005-02-05 11:11:04.130518312 -0600 @@ -67,7 +67,7 @@ #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #define in_hugepage_area(context, addr) \ - ((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) && \ + (cpu_has_feature(CPU_FTR_16M_PAGE) && \ ( (((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \ ( ((addr) < 0x100000000L) && \ ((1 << GET_ESID(addr)) & (context).htlb_segs) ) ) ) diff -puN arch/ppc64/kernel/pSeries_lpar.c~cpu-has-feature arch/ppc64/kernel/pSeries_lpar.c --- linux-2.5/arch/ppc64/kernel/pSeries_lpar.c~cpu-has-feature 2005-02-05 11:11:03.848561176 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/pSeries_lpar.c 2005-02-05 11:11:04.130518312 -0600 @@ -505,7 +505,7 @@ void pSeries_lpar_flush_hash_range(unsig int i; unsigned long flags = 0; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); - int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE); + int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); if (lock_tlbie) spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); diff -puN arch/ppc64/kernel/setup.c~cpu-has-feature arch/ppc64/kernel/setup.c --- linux-2.5/arch/ppc64/kernel/setup.c~cpu-has-feature 2005-02-05 11:11:03.853560416 -0600 +++ linux-2.5-olof/arch/ppc64/kernel/setup.c 2005-02-05 11:11:04.132518008 -0600 @@ -315,7 +315,7 @@ static void __init setup_cpu_maps(void) maxcpus = ireg[num_addr_cell + num_size_cell]; /* Double maxcpus for processors which have SMT capability */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) maxcpus *= 2; if (maxcpus > NR_CPUS) { @@ -339,7 +339,7 @@ static void __init setup_cpu_maps(void) */ for_each_cpu(cpu) { cpu_set(cpu, cpu_sibling_map[cpu]); - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + if (cpu_has_feature(CPU_FTR_SMT)) cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); } @@ -767,7 +767,7 @@ static int show_cpuinfo(struct seq_file seq_printf(m, "unknown (%08x)", pvr); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) seq_printf(m, ", altivec supported"); #endif /* CONFIG_ALTIVEC */ diff -puN drivers/macintosh/via-pmu.c~cpu-has-feature drivers/macintosh/via-pmu.c --- linux-2.5/drivers/macintosh/via-pmu.c~cpu-has-feature 2005-02-05 11:11:03.895554032 -0600 +++ linux-2.5-olof/drivers/macintosh/via-pmu.c 2005-02-05 11:11:04.134517704 -0600 @@ -2389,7 +2389,7 @@ pmac_suspend_devices(void) enable_kernel_fp(); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) enable_kernel_altivec(); #endif /* CONFIG_ALTIVEC */ diff -puN include/asm-ppc/cputable.h~cpu-has-feature include/asm-ppc/cputable.h --- linux-2.5/include/asm-ppc/cputable.h~cpu-has-feature 2005-02-05 11:11:03.919550384 -0600 +++ linux-2.5-olof/include/asm-ppc/cputable.h 2005-02-05 21:14:25.443082280 -0600 @@ -61,6 +61,11 @@ struct cpu_spec { extern struct cpu_spec cpu_specs[]; extern struct cpu_spec *cur_cpu_spec[]; +static inline unsigned int cpu_has_feature(unsigned int feature) +{ + return cur_cpu_spec[0]->cpu_features & feature; +} + #endif /* __ASSEMBLY__ */ /* CPU kernel features */ diff -puN arch/ppc/mm/ppc_mmu.c~cpu-has-feature arch/ppc/mm/ppc_mmu.c --- linux-2.5/arch/ppc/mm/ppc_mmu.c~cpu-has-feature 2005-02-05 11:11:03.976541720 -0600 +++ linux-2.5-olof/arch/ppc/mm/ppc_mmu.c 2005-02-05 11:11:04.136517400 -0600 @@ -138,7 +138,7 @@ void __init setbat(int index, unsigned l union ubat *bat = BATS[index]; if (((flags & _PAGE_NO_CACHE) == 0) && - (cur_cpu_spec[0]->cpu_features & CPU_FTR_NEED_COHERENT)) + cpu_has_feature(CPU_FTR_NEED_COHERENT)) flags |= _PAGE_COHERENT; bl = (size >> 17) - 1; @@ -191,7 +191,7 @@ void __init MMU_init_hw(void) extern unsigned int hash_page[]; extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[]; - if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0) { + if (!cpu_has_feature(CPU_FTR_HPTE_TABLE)) { /* * Put a blr (procedure return) instruction at the * start of hash_page, since we can still get DSI diff -puN arch/ppc/mm/mmu_decl.h~cpu-has-feature arch/ppc/mm/mmu_decl.h --- linux-2.5/arch/ppc/mm/mmu_decl.h~cpu-has-feature 2005-02-05 11:11:03.979541264 -0600 +++ linux-2.5-olof/arch/ppc/mm/mmu_decl.h 2005-02-05 11:11:04.136517400 -0600 @@ -75,7 +75,7 @@ static inline void flush_HPTE(unsigned c unsigned long pdval) { if ((Hash != 0) && - (cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE)) + cpu_has_feature(CPU_FTR_HPTE_TABLE)) flush_hash_pages(0, va, pdval, 1); else _tlbie(va); diff -puN arch/ppc/kernel/setup.c~cpu-has-feature arch/ppc/kernel/setup.c --- linux-2.5/arch/ppc/kernel/setup.c~cpu-has-feature 2005-02-05 11:11:04.018535336 -0600 +++ linux-2.5-olof/arch/ppc/kernel/setup.c 2005-02-05 11:11:04.137517248 -0600 @@ -619,7 +619,7 @@ machine_init(unsigned long r3, unsigned /* Checks "l2cr=xxxx" command-line option */ int __init ppc_setup_l2cr(char *str) { - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { + if (cpu_has_feature(CPU_FTR_L2CR)) { unsigned long val = simple_strtoul(str, NULL, 0); printk(KERN_INFO "l2cr set to %lx\n", val); _set_L2CR(0); /* force invalidate by disable cache */ @@ -720,7 +720,7 @@ void __init setup_arch(char **cmdline_p) * Systems with OF can look in the properties on the cpu node(s) * for a possibly more accurate value. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPLIT_ID_CACHE) { + if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { dcache_bsize = cur_cpu_spec[0]->dcache_bsize; icache_bsize = cur_cpu_spec[0]->icache_bsize; ucache_bsize = 0; diff -puN arch/ppc/kernel/temp.c~cpu-has-feature arch/ppc/kernel/temp.c --- linux-2.5/arch/ppc/kernel/temp.c~cpu-has-feature 2005-02-05 11:11:04.024534424 -0600 +++ linux-2.5-olof/arch/ppc/kernel/temp.c 2005-02-05 11:11:04.137517248 -0600 @@ -223,7 +223,7 @@ int __init TAU_init(void) /* We assume in SMP that if one CPU has TAU support, they * all have it --BenH */ - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_TAU)) { + if (!cpu_has_feature(CPU_FTR_TAU)) { printk("Thermal assist unit not available\n"); tau_initialized = 0; return 1; diff -puN arch/ppc/platforms/pmac_cpufreq.c~cpu-has-feature arch/ppc/platforms/pmac_cpufreq.c --- linux-2.5/arch/ppc/platforms/pmac_cpufreq.c~cpu-has-feature 2005-02-05 11:11:04.064528344 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_cpufreq.c 2005-02-05 11:11:04.138517096 -0600 @@ -230,7 +230,7 @@ static int __pmac pmu_set_cpu_speed(int enable_kernel_fp(); #ifdef CONFIG_ALTIVEC - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) enable_kernel_altivec(); #endif /* CONFIG_ALTIVEC */ diff -puN arch/ppc/platforms/pmac_setup.c~cpu-has-feature arch/ppc/platforms/pmac_setup.c --- linux-2.5/arch/ppc/platforms/pmac_setup.c~cpu-has-feature 2005-02-05 11:11:04.068527736 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_setup.c 2005-02-05 11:11:04.139516944 -0600 @@ -274,7 +274,7 @@ pmac_setup_arch(void) pmac_find_bridges(); /* Checks "l2cr-value" property in the registry */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { + if (cpu_has_feature(CPU_FTR_L2CR)) { struct device_node *np = find_devices("cpus"); if (np == 0) np = find_type_devices("cpu"); diff -puN arch/ppc/platforms/pmac_smp.c~cpu-has-feature arch/ppc/platforms/pmac_smp.c --- linux-2.5/arch/ppc/platforms/pmac_smp.c~cpu-has-feature 2005-02-05 11:11:04.071527280 -0600 +++ linux-2.5-olof/arch/ppc/platforms/pmac_smp.c 2005-02-05 11:11:04.139516944 -0600 @@ -119,7 +119,7 @@ static volatile int sec_tb_reset = 0; static void __init core99_init_caches(int cpu) { - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) + if (!cpu_has_feature(CPU_FTR_L2CR)) return; if (cpu == 0) { @@ -132,7 +132,7 @@ static void __init core99_init_caches(in printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); } - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)) + if (!cpu_has_feature(CPU_FTR_L3CR)) return; if (cpu == 0){ diff -puN arch/ppc/platforms/sandpoint.c~cpu-has-feature arch/ppc/platforms/sandpoint.c --- linux-2.5/arch/ppc/platforms/sandpoint.c~cpu-has-feature 2005-02-05 11:11:04.074526824 -0600 +++ linux-2.5-olof/arch/ppc/platforms/sandpoint.c 2005-02-05 11:11:04.140516792 -0600 @@ -319,10 +319,10 @@ sandpoint_setup_arch(void) * We will do this now with good known values. Future versions * of DINK32 are supposed to get this correct. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) + if (cpu_has_feature(CPU_FTR_SPEC7450)) /* 745x is different. We only want to pass along enable. */ _set_L2CR(L2CR_L2E); - else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) + else if (cpu_has_feature(CPU_FTR_L2CR)) /* All modules have 1MB of L2. We also assume that an * L2 divisor of 3 will work. */ @@ -330,7 +330,7 @@ sandpoint_setup_arch(void) | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF); #if 0 /* Untested right now. */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR) { + if (cpu_has_feature(CPU_FTR_L3CR)) { /* Magic value. */ _set_L3CR(0x8f032000); } diff -puN arch/ppc/kernel/ppc_htab.c~cpu-has-feature arch/ppc/kernel/ppc_htab.c --- linux-2.5/arch/ppc/kernel/ppc_htab.c~cpu-has-feature 2005-02-05 11:11:04.077526368 -0600 +++ linux-2.5-olof/arch/ppc/kernel/ppc_htab.c 2005-02-05 11:11:04.141516640 -0600 @@ -108,7 +108,7 @@ static int ppc_htab_show(struct seq_file PTE *ptr; #endif /* CONFIG_PPC_STD_MMU */ - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { + if (cpu_has_feature(CPU_FTR_604_PERF_MON)) { mmcr0 = mfspr(SPRN_MMCR0); pmc1 = mfspr(SPRN_PMC1); pmc2 = mfspr(SPRN_PMC2); @@ -209,7 +209,7 @@ static ssize_t ppc_htab_write(struct fil if ( !strncmp( buffer, "reset", 5) ) { - if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { + if (cpu_has_feature(CPU_FTR_604_PERF_MON)) { /* reset PMC1 and PMC2 */ mtspr(SPRN_PMC1, 0); mtspr(SPRN_PMC2, 0); @@ -221,7 +221,7 @@ static ssize_t ppc_htab_write(struct fil } /* Everything below here requires the performance monitor feature. */ - if ( !cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON ) + if (!cpu_has_feature(CPU_FTR_604_PERF_MON)) return count; /* turn off performance monitoring */ @@ -339,7 +339,7 @@ int proc_dol2crvec(ctl_table *table, int "0.5", "1.0", "(reserved2)", "(reserved3)" }; - if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) + if (!cpu_has_feature(CPU_FTR_L2CR)) return -EFAULT; if ( /*!table->maxlen ||*/ (*ppos && !write)) { diff -puN drivers/md/raid6altivec.uc~cpu-has-feature drivers/md/raid6altivec.uc --- linux-2.5/drivers/md/raid6altivec.uc~cpu-has-feature 2005-02-05 11:11:04.081525760 -0600 +++ linux-2.5-olof/drivers/md/raid6altivec.uc 2005-02-05 11:11:05.007385008 -0600 @@ -108,7 +108,7 @@ int raid6_have_altivec(void); int raid6_have_altivec(void) { /* This assumes either all CPUs have Altivec or none does */ - return cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC; + return cpu_has_feature(CPU_FTR_ALTIVEC): } #endif _ From miltonm at bga.com Sun Feb 6 19:10:55 2005 From: miltonm at bga.com (Milton Miller) Date: Sun, 6 Feb 2005 02:10:55 -0600 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline #2 In-Reply-To: <1107151447.5712.81.camel@gaston> References: <1107151447.5712.81.camel@gaston> Message-ID: <5fcc65f08b15fa6d1d69f75d7c4dc989@bga.com> Benjamin Herrenschmidt wrote: > Index: linux-work/arch/ppc64/kernel/vdso32/vdso32_wrapper.S > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ linux-work/arch/ppc64/kernel/vdso32/vdso32_wrapper.S > 2005-01-31 16:25:56.000000000 +1100 > @@ -0,0 +1,12 @@ > +#include > + > + .section ".data" > + > + .globl vdso32_start, vdso32_end > + .balign 4096 > +vdso32_start: > + .incbin "arch/ppc64/kernel/vdso32/vdso32.so" > + .balign 4096 > +vdso32_end: > + > + .previous > Index: linux-work/arch/ppc64/kernel/vdso64/vdso64_wrapper.S > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ linux-work/arch/ppc64/kernel/vdso64/vdso64_wrapper.S > 2005-01-31 16:25:56.000000000 +1100 > @@ -0,0 +1,12 @@ > +#include > + > + .section ".data" > + > + .globl vdso64_start, vdso64_end > + .balign 4096 > +vdso64_start: > + .incbin "arch/ppc64/kernel/vdso64/vdso64.so" > + .balign 4096 > +vdso64_end: > + > + .previous How about putting these with the other page_aligned data, with .section ".data.page_aligned" Also, I don't see anything from being used, although including to get PAGE_SIZE would elimintate the magic 4096 number. milton From benh at kernel.crashing.org Sun Feb 6 21:30:06 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Sun, 06 Feb 2005 21:30:06 +1100 Subject: [PATCH] ppc64: Implement a vDSO and use it for signal trampoline #2 In-Reply-To: <5fcc65f08b15fa6d1d69f75d7c4dc989@bga.com> References: <1107151447.5712.81.camel@gaston> <5fcc65f08b15fa6d1d69f75d7c4dc989@bga.com> Message-ID: <1107685806.30303.50.camel@gaston> On Sun, 2005-02-06 at 02:10 -0600, Milton Miller wrote: > How about putting these with the other page_aligned data, with > .section ".data.page_aligned" > > Also, I don't see anything from being used, although > including to get PAGE_SIZE would elimintate the magic > 4096 number. Good point. The wrapper is indeed normally linked with the rest of the kernel. This was quick and dirty stuff a bit overlooked, I'll fix it, thanks for noticing. Ben. From arnd at arndb.de Sun Feb 6 22:57:34 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Sun, 6 Feb 2005 12:57:34 +0100 Subject: [PATCH] PPC/PPC64: Abstract cpu_feature checks. In-Reply-To: <20050206032645.GA18845@austin.ibm.com> References: <20050204072254.GA17565@austin.ibm.com> <20050205184647.GA17417@austin.ibm.com> <20050206032645.GA18845@austin.ibm.com> Message-ID: <200502061257.40798.arnd@arndb.de> On S?nndag 06 Februar 2005 04:26, Olof Johansson wrote: > > Abstract most manual mask checks of cpu_features with cpu_has_feature() > ? Just to get back to the point of consistant naming: In case we do the other proposed changes as well, is everyone happy with the following function names? cpu_has_feature(CPU_FTR_X) cur_cpu_spec->cpu_features & CPU_FTR_X cpu_feature_possible(CPU_FTR_X) CPU_FTR_POSSIBLE_MASK & CPU_FTR_X fw_has_feature(FW_FEATURE_X) cur_cpu_spec->fw_features & FW_FTR_X platform_is(PLATFORM_X) systemcfg->platform == PLATFORM_X platform_possible(PLATFORM_X) PLATFORM_POSSIBLE_MASK & PLATFORM_X platform_compatible(PLATFORM_X) systemcfg->platform & PLATFORM_X It's not as consistant as I'd like it to be, but it's the best I could come up with. Arnd <>< -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050206/4abc4242/attachment.pgp From olh at suse.de Mon Feb 7 02:26:12 2005 From: olh at suse.de (Olaf Hering) Date: Sun, 6 Feb 2005 16:26:12 +0100 Subject: [PATCH] remove unneeded includes from pSeries_nvram.c Message-ID: <20050206152612.GA13354@suse.de> The pseries nvram driver started probably as a copy of nvram.c. These includes are not needed to build it. Signed-off-by: Olaf Hering diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc64/kernel/pSeries_nvram.c ./arch/ppc64/kernel/pSeries_nvram.c --- ../linux-2.6.11-rc3.orig/arch/ppc64/kernel/pSeries_nvram.c 2005-02-03 02:56:33.000000000 +0100 +++ ./arch/ppc64/kernel/pSeries_nvram.c 2005-02-06 14:57:23.000000000 +0100 @@ -11,14 +11,9 @@ * This perhaps should live in drivers/char */ -#include #include #include -#include -#include -#include -#include #include #include #include From olh at suse.de Mon Feb 7 02:28:11 2005 From: olh at suse.de (Olaf Hering) Date: Sun, 6 Feb 2005 16:28:11 +0100 Subject: [PATCH] hide plpar_hcall_norets call in xmon Message-ID: <20050206152811.GB13354@suse.de> plpar_hcall_norets() is only availbe if pseries is selected in .config. The maple defconfig doesnt build right now because it has xmon enabled. Signed-off-by: Olaf Hering diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc64/xmon/xmon.c ./arch/ppc64/xmon/xmon.c --- ../linux-2.6.11-rc3.orig/arch/ppc64/xmon/xmon.c 2005-02-03 02:56:35.000000000 +0100 +++ ./arch/ppc64/xmon/xmon.c 2005-02-06 15:44:50.643489636 +0100 @@ -629,9 +629,11 @@ int xmon_fault_handler(struct pt_regs *r static void set_controlled_dabr(unsigned long val) { if (systemcfg->platform == PLATFORM_PSERIES_LPAR) { +#ifdef CONFIG_PPC_PSERIES int rc = plpar_hcall_norets(H_SET_DABR, val); if (rc != H_Success) xmon_printf("Warning: setting DABR failed (%d)\n", rc); +#endif } else set_dabr(val); } From anton at samba.org Mon Feb 7 14:44:18 2005 From: anton at samba.org (Anton Blanchard) Date: Mon, 7 Feb 2005 14:44:18 +1100 Subject: Fix pseries hcall functions Message-ID: <20050207034418.GD5567@krispykreme.ozlabs.ibm.com> Hi, I had a look over our hcall functions and they are a bit of a mess. plpar_hcall_4out was corrupting r14 and they all did their own thing instead of following the ABI. How does this look? We no longer create a stack frame and save the required volatiles away in the parameter save area the caller set up. I also consolidated the duplicate HVSC definitions. Anton diff -puN arch/ppc64/kernel/pSeries_hvCall.S~fix_pseries_hcalls arch/ppc64/kernel/pSeries_hvCall.S --- foobar2/arch/ppc64/kernel/pSeries_hvCall.S~fix_pseries_hcalls 2005-01-30 13:51:35.800353154 +1100 +++ foobar2-anton/arch/ppc64/kernel/pSeries_hvCall.S 2005-01-30 14:23:02.535533536 +1100 @@ -1,7 +1,6 @@ /* * arch/ppc64/kernel/pSeries_hvCall.S * - * * This file contains the generic code to perform a call to the * pSeries LPAR hypervisor. * NOTE: this file will go away when we move to inline this work. @@ -11,133 +10,114 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include -#include -#include +#include #include -#include -#include #include -/* - * hcall interface to pSeries LPAR - */ -#define HVSC .long 0x44000022 - -/* long plpar_hcall(unsigned long opcode, R3 - unsigned long arg1, R4 - unsigned long arg2, R5 - unsigned long arg3, R6 - unsigned long arg4, R7 - unsigned long *out1, R8 - unsigned long *out2, R9 - unsigned long *out3); R10 - */ +#define STK_PARM(i) (48 + ((i)-3)*8) .text + +/* long plpar_hcall(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long *out1, R8 + unsigned long *out2, R9 + unsigned long *out3); R10 + */ _GLOBAL(plpar_hcall) mfcr r0 - std r0,-8(r1) - stdu r1,-32(r1) - std r8,-8(r1) /* Save out ptrs. */ - std r9,-16(r1) - std r10,-24(r1) - - HVSC /* invoke the hypervisor */ + std r8,STK_PARM(r8)(r1) /* Save out ptrs */ + std r9,STK_PARM(r9)(r1) + std r10,STK_PARM(r10)(r1) + + stw r0,8(r1) + + HVSC /* invoke the hypervisor */ + + lwz r0,8(r1) + + ld r8,STK_PARM(r8)(r1) /* Fetch r4-r6 ret args */ + ld r9,STK_PARM(r9)(r1) + ld r10,STK_PARM(r10)(r1) + std r4,0(r8) + std r5,0(r9) + std r6,0(r10) - ld r10,-8(r1) /* Fetch r4-r7 ret args. */ - std r4,0(r10) - ld r10,-16(r1) - std r5,0(r10) - ld r10,-24(r1) - std r6,0(r10) - - ld r1,0(r1) - ld r0,-8(r1) mtcrf 0xff,r0 - blr /* return r3 = status */ + blr /* return r3 = status */ /* Simple interface with no output values (other than status) */ _GLOBAL(plpar_hcall_norets) mfcr r0 - std r0,-8(r1) - HVSC /* invoke the hypervisor */ - ld r0,-8(r1) - mtcrf 0xff,r0 - blr /* return r3 = status */ + stw r0,8(r1) + HVSC /* invoke the hypervisor */ -/* long plpar_hcall_8arg_2ret(unsigned long opcode, R3 - unsigned long arg1, R4 - unsigned long arg2, R5 - unsigned long arg3, R6 - unsigned long arg4, R7 - unsigned long arg5, R8 - unsigned long arg6, R9 - unsigned long arg7, R10 - unsigned long arg8, 112(R1) - unsigned long *out1); 120(R1) + lwz r0,8(r1) + mtcrf 0xff,r0 + blr /* return r3 = status */ - */ - .text +/* long plpar_hcall_8arg_2ret(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long arg5, R8 + unsigned long arg6, R9 + unsigned long arg7, R10 + unsigned long arg8, 112(R1) + unsigned long *out1); 120(R1) + */ _GLOBAL(plpar_hcall_8arg_2ret) mfcr r0 + ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ + stw r0,8(r1) - ld r11, 112(r1) /* put arg8 and out1 in R11 and R12 */ - ld r12, 120(r1) - - std r0,-8(r1) - stdu r1,-32(r1) + HVSC /* invoke the hypervisor */ - std r12,-8(r1) /* Save out ptr */ - - HVSC /* invoke the hypervisor */ - - ld r10,-8(r1) /* Fetch r4 ret arg */ - std r4,0(r10) - - ld r1,0(r1) - ld r0,-8(r1) + lwz r0,8(r1) + ld r10,STK_PARM(r12)(r1) /* Fetch r4 ret arg */ + std r4,0(r10) mtcrf 0xff,r0 - blr /* return r3 = status */ + blr /* return r3 = status */ -/* long plpar_hcall_4out(unsigned long opcode, R3 - unsigned long arg1, R4 - unsigned long arg2, R5 - unsigned long arg3, R6 - unsigned long arg4, R7 - unsigned long *out1, (r4) R8 - unsigned long *out2, (r5) R9 - unsigned long *out3, (r6) R10 - unsigned long *out4); (r7) 112(R1). From Parameter save area. +/* long plpar_hcall_4out(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long *out1, R8 + unsigned long *out2, R9 + unsigned long *out3, R10 + unsigned long *out4); 112(R1) */ _GLOBAL(plpar_hcall_4out) mfcr r0 - std r0,-8(r1) - ld r14,112(r1) - stdu r1,-48(r1) - - std r8,32(r1) /* Save out ptrs. */ - std r9,24(r1) - std r10,16(r1) - std r14,8(r1) - - HVSC /* invoke the hypervisor */ + std r0,8(r1) - ld r14,32(r1) /* Fetch r4-r7 ret args. */ - std r4,0(r14) - ld r14,24(r1) - std r5,0(r14) - ld r14,16(r1) - std r6,0(r14) - ld r14,8(r1) - std r7,0(r14) + std r8,STK_PARM(r8)(r1) /* Save out ptrs */ + std r9,STK_PARM(r9)(r1) + std r10,STK_PARM(r10)(r1) + + HVSC /* invoke the hypervisor */ + + lwz r0,8(r1) + + ld r8,STK_PARM(r8)(r1) /* Fetch r4-r7 ret args */ + ld r9,STK_PARM(r9)(r1) + ld r10,STK_PARM(r10)(r1) + ld r11,STK_PARM(r11)(r1) + std r4,0(r8) + std r5,0(r9) + std r6,0(r10) + std r7,0(r11) - ld r1,0(r1) - ld r0,-8(r1) mtcrf 0xff,r0 - blr /* return r3 = status */ + blr /* return r3 = status */ diff -puN include/asm-ppc64/hvcall.h~fix_pseries_hcalls include/asm-ppc64/hvcall.h --- foobar2/include/asm-ppc64/hvcall.h~fix_pseries_hcalls 2005-01-30 13:54:53.163581752 +1100 +++ foobar2-anton/include/asm-ppc64/hvcall.h 2005-01-30 13:57:58.784771353 +1100 @@ -1,6 +1,8 @@ #ifndef _PPC64_HVCALL_H #define _PPC64_HVCALL_H +#define HVSC .long 0x44000022 + #define H_Success 0 #define H_Busy 1 /* Hardware busy -- retry later */ #define H_Constrained 4 /* Resource request constrained to max allowed */ @@ -41,7 +43,7 @@ /* Flags */ #define H_LARGE_PAGE (1UL<<(63-16)) -#define H_EXACT (1UL<<(63-24)) /* Use exact PTE or return H_PTEG_FULL */ +#define H_EXACT (1UL<<(63-24)) /* Use exact PTE or return H_PTEG_FULL */ #define H_R_XLATE (1UL<<(63-25)) /* include a valid logical page num in the pte if the valid bit is set */ #define H_READ_4 (1UL<<(63-26)) /* Return 4 PTEs */ #define H_AVPN (1UL<<(63-32)) /* An avpn is provided as a sanity test */ @@ -54,8 +56,6 @@ #define H_PP1 (1UL<<(63-62)) #define H_PP2 (1UL<<(63-63)) - - /* pSeries hypervisor opcodes */ #define H_REMOVE 0x04 #define H_ENTER 0x08 @@ -108,6 +108,8 @@ #define H_FREE_VTERM 0x158 #define H_POLL_PENDING 0x1D8 +#ifndef __ASSEMBLY__ + /* plpar_hcall() -- Generic call interface using above opcodes * * The actual call interface is a hypervisor call instruction with @@ -125,8 +127,6 @@ long plpar_hcall(unsigned long opcode, unsigned long *out2, unsigned long *out3); -#define HVSC ".long 0x44000022\n" - /* Same as plpar_hcall but for those opcodes that return no values * other than status. Slightly more efficient. */ @@ -147,9 +147,6 @@ long plpar_hcall_8arg_2ret(unsigned long unsigned long arg7, unsigned long arg8, unsigned long *out1); - - - /* plpar_hcall_4out() * @@ -166,4 +163,5 @@ long plpar_hcall_4out(unsigned long opco unsigned long *out3, unsigned long *out4); +#endif /* __ASSEMBLY__ */ #endif /* _PPC64_HVCALL_H */ diff -puN arch/ppc64/kernel/head.S~fix_pseries_hcalls arch/ppc64/kernel/head.S --- foobar2/arch/ppc64/kernel/head.S~fix_pseries_hcalls 2005-01-30 14:24:00.495238354 +1100 +++ foobar2-anton/arch/ppc64/kernel/head.S 2005-01-30 14:24:09.523947006 +1100 @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -45,7 +46,6 @@ /* * hcall interface to pSeries LPAR */ -#define HVSC .long 0x44000022 #define H_SET_ASR 0x30 /* _ From sfr at canb.auug.org.au Mon Feb 7 18:02:18 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 7 Feb 2005 18:02:18 +1100 Subject: [PATCH] "invert" dma mapping routines Message-ID: <20050207180218.463809ed.sfr@canb.auug.org.au> Hi Anton, This patch "inverts" our dma mapping routines so that the pci_ and vio_ ... routines are implemented in terms of the dma_ ... routines (the vio_ routines basically disappear anyway as noone uses them directly any more). This is in anticipation of having something akin to dma_mapping_ops attached to the struct device. It also makes sompiling without PCI much easier. Compiled on iSeries, pSeries and pmac. Booted on iSeries. Diffstat looks like this: arch/ppc64/kernel/dma.c | 100 +++++++++++++-------------- arch/ppc64/kernel/iommu.c | 8 +- arch/ppc64/kernel/pci.c | 2 arch/ppc64/kernel/pci_direct_iommu.c | 34 +++++---- arch/ppc64/kernel/pci_iommu.c | 55 ++++++++------- arch/ppc64/kernel/vio.c | 55 +++++++++------ include/asm-ppc64/dma-mapping.h | 20 +++++ include/asm-ppc64/iommu.h | 6 - include/asm-ppc64/pci.h | 126 +---------------------------------- include/asm-ppc64/vio.h | 27 ------- 10 files changed, 166 insertions(+), 267 deletions(-) Please comment. -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN linus-bk/arch/ppc64/kernel/dma.c linus-bk-dma.4/arch/ppc64/kernel/dma.c --- linus-bk/arch/ppc64/kernel/dma.c 2004-10-26 16:06:41.000000000 +1000 +++ linus-bk-dma.4/arch/ppc64/kernel/dma.c 2005-02-07 17:47:41.000000000 +1100 @@ -13,14 +13,23 @@ #include #include -int dma_supported(struct device *dev, u64 mask) +static struct dma_mapping_ops *get_dma_ops(struct device *dev) { if (dev->bus == &pci_bus_type) - return pci_dma_supported(to_pci_dev(dev), mask); + return &pci_dma_ops; #ifdef CONFIG_IBMVIO if (dev->bus == &vio_bus_type) - return vio_dma_supported(to_vio_dev(dev), mask); -#endif /* CONFIG_IBMVIO */ + return &vio_dma_ops; +#endif + return NULL; +} + +int dma_supported(struct device *dev, u64 mask) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + return dma_ops->dma_supported(dev, mask); BUG(); return 0; } @@ -32,7 +41,7 @@ return pci_set_dma_mask(to_pci_dev(dev), dma_mask); #ifdef CONFIG_IBMVIO if (dev->bus == &vio_bus_type) - return vio_set_dma_mask(to_vio_dev(dev), dma_mask); + return -EIO; #endif /* CONFIG_IBMVIO */ BUG(); return 0; @@ -42,12 +51,10 @@ void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag) { - if (dev->bus == &pci_bus_type) - return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle); -#ifdef CONFIG_IBMVIO - if (dev->bus == &vio_bus_type) - return vio_alloc_consistent(to_vio_dev(dev), size, dma_handle); -#endif /* CONFIG_IBMVIO */ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + return dma_ops->alloc_coherent(dev, size, dma_handle, flag); BUG(); return NULL; } @@ -56,12 +63,10 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle) { - if (dev->bus == &pci_bus_type) - pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle); -#ifdef CONFIG_IBMVIO - else if (dev->bus == &vio_bus_type) - vio_free_consistent(to_vio_dev(dev), size, cpu_addr, dma_handle); -#endif /* CONFIG_IBMVIO */ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); else BUG(); } @@ -70,12 +75,10 @@ dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, enum dma_data_direction direction) { - if (dev->bus == &pci_bus_type) - return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction); -#ifdef CONFIG_IBMVIO - if (dev->bus == &vio_bus_type) - return vio_map_single(to_vio_dev(dev), cpu_addr, size, direction); -#endif /* CONFIG_IBMVIO */ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + return dma_ops->map_single(dev, cpu_addr, size, direction); BUG(); return (dma_addr_t)0; } @@ -84,12 +87,10 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction) { - if (dev->bus == &pci_bus_type) - pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction); -#ifdef CONFIG_IBMVIO - else if (dev->bus == &vio_bus_type) - vio_unmap_single(to_vio_dev(dev), dma_addr, size, direction); -#endif /* CONFIG_IBMVIO */ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + dma_ops->unmap_single(dev, dma_addr, size, direction); else BUG(); } @@ -99,12 +100,11 @@ unsigned long offset, size_t size, enum dma_data_direction direction) { - if (dev->bus == &pci_bus_type) - return pci_map_page(to_pci_dev(dev), page, offset, size, (int)direction); -#ifdef CONFIG_IBMVIO - if (dev->bus == &vio_bus_type) - return vio_map_page(to_vio_dev(dev), page, offset, size, direction); -#endif /* CONFIG_IBMVIO */ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + return dma_ops->map_single(dev, + (page_address(page) + offset), size, direction); BUG(); return (dma_addr_t)0; } @@ -113,12 +113,10 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, enum dma_data_direction direction) { - if (dev->bus == &pci_bus_type) - pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction); -#ifdef CONFIG_IBMVIO - else if (dev->bus == &vio_bus_type) - vio_unmap_page(to_vio_dev(dev), dma_address, size, direction); -#endif /* CONFIG_IBMVIO */ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + dma_ops->unmap_single(dev, dma_address, size, direction); else BUG(); } @@ -127,12 +125,10 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction) { - if (dev->bus == &pci_bus_type) - return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction); -#ifdef CONFIG_IBMVIO - if (dev->bus == &vio_bus_type) - return vio_map_sg(to_vio_dev(dev), sg, nents, direction); -#endif /* CONFIG_IBMVIO */ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + return dma_ops->map_sg(dev, sg, nents, direction); BUG(); return 0; } @@ -141,12 +137,10 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, enum dma_data_direction direction) { - if (dev->bus == &pci_bus_type) - pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction); -#ifdef CONFIG_IBMVIO - else if (dev->bus == &vio_bus_type) - vio_unmap_sg(to_vio_dev(dev), sg, nhwentries, direction); -#endif /* CONFIG_IBMVIO */ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + if (dma_ops) + dma_ops->unmap_sg(dev, sg, nhwentries, direction); else BUG(); } diff -ruN linus-bk/arch/ppc64/kernel/iommu.c linus-bk-dma.4/arch/ppc64/kernel/iommu.c --- linus-bk/arch/ppc64/kernel/iommu.c 2005-01-09 10:05:39.000000000 +1100 +++ linus-bk-dma.4/arch/ppc64/kernel/iommu.c 2005-02-07 15:00:06.000000000 +1100 @@ -513,8 +513,8 @@ * Returns the virtual address of the buffer and sets dma_handle * to the dma address (mapping) of the first page. */ -void *iommu_alloc_consistent(struct iommu_table *tbl, size_t size, - dma_addr_t *dma_handle) +void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, + dma_addr_t *dma_handle, int flag) { void *ret = NULL; dma_addr_t mapping; @@ -538,7 +538,7 @@ return NULL; /* Alloc enough pages (and possibly more) */ - ret = (void *)__get_free_pages(GFP_ATOMIC, order); + ret = (void *)__get_free_pages(flag, order); if (!ret) return NULL; memset(ret, 0, size); @@ -553,7 +553,7 @@ return ret; } -void iommu_free_consistent(struct iommu_table *tbl, size_t size, +void iommu_free_coherent(struct iommu_table *tbl, size_t size, void *vaddr, dma_addr_t dma_handle) { unsigned int npages; diff -ruN linus-bk/arch/ppc64/kernel/pci.c linus-bk-dma.4/arch/ppc64/kernel/pci.c --- linus-bk/arch/ppc64/kernel/pci.c 2005-01-22 06:09:00.000000000 +1100 +++ linus-bk-dma.4/arch/ppc64/kernel/pci.c 2005-02-07 14:45:23.000000000 +1100 @@ -69,7 +69,7 @@ LIST_HEAD(hose_list); -struct pci_dma_ops pci_dma_ops; +struct dma_mapping_ops pci_dma_ops; EXPORT_SYMBOL(pci_dma_ops); int global_phb_number; /* Global phb counter */ diff -ruN linus-bk/arch/ppc64/kernel/pci_direct_iommu.c linus-bk-dma.4/arch/ppc64/kernel/pci_direct_iommu.c --- linus-bk/arch/ppc64/kernel/pci_direct_iommu.c 2005-01-09 10:05:39.000000000 +1100 +++ linus-bk-dma.4/arch/ppc64/kernel/pci_direct_iommu.c 2005-02-07 16:00:47.000000000 +1100 @@ -30,12 +30,12 @@ #include "pci.h" -static void *pci_direct_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) +static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, int flag) { void *ret; - ret = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)); + ret = (void *)__get_free_pages(flag, get_order(size)); if (ret != NULL) { memset(ret, 0, size); *dma_handle = virt_to_abs(ret); @@ -43,24 +43,24 @@ return ret; } -static void pci_direct_free_consistent(struct pci_dev *hwdev, size_t size, +static void pci_direct_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { free_pages((unsigned long)vaddr, get_order(size)); } -static dma_addr_t pci_direct_map_single(struct pci_dev *hwdev, void *ptr, +static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr, size_t size, enum dma_data_direction direction) { return virt_to_abs(ptr); } -static void pci_direct_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, +static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction) { } -static int pci_direct_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, +static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, enum dma_data_direction direction) { int i; @@ -73,17 +73,23 @@ return nents; } -static void pci_direct_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, +static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, enum dma_data_direction direction) { } +static int pci_direct_dma_supported(struct device *dev, u64 mask) +{ + return mask < 0x100000000ull; +} + void __init pci_direct_iommu_init(void) { - pci_dma_ops.pci_alloc_consistent = pci_direct_alloc_consistent; - pci_dma_ops.pci_free_consistent = pci_direct_free_consistent; - pci_dma_ops.pci_map_single = pci_direct_map_single; - pci_dma_ops.pci_unmap_single = pci_direct_unmap_single; - pci_dma_ops.pci_map_sg = pci_direct_map_sg; - pci_dma_ops.pci_unmap_sg = pci_direct_unmap_sg; + pci_dma_ops.alloc_coherent = pci_direct_alloc_coherent; + pci_dma_ops.free_coherent = pci_direct_free_coherent; + pci_dma_ops.map_single = pci_direct_map_single; + pci_dma_ops.unmap_single = pci_direct_unmap_single; + pci_dma_ops.map_sg = pci_direct_map_sg; + pci_dma_ops.unmap_sg = pci_direct_unmap_sg; + pci_dma_ops.dma_supported = pci_direct_dma_supported; } diff -ruN linus-bk/arch/ppc64/kernel/pci_iommu.c linus-bk-dma.4/arch/ppc64/kernel/pci_iommu.c --- linus-bk/arch/ppc64/kernel/pci_iommu.c 2004-11-16 16:05:10.000000000 +1100 +++ linus-bk-dma.4/arch/ppc64/kernel/pci_iommu.c 2005-02-07 15:10:05.000000000 +1100 @@ -50,19 +50,23 @@ */ #define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata)) -static inline struct iommu_table *devnode_table(struct pci_dev *dev) +static inline struct iommu_table *devnode_table(struct device *dev) { - if (!dev) - dev = ppc64_isabridge_dev; - if (!dev) - return NULL; + struct pci_dev *pdev; + + if (!dev) { + pdev = ppc64_isabridge_dev; + if (!pdev) + return NULL; + } else + pdev = to_pci_dev(dev); #ifdef CONFIG_PPC_ISERIES - return ISERIES_DEVNODE(dev)->iommu_table; + return ISERIES_DEVNODE(pdev)->iommu_table; #endif /* CONFIG_PPC_ISERIES */ #ifdef CONFIG_PPC_MULTIPLATFORM - return PCI_GET_DN(dev)->iommu_table; + return PCI_GET_DN(pdev)->iommu_table; #endif /* CONFIG_PPC_MULTIPLATFORM */ } @@ -71,16 +75,17 @@ * Returns the virtual address of the buffer and sets dma_handle * to the dma address (mapping) of the first page. */ -static void *pci_iommu_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) +static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, int flag) { - return iommu_alloc_consistent(devnode_table(hwdev), size, dma_handle); + return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle, + flag); } -static void pci_iommu_free_consistent(struct pci_dev *hwdev, size_t size, +static void pci_iommu_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { - iommu_free_consistent(devnode_table(hwdev), size, vaddr, dma_handle); + iommu_free_coherent(devnode_table(hwdev), size, vaddr, dma_handle); } /* Creates TCEs for a user provided buffer. The user buffer must be @@ -89,46 +94,46 @@ * need not be page aligned, the dma_addr_t returned will point to the same * byte within the page as vaddr. */ -static dma_addr_t pci_iommu_map_single(struct pci_dev *hwdev, void *vaddr, +static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr, size_t size, enum dma_data_direction direction) { return iommu_map_single(devnode_table(hwdev), vaddr, size, direction); } -static void pci_iommu_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_handle, +static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { iommu_unmap_single(devnode_table(hwdev), dma_handle, size, direction); } -static int pci_iommu_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, +static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist, int nelems, enum dma_data_direction direction) { - return iommu_map_sg(&pdev->dev, devnode_table(pdev), sglist, + return iommu_map_sg(pdev, devnode_table(pdev), sglist, nelems, direction); } -static void pci_iommu_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, +static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist, int nelems, enum dma_data_direction direction) { iommu_unmap_sg(devnode_table(pdev), sglist, nelems, direction); } /* We support DMA to/from any memory page via the iommu */ -static int pci_iommu_dma_supported(struct pci_dev *pdev, u64 mask) +static int pci_iommu_dma_supported(struct device *dev, u64 mask) { return 1; } void pci_iommu_init(void) { - pci_dma_ops.pci_alloc_consistent = pci_iommu_alloc_consistent; - pci_dma_ops.pci_free_consistent = pci_iommu_free_consistent; - pci_dma_ops.pci_map_single = pci_iommu_map_single; - pci_dma_ops.pci_unmap_single = pci_iommu_unmap_single; - pci_dma_ops.pci_map_sg = pci_iommu_map_sg; - pci_dma_ops.pci_unmap_sg = pci_iommu_unmap_sg; - pci_dma_ops.pci_dma_supported = pci_iommu_dma_supported; + pci_dma_ops.alloc_coherent = pci_iommu_alloc_coherent; + pci_dma_ops.free_coherent = pci_iommu_free_coherent; + pci_dma_ops.map_single = pci_iommu_map_single; + pci_dma_ops.unmap_single = pci_iommu_unmap_single; + pci_dma_ops.map_sg = pci_iommu_map_sg; + pci_dma_ops.unmap_sg = pci_iommu_unmap_sg; + pci_dma_ops.dma_supported = pci_iommu_dma_supported; } diff -ruN linus-bk/arch/ppc64/kernel/vio.c linus-bk-dma.4/arch/ppc64/kernel/vio.c --- linus-bk/arch/ppc64/kernel/vio.c 2005-01-09 10:05:39.000000000 +1100 +++ linus-bk-dma.4/arch/ppc64/kernel/vio.c 2005-02-07 15:45:00.000000000 +1100 @@ -557,48 +557,61 @@ EXPORT_SYMBOL(vio_disable_interrupts); #endif -dma_addr_t vio_map_single(struct vio_dev *dev, void *vaddr, +static dma_addr_t vio_map_single(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { - return iommu_map_single(dev->iommu_table, vaddr, size, direction); + return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size, + direction); } -EXPORT_SYMBOL(vio_map_single); -void vio_unmap_single(struct vio_dev *dev, dma_addr_t dma_handle, +static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - iommu_unmap_single(dev->iommu_table, dma_handle, size, direction); + iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size, + direction); } -EXPORT_SYMBOL(vio_unmap_single); -int vio_map_sg(struct vio_dev *vdev, struct scatterlist *sglist, int nelems, - enum dma_data_direction direction) +static int vio_map_sg(struct device *dev, struct scatterlist *sglist, + int nelems, enum dma_data_direction direction) { - return iommu_map_sg(&vdev->dev, vdev->iommu_table, sglist, + return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist, nelems, direction); } -EXPORT_SYMBOL(vio_map_sg); -void vio_unmap_sg(struct vio_dev *vdev, struct scatterlist *sglist, int nelems, - enum dma_data_direction direction) +static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist, + int nelems, enum dma_data_direction direction) { - iommu_unmap_sg(vdev->iommu_table, sglist, nelems, direction); + iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction); } -EXPORT_SYMBOL(vio_unmap_sg); -void *vio_alloc_consistent(struct vio_dev *dev, size_t size, - dma_addr_t *dma_handle) +static void *vio_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, int flag) { - return iommu_alloc_consistent(dev->iommu_table, size, dma_handle); + return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size, + dma_handle, flag); } -EXPORT_SYMBOL(vio_alloc_consistent); -void vio_free_consistent(struct vio_dev *dev, size_t size, +static void vio_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { - iommu_free_consistent(dev->iommu_table, size, vaddr, dma_handle); + iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr, + dma_handle); } -EXPORT_SYMBOL(vio_free_consistent); + +static int vio_dma_supported(struct device *dev, u64 mask) +{ + return 1; +} + +struct dma_mapping_ops vio_dma_ops = { + .alloc_coherent = vio_alloc_coherent, + .free_coherent = vio_free_coherent, + .map_single = vio_map_single, + .unmap_single = vio_unmap_single, + .map_sg = vio_map_sg, + .unmap_sg = vio_unmap_sg, + .dma_supported = vio_dma_supported, +}; static int vio_bus_match(struct device *dev, struct device_driver *drv) { diff -ruN linus-bk/include/asm-ppc64/dma-mapping.h linus-bk-dma.4/include/asm-ppc64/dma-mapping.h --- linus-bk/include/asm-ppc64/dma-mapping.h 2004-09-14 21:06:08.000000000 +1000 +++ linus-bk-dma.4/include/asm-ppc64/dma-mapping.h 2005-02-07 14:38:01.000000000 +1100 @@ -113,4 +113,24 @@ /* nothing to do */ } +/* + * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO + */ +struct dma_mapping_ops { + void * (*alloc_coherent)(struct device *dev, size_t size, + dma_addr_t *dma_handle, int flag); + void (*free_coherent)(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); + dma_addr_t (*map_single)(struct device *dev, void *ptr, + size_t size, enum dma_data_direction direction); + void (*unmap_single)(struct device *dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction direction); + int (*map_sg)(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction direction); + void (*unmap_sg)(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction direction); + int (*dma_supported)(struct device *dev, u64 mask); + int (*dac_dma_supported)(struct device *dev, u64 mask); +}; + #endif /* _ASM_DMA_MAPPING_H */ diff -ruN linus-bk/include/asm-ppc64/iommu.h linus-bk-dma.4/include/asm-ppc64/iommu.h --- linus-bk/include/asm-ppc64/iommu.h 2005-01-09 10:05:41.000000000 +1100 +++ linus-bk-dma.4/include/asm-ppc64/iommu.h 2005-02-07 15:02:01.000000000 +1100 @@ -145,9 +145,9 @@ extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, int nelems, enum dma_data_direction direction); -extern void *iommu_alloc_consistent(struct iommu_table *tbl, size_t size, - dma_addr_t *dma_handle); -extern void iommu_free_consistent(struct iommu_table *tbl, size_t size, +extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, + dma_addr_t *dma_handle, int flag); +extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, void *vaddr, dma_addr_t dma_handle); extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, size_t size, enum dma_data_direction direction); diff -ruN linus-bk/include/asm-ppc64/pci.h linus-bk-dma.4/include/asm-ppc64/pci.h --- linus-bk/include/asm-ppc64/pci.h 2004-10-28 06:58:36.000000000 +1000 +++ linus-bk-dma.4/include/asm-ppc64/pci.h 2005-02-07 15:03:50.000000000 +1100 @@ -13,11 +13,14 @@ #include #include #include + #include #include #include #include +#include + #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 @@ -63,131 +66,18 @@ extern unsigned int pcibios_assign_all_busses(void); -/* - * PCI DMA operations are abstracted for G5 vs. i/pSeries - */ -struct pci_dma_ops { - void * (*pci_alloc_consistent)(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle); - void (*pci_free_consistent)(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle); - - dma_addr_t (*pci_map_single)(struct pci_dev *hwdev, void *ptr, - size_t size, enum dma_data_direction direction); - void (*pci_unmap_single)(struct pci_dev *hwdev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction); - int (*pci_map_sg)(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction direction); - void (*pci_unmap_sg)(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction direction); - int (*pci_dma_supported)(struct pci_dev *hwdev, u64 mask); - int (*pci_dac_dma_supported)(struct pci_dev *hwdev, u64 mask); -}; - -extern struct pci_dma_ops pci_dma_ops; - -static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - return pci_dma_ops.pci_alloc_consistent(hwdev, size, dma_handle); -} - -static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - pci_dma_ops.pci_free_consistent(hwdev, size, vaddr, dma_handle); -} - -static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, - size_t size, int direction) -{ - return pci_dma_ops.pci_map_single(hwdev, ptr, size, - (enum dma_data_direction)direction); -} - -static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, - size_t size, int direction) -{ - pci_dma_ops.pci_unmap_single(hwdev, dma_addr, size, - (enum dma_data_direction)direction); -} - -static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction) -{ - return pci_dma_ops.pci_map_sg(hwdev, sg, nents, - (enum dma_data_direction)direction); -} - -static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction) -{ - pci_dma_ops.pci_unmap_sg(hwdev, sg, nents, - (enum dma_data_direction)direction); -} - -static inline void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, - dma_addr_t dma_handle, - size_t size, int direction) -{ - BUG_ON(direction == PCI_DMA_NONE); - /* nothing to do */ -} - -static inline void pci_dma_sync_single_for_device(struct pci_dev *hwdev, - dma_addr_t dma_handle, - size_t size, int direction) -{ - BUG_ON(direction == PCI_DMA_NONE); - /* nothing to do */ -} - -static inline void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, - struct scatterlist *sg, - int nelems, int direction) -{ - BUG_ON(direction == PCI_DMA_NONE); - /* nothing to do */ -} - -static inline void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, - struct scatterlist *sg, - int nelems, int direction) -{ - BUG_ON(direction == PCI_DMA_NONE); - /* nothing to do */ -} - -/* Return whether the given PCI device DMA address mask can - * be supported properly. For example, if your device can - * only drive the low 24-bits during PCI bus mastering, then - * you would pass 0x00ffffff as the mask to this function. - * We default to supporting only 32 bits DMA unless we have - * an explicit override of this function in pci_dma_ops for - * the platform - */ -static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) -{ - if (pci_dma_ops.pci_dma_supported) - return pci_dma_ops.pci_dma_supported(hwdev, mask); - return (mask < 0x100000000ull); -} +extern struct dma_mapping_ops pci_dma_ops; /* For DAC DMA, we currently don't support it by default, but * we let the platform override this */ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) { - if (pci_dma_ops.pci_dac_dma_supported) - return pci_dma_ops.pci_dac_dma_supported(hwdev, mask); + if (pci_dma_ops.dac_dma_supported) + return pci_dma_ops.dac_dma_supported(&hwdev->dev, mask); return 0; } -static inline int pci_dma_mapping_error(dma_addr_t dma_addr) -{ - return dma_mapping_error(dma_addr); -} - extern int pci_domain_nr(struct pci_bus *bus); /* Set the name of the bus as it appears in /proc/bus/pci */ @@ -201,10 +91,6 @@ /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ #define HAVE_PCI_MMAP 1 -#define pci_map_page(dev, page, off, size, dir) \ - pci_map_single(dev, (page_address(page) + (off)), size, dir) -#define pci_unmap_page(dev,addr,sz,dir) pci_unmap_single(dev,addr,sz,dir) - /* pci_unmap_{single,page} is not a nop, thus... */ #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ dma_addr_t ADDR_NAME; diff -ruN linus-bk/include/asm-ppc64/vio.h linus-bk-dma.4/include/asm-ppc64/vio.h --- linus-bk/include/asm-ppc64/vio.h 2004-06-30 15:40:04.000000000 +1000 +++ linus-bk-dma.4/include/asm-ppc64/vio.h 2005-02-07 15:42:37.000000000 +1100 @@ -57,32 +57,7 @@ int vio_enable_interrupts(struct vio_dev *dev); int vio_disable_interrupts(struct vio_dev *dev); -dma_addr_t vio_map_single(struct vio_dev *dev, void *vaddr, - size_t size, enum dma_data_direction direction); -void vio_unmap_single(struct vio_dev *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction); -int vio_map_sg(struct vio_dev *vdev, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction); -void vio_unmap_sg(struct vio_dev *vdev, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction); -void *vio_alloc_consistent(struct vio_dev *dev, size_t size, - dma_addr_t *dma_handle); -void vio_free_consistent(struct vio_dev *dev, size_t size, void *vaddr, - dma_addr_t dma_handle); - -static inline int vio_dma_supported(struct vio_dev *hwdev, u64 mask) -{ - return 1; -} - -#define vio_map_page(dev, page, off, size, dir) \ - vio_map_single(dev, (page_address(page) + (off)), size, dir) -#define vio_unmap_page(dev,addr,sz,dir) vio_unmap_single(dev,addr,sz,dir) - -static inline int vio_set_dma_mask(struct vio_dev *dev, u64 mask) -{ - return -EIO; -} +extern struct dma_mapping_ops vio_dma_ops; extern struct bus_type vio_bus_type; -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050207/9250fc87/attachment.pgp From olh at suse.de Tue Feb 8 01:40:58 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 7 Feb 2005 15:40:58 +0100 Subject: [PATCH] disable HMT for RS64 cpus Message-ID: <20050207144058.GA5516@suse.de> Hardware multithreading for RS64 cpus is currently broken. Anton sent me a patch a few weeks ago, but it did not work. So just hide the config option for the time being. Signed-off-by: Olaf Hering diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc64/Kconfig ./arch/ppc64/Kconfig --- ../linux-2.6.11-rc3.orig/arch/ppc64/Kconfig 2005-02-03 02:55:53.000000000 +0100 +++ ./arch/ppc64/Kconfig 2005-02-07 15:36:25.079315558 +0100 @@ -194,7 +194,10 @@ config NR_CPUS config HMT bool "Hardware multithreading" - depends on SMP && PPC_PSERIES + depends on SMP && PPC_PSERIES && BROKEN + help + This option enables hardware multithreading on RS64 cpus. + pSeries systems p620 and p660 have such a cpu type. config DISCONTIGMEM bool "Discontiguous Memory Support" From olh at suse.de Tue Feb 8 01:42:28 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 7 Feb 2005 15:42:28 +0100 Subject: [PATCH] update ppc64 defconfig Message-ID: <20050207144228.GB5516@suse.de> This turns the ppc64/defconfig into something useful, it boots on all systems. Signed-off-by: Olaf Hering diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc64/defconfig ./arch/ppc64/defconfig --- ../linux-2.6.11-rc3.orig/arch/ppc64/defconfig 2005-02-03 02:55:23.000000000 +0100 +++ ./arch/ppc64/defconfig 2005-02-07 15:11:06.466124000 +0100 @@ -1,9 +1,12 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.11-rc3-bk3 +# Mon Feb 7 15:11:06 2005 # CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y @@ -16,27 +19,36 @@ CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y +CONFIG_LOCK_KERNEL=y # # General setup # +CONFIG_LOCALVERSION="" CONFIG_SWAP=y CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set # # Loadable module support @@ -45,28 +57,41 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y CONFIG_STOP_MACHINE=y +CONFIG_SYSVIPC_COMPAT=y # # Platform support # # CONFIG_PPC_ISERIES is not set +CONFIG_PPC_MULTIPLATFORM=y CONFIG_PPC_PSERIES=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_MAPLE=y CONFIG_PPC=y CONFIG_PPC64=y CONFIG_PPC_OF=y CONFIG_ALTIVEC=y -# CONFIG_PPC_PMAC is not set -# CONFIG_BOOTX_TEXT is not set +CONFIG_PPC_SPLPAR=y +CONFIG_IBMVIO=y +CONFIG_U3_DART=y +CONFIG_MPIC_BROKEN_U3=y +CONFIG_PPC_PMAC64=y +CONFIG_BOOTX_TEXT=y # CONFIG_POWER4_ONLY is not set -# CONFIG_IOMMU_VMERGE is not set +CONFIG_IOMMU_VMERGE=y CONFIG_SMP=y -CONFIG_IRQ_ALL_CPUS=y CONFIG_NR_CPUS=32 # CONFIG_HMT is not set -# CONFIG_DISCONTIGMEM is not set +CONFIG_DISCONTIGMEM=y +# CONFIG_NUMA is not set +# CONFIG_SCHED_SMT is not set +# CONFIG_PREEMPT is not set +CONFIG_EEH=y +CONFIG_GENERIC_HARDIRQS=y CONFIG_PPC_RTAS=y CONFIG_RTAS_FLASH=m CONFIG_SCANLOG=m @@ -78,14 +103,19 @@ CONFIG_LPARCFG=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y +CONFIG_BINFMT_MISC=m +# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCI_NAMES is not set +CONFIG_HOTPLUG_CPU=y # -# PCMCIA/CardBus support +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PC-card bridges # -# CONFIG_PCMCIA is not set # # PCI Hotplug Support @@ -93,7 +123,6 @@ CONFIG_PCI_NAMES=y CONFIG_HOTPLUG_PCI=m # CONFIG_HOTPLUG_PCI_FAKE is not set # CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_PCIE is not set # CONFIG_HOTPLUG_PCI_SHPC is not set CONFIG_HOTPLUG_PCI_RPA=m CONFIG_HOTPLUG_PCI_RPA_DLPAR=m @@ -107,7 +136,9 @@ CONFIG_PROC_DEVICETREE=y # # Generic Driver Options # -CONFIG_FW_LOADER=m +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set # @@ -118,7 +149,14 @@ CONFIG_FW_LOADER=m # # Parallel port support # -# CONFIG_PARPORT is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set # # Plug and Play support @@ -128,17 +166,32 @@ CONFIG_FW_LOADER=m # Block devices # CONFIG_BLK_DEV_FD=y +# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_CARMEL is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -149,15 +202,14 @@ CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide.txt for help/info on IDE drives # +# CONFIG_BLK_DEV_IDE_SATA is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_IDE_TASKFILE_IO is not set # # IDE chipset support/bugfixes @@ -173,7 +225,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set CONFIG_BLK_DEV_AMD74XX=y @@ -194,6 +245,11 @@ CONFIG_BLK_DEV_AMD74XX=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y +# CONFIG_BLK_DEV_IDE_PMAC_BLINK is not set +# CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y @@ -219,7 +275,6 @@ CONFIG_CHR_DEV_SG=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_REPORT_LUNS=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -228,33 +283,52 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y +CONFIG_SCSI_ISCSI_ATTRS=m # # SCSI low-level drivers # # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_SATA is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set +CONFIG_SCSI_SATA_SVW=y +# CONFIG_SCSI_ATA_PIIX is not set +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +# CONFIG_SCSI_SATA_VIA is not set +# CONFIG_SCSI_SATA_VITESSE is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set +CONFIG_SCSI_IBMVSCSI=y +# CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +CONFIG_SCSI_IPR=y +CONFIG_SCSI_IPR_TRACE=y +CONFIG_SCSI_IPR_DUMP=y # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -264,10 +338,9 @@ CONFIG_SCSI_QLA22XX=m CONFIG_SCSI_QLA2300=m CONFIG_SCSI_QLA2322=m CONFIG_SCSI_QLA6312=m -CONFIG_SCSI_QLA6322=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_DEBUG=m # # Multi-device support (RAID and LVM) @@ -277,11 +350,16 @@ CONFIG_BLK_DEV_MD=y CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=y CONFIG_MD_RAID5=y -CONFIG_MD_RAID6=y -# CONFIG_MD_MULTIPATH is not set +CONFIG_MD_RAID6=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m # # Fusion MPT device support @@ -291,15 +369,48 @@ CONFIG_DM_CRYPT=m # # IEEE 1394 (FireWire) support # -# CONFIG_IEEE1394 is not set +CONFIG_IEEE1394=y + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +# CONFIG_IEEE1394_OUI_DB is not set +CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y +CONFIG_IEEE1394_CONFIG_ROM_IP1394=y + +# +# Device Drivers +# +# CONFIG_IEEE1394_PCILYNX is not set +CONFIG_IEEE1394_OHCI1394=y + +# +# Protocol Drivers +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=y +CONFIG_IEEE1394_CMP=m +CONFIG_IEEE1394_AMDTP=m # # I2O device support # +# CONFIG_I2O is not set # # Macintosh device drivers # +CONFIG_ADB=y +CONFIG_ADB_PMU=y +# CONFIG_PMAC_PBOOK is not set +# CONFIG_PMAC_BACKLIGHT is not set +# CONFIG_INPUT_ADBHID is not set +CONFIG_THERM_PM72=y # # Networking support @@ -322,19 +433,19 @@ CONFIG_NET_IPIP=y # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set -CONFIG_INET_ECN=y CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m +CONFIG_INET_TUNNEL=y +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set # # IP: Virtual Server Configuration # # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -342,6 +453,9 @@ CONFIG_NETFILTER=y # IP: Netfilter Configuration # CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +CONFIG_IP_NF_CT_PROTO_SCTP=m CONFIG_IP_NF_FTP=m CONFIG_IP_NF_IRC=m CONFIG_IP_NF_TFTP=m @@ -366,8 +480,17 @@ CONFIG_IP_NF_MATCH_HELPER=m CONFIG_IP_NF_MATCH_STATE=m CONFIG_IP_NF_MATCH_CONNTRACK=m CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_CONNMARK=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m @@ -385,24 +508,24 @@ CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_DSCP=m CONFIG_IP_NF_TARGET_MARK=m CONFIG_IP_NF_TARGET_CLASSIFY=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_IP_NF_COMPAT_IPCHAINS=m -CONFIG_IP_NF_COMPAT_IPFWADM=m CONFIG_XFRM=y CONFIG_XFRM_USER=m # # SCTP Configuration (EXPERIMENTAL) # -CONFIG_IPV6_SCTP__=y # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set +# CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set CONFIG_LLC=y # CONFIG_LLC2 is not set # CONFIG_IPX is not set @@ -412,36 +535,42 @@ CONFIG_LLC=y # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set -# CONFIG_NET_HW_FLOWCONTROL is not set # # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y # # Network testing # # CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +CONFIG_NETPOLL_RX=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m # # ARCnet devices # # CONFIG_ARCNET is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_OAKNET is not set # CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set +CONFIG_SUNGEM=y CONFIG_NET_VENDOR_3COM=y CONFIG_VORTEX=y # CONFIG_TYPHOON is not set @@ -451,6 +580,7 @@ CONFIG_VORTEX=y # # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set +CONFIG_IBMVETH=m CONFIG_NET_PCI=y CONFIG_PCNET32=y # CONFIG_AMD8111_ETH is not set @@ -483,8 +613,8 @@ CONFIG_E1000=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set -# CONFIG_SIS190 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y # @@ -492,59 +622,40 @@ CONFIG_TIGON3=y # CONFIG_IXGB=m # CONFIG_IXGB_NAPI is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_IBMVETH=m -CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPPOE=m -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set +# CONFIG_S2IO is not set # # Token Ring devices # CONFIG_TR=y CONFIG_IBMOL=y -# CONFIG_IBMLS is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -CONFIG_NETCONSOLE=y - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set # -# IrDA (infrared) support +# Wireless LAN (non-hamradio) # -# CONFIG_IRDA is not set +# CONFIG_NET_RADIO is not set # -# Bluetooth support +# Wan interfaces # -# CONFIG_BT is not set -CONFIG_NETPOLL=y -CONFIG_NETPOLL_RX=y -CONFIG_NETPOLL_TRAP=y -CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=y # # ISDN subsystem @@ -565,12 +676,12 @@ CONFIG_INPUT=y # Userland interfaces # CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set # @@ -582,7 +693,10 @@ CONFIG_SERIO=y CONFIG_SERIO_I8042=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set # # Input Device Drivers @@ -590,15 +704,17 @@ CONFIG_SERIO_I8042=y CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y -CONFIG_INPUT_PCSPKR=y +CONFIG_INPUT_PCSPKR=m # CONFIG_INPUT_UINPUT is not set # @@ -623,16 +739,16 @@ CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_PMACZILOG is not set +CONFIG_SERIAL_ICOM=m CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set CONFIG_HVC_CONSOLE=y - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_QIC02_TAPE is not set +CONFIG_HVCS=m # # IPMI @@ -652,7 +768,6 @@ CONFIG_HVC_CONSOLE=y # # Ftape, the floppy tape device driver # -# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 @@ -661,25 +776,30 @@ CONFIG_MAX_RAW_DEVS=256 # I2C support # CONFIG_I2C=y -# CONFIG_I2C_CHARDEV is not set +CONFIG_I2C_CHARDEV=y # # I2C Algorithms # CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set # # I2C Hardware Bus support # # CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set # CONFIG_I2C_ALI15X3 is not set # CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set +CONFIG_I2C_AMD8111=y # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set # CONFIG_I2C_ISA is not set +CONFIG_I2C_KEYWEST=y +# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set @@ -687,33 +807,61 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set # -# I2C Hardware Sensors Chip support +# Hardware Sensors Chip support # # CONFIG_I2C_SENSOR is not set # CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set # CONFIG_SENSORS_LM83 is not set # CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set # CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set # +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# # Misc devices # @@ -731,20 +879,28 @@ CONFIG_I2C_ALGOBIT=y # Graphics support # CONFIG_FB=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set # CONFIG_FB_CT65550 is not set +# CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set -# CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set -# CONFIG_FB_RIVA is not set +CONFIG_FB_RIVA=y +CONFIG_FB_RIVA_I2C=y +# CONFIG_FB_RIVA_DEBUG is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G450=y -CONFIG_FB_MATROX_G100=y -# CONFIG_FB_MATROX_I2C is not set +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m CONFIG_FB_MATROX_MULTIHEAD=y # CONFIG_FB_RADEON_OLD is not set CONFIG_FB_RADEON=y @@ -752,6 +908,7 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_RADEON_DEBUG is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_KYRO is not set @@ -764,10 +921,8 @@ CONFIG_FB_RADEON_I2C=y # Console display driver support # # CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_PCI_CONSOLE=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y @@ -779,6 +934,11 @@ CONFIG_LOGO=y CONFIG_LOGO_LINUX_MONO=y CONFIG_LOGO_LINUX_VGA16=y CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_DEVICE=y # # Sound @@ -797,13 +957,19 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers # CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set # # USB Device Class drivers @@ -811,8 +977,13 @@ CONFIG_USB_OHCI_HCD=y # CONFIG_USB_BLUETOOTH_TTY is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set -CONFIG_USB_STORAGE=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_RW_DETECT=y # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set @@ -823,7 +994,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_JUMPSHOT is not set # -# USB Human Interface Devices (HID) +# USB Input Devices # CONFIG_USB_HID=y CONFIG_USB_HIDINPUT=y @@ -833,14 +1004,16 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_WACOM is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -852,17 +1025,18 @@ CONFIG_USB_HIDDEV=y # # -# USB Network adaptors +# USB Network Adapters # # CONFIG_USB_CATC is not set # CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set +CONFIG_USB_PEGASUS=y # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set # # USB port drivers # +# CONFIG_USB_USS720 is not set # # USB Serial Converter support @@ -874,50 +1048,81 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set # CONFIG_USB_TEST is not set # +# USB ATM/DSL drivers +# + +# # USB Gadget Support # # CONFIG_USB_GADGET is not set # +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_MTHCA=m +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +# CONFIG_INFINIBAND_IPOIB_DEBUG is not set + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y -# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT3_FS_SECURITY=y CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=y # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y CONFIG_JFS_FS=y CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# CONFIG_XFS_FS=m +CONFIG_XFS_EXPORT=y # CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set +CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=m +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set # @@ -927,6 +1132,7 @@ CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y # # DOS/FAT/NT Filesystems @@ -934,6 +1140,8 @@ CONFIG_UDF_FS=m CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # @@ -941,10 +1149,13 @@ CONFIG_VFAT_FS=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set CONFIG_DEVPTS_FS_XATTR=y -# CONFIG_DEVPTS_FS_SECURITY is not set +CONFIG_DEVPTS_FS_SECURITY=y CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -954,8 +1165,8 @@ CONFIG_RAMFS=y # # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set @@ -973,18 +1184,23 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y +CONFIG_NFSD=m CONFIG_NFSD_V3=y CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y +CONFIG_EXPORTFS=m CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=m -CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +CONFIG_RPCSEC_GSS_SPKM3=m # CONFIG_SMB_FS is not set CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -992,51 +1208,66 @@ CONFIG_CIFS=m # # Partition Types # -# CONFIG_PARTITION_ADVANCED is not set +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set # # Native Language Support # CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m # # Profiling support @@ -1048,19 +1279,26 @@ CONFIG_OPROFILE=y # Kernel hacking # CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_FS=y CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_KPROBES is not set CONFIG_DEBUG_STACK_USAGE=y -# CONFIG_DEBUG_SLAB is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUGGER=y CONFIG_XMON=y -CONFIG_XMON_DEFAULT=y +# CONFIG_XMON_DEFAULT is not set # CONFIG_PPCDBG is not set -# CONFIG_DEBUG_INFO is not set +CONFIG_IRQSTACKS=y # # Security options # +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # @@ -1070,24 +1308,36 @@ CONFIG_CRYPTO=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_TEST=m # +# Hardware crypto devices +# + +# # Library routines # +CONFIG_CRC_CCITT=m CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m From cfriesen at nortel.com Tue Feb 8 01:44:48 2005 From: cfriesen at nortel.com (Chris Friesen) Date: Mon, 07 Feb 2005 08:44:48 -0600 Subject: question on symbol exports In-Reply-To: <1107595148.30302.5.camel@gaston> References: <41FECA18.50609@nortelnetworks.com> <1107243398.4208.47.camel@laptopd505.fenrus.org> <41FFA21C.8060203@nortelnetworks.com> <1107273017.4208.132.camel@laptopd505.fenrus.org> <20050204203050.GA5889@dmt.cnet> <4203D793.1040604@nortel.com> <1107595148.30302.5.camel@gaston> Message-ID: <42077EE0.2060505@nortel.com> Benjamin Herrenschmidt wrote: >>It turns out that to call ptep_clear_flush_dirty() on ppc64 from a >>module I needed to export the following symbols: >> >>__flush_tlb_pending >>ppc64_tlb_batch >>hpte_update > > > Any reason why you need to call that from a module ? Is the module > GPL'd ? I explained this at the beginning of the thread, but I'll do so again. The module will be released under the GPL. The basic idea is that we want to be able to track pages dirtied by a userspace process. The system has no swap, so we use the dirty bit for this. On demand we look up the page tables for an address range specified by the caller, store the addresses of any dirty pages, then mark them clean so that the next write causes them to get marked dirty again. It is this act of marking them clean that requires the additional exports. I've included the current code below. If there is any way to accomplish this without the additional exports, I'd love to hear about it. Chris Note: this code is run while holding &mm->mmap_sem and &mm->page_table_lock. for(addr=start&PAGE_MASK; addr<=end; addr+=PAGE_SIZE) { pte_t *ptep=0; ptep = va_to_ptep_map(mm, addr); if (!ptep) goto unmap_continue; if (!pte_dirty(*ptep)) goto unmap_continue; /* We have a user readable dirty page. Count it.*/ dirty_count++; if (dirty_count <= entries) { __put_user(addr, buf); buf++; ptep_clear_flush_dirty(find_vma(mm, addr), addr, ptep); /* Handle option to stop early. */ if ((dirty_count == entries) && (options & STOP_WHEN_BUF_FULL)) addr=end+1; } unmap_continue: if (ptep) pte_unmap(ptep); } From olh at suse.de Tue Feb 8 01:45:01 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 7 Feb 2005 15:45:01 +0100 Subject: [PATCH] update ppc64 g5_defconfig In-Reply-To: <20050207144228.GB5516@suse.de> References: <20050207144228.GB5516@suse.de> Message-ID: <20050207144501.GC5516@suse.de> This updates the G5 defconfig, disables some option for hardware that is not used on such toys. Signed-off-by: Olaf Hering diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc64/configs/g5_defconfig ./arch/ppc64/configs/g5_defconfig --- ../linux-2.6.11-rc3.orig/arch/ppc64/configs/g5_defconfig 2005-02-03 02:55:06.000000000 +0100 +++ ./arch/ppc64/configs/g5_defconfig 2005-02-07 14:58:27.000000000 +0100 @@ -1,11 +1,12 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.9-rc3 -# Thu Oct 7 15:18:38 2004 +# Linux kernel version: 2.6.11-rc3-bk3 +# Mon Feb 7 14:54:48 2005 # CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y @@ -18,6 +19,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y +CONFIG_LOCK_KERNEL=y # # General setup @@ -25,25 +27,28 @@ CONFIG_CLEAN_COMPILE=y CONFIG_LOCALVERSION="" CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set +CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y -# CONFIG_IKCONFIG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set # @@ -51,10 +56,11 @@ CONFIG_SHMEM=y # CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y CONFIG_STOP_MACHINE=y CONFIG_SYSVIPC_COMPAT=y @@ -65,6 +71,7 @@ CONFIG_SYSVIPC_COMPAT=y CONFIG_PPC_MULTIPLATFORM=y # CONFIG_PPC_PSERIES is not set CONFIG_PPC_PMAC=y +# CONFIG_PPC_MAPLE is not set CONFIG_PPC=y CONFIG_PPC64=y CONFIG_PPC_OF=y @@ -75,12 +82,10 @@ CONFIG_BOOTX_TEXT=y CONFIG_POWER4_ONLY=y CONFIG_IOMMU_VMERGE=y CONFIG_SMP=y -CONFIG_IRQ_ALL_CPUS=y CONFIG_NR_CPUS=2 # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_LPARCFG is not set +CONFIG_GENERIC_HARDIRQS=y # # General setup @@ -91,12 +96,15 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y -# CONFIG_HOTPLUG_CPU is not set # -# PCMCIA/CardBus support +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PC-card bridges # -# CONFIG_PCMCIA is not set # # PCI Hotplug Support @@ -139,14 +147,29 @@ CONFIG_FW_LOADER=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -161,11 +184,10 @@ CONFIG_BLK_DEV_IDE=y CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_IDETAPE=y -CONFIG_BLK_DEV_IDEFLOPPY=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_IDE_TASKFILE_IO is not set # # IDE chipset support/bugfixes @@ -205,7 +227,6 @@ CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y CONFIG_BLK_DEV_IDEDMA_PMAC=y # CONFIG_BLK_DEV_IDE_PMAC_BLINK is not set -CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set @@ -240,6 +261,7 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # # SCSI low-level drivers @@ -254,6 +276,7 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_ATA_PIIX is not set # CONFIG_SCSI_SATA_NV is not set @@ -261,6 +284,7 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_SATA_SX4 is not set # CONFIG_SCSI_SATA_SIL is not set # CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set # CONFIG_SCSI_SATA_VIA is not set # CONFIG_SCSI_SATA_VITESSE is not set # CONFIG_SCSI_BUSLOGIC is not set @@ -270,12 +294,9 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -CONFIG_SCSI_SYM53C8XX_2=y -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set @@ -286,11 +307,9 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_MAC53C94 is not set # # Multi-device support (RAID and LVM) @@ -300,15 +319,16 @@ CONFIG_BLK_DEV_MD=y CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y -# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID10=m CONFIG_MD_RAID5=y -# CONFIG_MD_RAID6 is not set -# CONFIG_MD_MULTIPATH is not set +CONFIG_MD_RAID6=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=y -# CONFIG_DM_CRYPT is not set -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m # # Fusion MPT device support @@ -386,6 +406,8 @@ CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_TUNNEL=y +CONFIG_IP_TCPDIAG=m +# CONFIG_IP_TCPDIAG_IPV6 is not set # # IP: Virtual Server Configuration @@ -398,61 +420,71 @@ CONFIG_NETFILTER=y # # IP: Netfilter Configuration # -CONFIG_IP_NF_CONNTRACK=y -# CONFIG_IP_NF_CT_ACCT is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -# CONFIG_IP_NF_FTP is not set -# CONFIG_IP_NF_IRC is not set -# CONFIG_IP_NF_TFTP is not set -# CONFIG_IP_NF_AMANDA is not set -CONFIG_IP_NF_QUEUE=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_LIMIT=y -CONFIG_IP_NF_MATCH_IPRANGE=y -CONFIG_IP_NF_MATCH_MAC=y -CONFIG_IP_NF_MATCH_PKTTYPE=y -CONFIG_IP_NF_MATCH_MARK=y -CONFIG_IP_NF_MATCH_MULTIPORT=y -CONFIG_IP_NF_MATCH_TOS=y -CONFIG_IP_NF_MATCH_RECENT=y -CONFIG_IP_NF_MATCH_ECN=y -CONFIG_IP_NF_MATCH_DSCP=y -CONFIG_IP_NF_MATCH_AH_ESP=y -CONFIG_IP_NF_MATCH_LENGTH=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_MATCH_TCPMSS=y -CONFIG_IP_NF_MATCH_HELPER=y -CONFIG_IP_NF_MATCH_STATE=y -CONFIG_IP_NF_MATCH_CONNTRACK=y -CONFIG_IP_NF_MATCH_OWNER=y -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_MATCH_REALM is not set -# CONFIG_IP_NF_MATCH_SCTP is not set -# CONFIG_IP_NF_MATCH_COMMENT is not set -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_LOG=y -CONFIG_IP_NF_TARGET_ULOG=y -CONFIG_IP_NF_TARGET_TCPMSS=y -CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_CONNMARK=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_SAME=y -# CONFIG_IP_NF_NAT_SNMP_BASIC is not set -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_TARGET_TOS=y -CONFIG_IP_NF_TARGET_ECN=y -CONFIG_IP_NF_TARGET_DSCP=y -CONFIG_IP_NF_TARGET_MARK=y -CONFIG_IP_NF_TARGET_CLASSIFY=y -# CONFIG_IP_NF_RAW is not set -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set +CONFIG_XFRM_USER=m # # SCTP Configuration (EXPERIMENTAL) @@ -471,13 +503,12 @@ CONFIG_LLC=y # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set -# CONFIG_NET_HW_FLOWCONTROL is not set # # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set +CONFIG_NET_CLS_ROUTE=y # # Network testing @@ -587,7 +618,7 @@ CONFIG_INPUT=y # Userland interfaces # CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_JOYDEV=m @@ -663,7 +694,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # -# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 @@ -693,6 +723,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_I810 is not set # CONFIG_I2C_ISA is not set CONFIG_I2C_KEYWEST=y +# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set @@ -701,6 +732,7 @@ CONFIG_I2C_KEYWEST=y # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set @@ -712,20 +744,25 @@ CONFIG_I2C_KEYWEST=y # CONFIG_I2C_SENSOR is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set # CONFIG_SENSORS_LM80 is not set # CONFIG_SENSORS_LM83 is not set # CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set @@ -768,6 +805,7 @@ CONFIG_I2C_KEYWEST=y # CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set @@ -789,6 +827,7 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_RADEON_DEBUG is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_KYRO is not set @@ -814,6 +853,11 @@ CONFIG_LOGO=y CONFIG_LOGO_LINUX_MONO=y CONFIG_LOGO_LINUX_VGA16=y CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_DEVICE=y # # Sound @@ -833,6 +877,8 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -842,6 +888,7 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_ROOT_HUB_TT is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set # # USB Device Class drivers @@ -849,9 +896,13 @@ CONFIG_USB_OHCI_HCD=y # CONFIG_USB_BLUETOOTH_TTY is not set CONFIG_USB_ACM=m CONFIG_USB_PRINTER=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set +CONFIG_USB_STORAGE_RW_DETECT=y CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y CONFIG_USB_STORAGE_ISD200=y @@ -862,7 +913,7 @@ CONFIG_USB_STORAGE_SDDR55=y CONFIG_USB_STORAGE_JUMPSHOT=y # -# USB Human Interface Devices (HID) +# USB Input Devices # CONFIG_USB_HID=y CONFIG_USB_HIDINPUT=y @@ -885,7 +936,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -897,12 +947,12 @@ CONFIG_USB_HIDDEV=y # # -# USB Network adaptors +# USB Network Adapters # -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m CONFIG_USB_USBNET=m # @@ -914,6 +964,7 @@ CONFIG_USB_BELKIN=y CONFIG_USB_GENESYS=y CONFIG_USB_NET1080=y CONFIG_USB_PL2301=y +CONFIG_USB_KC2190=y # # Intelligent USB Devices/Gadgets @@ -939,6 +990,7 @@ CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_VISOR=m @@ -946,6 +998,8 @@ CONFIG_USB_SERIAL_IPAQ=m CONFIG_USB_SERIAL_IR=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m CONFIG_USB_SERIAL_KEYSPAN_PDA=m CONFIG_USB_SERIAL_KEYSPAN=m CONFIG_USB_SERIAL_KEYSPAN_MPR=y @@ -966,6 +1020,7 @@ CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_SERIAL_SAFE=m CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_TI=m CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OMNINET=m @@ -976,42 +1031,72 @@ CONFIG_USB_EZUSB=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set # CONFIG_USB_TEST is not set # +# USB ATM/DSL drivers +# + +# # USB Gadget Support # # CONFIG_USB_GADGET is not set # +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y -# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT3_FS_SECURITY=y CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=m +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=m # CONFIG_AUTOFS4_FS is not set @@ -1019,8 +1104,9 @@ CONFIG_AUTOFS_FS=m # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y CONFIG_UDF_FS=m CONFIG_UDF_NLS=y @@ -1044,6 +1130,8 @@ CONFIG_SYSFS=y CONFIG_DEVPTS_FS_XATTR=y # CONFIG_DEVPTS_FS_SECURITY is not set CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1053,8 +1141,8 @@ CONFIG_RAMFS=y # # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set @@ -1087,7 +1175,7 @@ CONFIG_RPCSEC_GSS_KRB5=y CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set # CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_POSIX is not set +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1117,7 +1205,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set +CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -1138,10 +1226,10 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_874 is not set # CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -1151,10 +1239,10 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_ISO8859_9 is not set # CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set +CONFIG_NLS_ISO8859_15=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +CONFIG_NLS_UTF8=y # # Profiling support @@ -1167,19 +1255,23 @@ CONFIG_OPROFILE=y # CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_FS=y # CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_KPROBES is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUGGER is not set # CONFIG_PPCDBG is not set CONFIG_IRQSTACKS=y -# CONFIG_SCHEDSTATS is not set # # Security options # +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # @@ -1193,7 +1285,7 @@ CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -# CONFIG_CRYPTO_WP512 is not set +CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m @@ -1201,19 +1293,24 @@ CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_KHAZAD is not set +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_MICHAEL_MIC=m -# CONFIG_CRYPTO_CRC32C is not set +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_TEST=m # +# Hardware crypto devices +# + +# # Library routines # CONFIG_CRC_CCITT=m CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m From olh at suse.de Tue Feb 8 01:48:33 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 7 Feb 2005 15:48:33 +0100 Subject: [PATCH] update ppc64 iSeries_defconfig In-Reply-To: <20050207144501.GC5516@suse.de> References: <20050207144228.GB5516@suse.de> <20050207144501.GC5516@suse.de> Message-ID: <20050207144833.GD5516@suse.de> update iSeries defconfig, compile tested. Signed-off-by: Olaf Hering diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc64/configs/iSeries_defconfig ./arch/ppc64/configs/iSeries_defconfig --- ../linux-2.6.11-rc3.orig/arch/ppc64/configs/iSeries_defconfig 2005-02-03 02:57:04.000000000 +0100 +++ ./arch/ppc64/configs/iSeries_defconfig 2005-02-07 14:15:15.000000000 +0100 @@ -1,9 +1,12 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.11-rc3-bk3 +# Mon Feb 7 14:15:15 2005 # CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y @@ -16,10 +19,12 @@ CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y +CONFIG_LOCK_KERNEL=y # # General setup # +CONFIG_LOCALVERSION="" CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -29,6 +34,7 @@ CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_EMBEDDED is not set @@ -37,12 +43,12 @@ CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set # @@ -52,8 +58,9 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not s