[PATCH 1/6] kvmppc: read device tree hypervisor node infrastructure
From: Christian Ehrhardt [EMAIL PROTECTED] This patch adds the guest portion of the device tree based host-guest communication. Using the device tree infrastructure this patch implements kvm_para_available and kvm_arch_para_features (in this patch just the infrastructure, no specific feature registered). Signed-off-by: Christian Ehrhardt [EMAIL PROTECTED] --- [diffstat] arch/powerpc/kernel/Makefile |2 ++ arch/powerpc/kernel/kvm.c | 30 ++ arch/powerpc/kernel/setup_32.c |3 +++ arch/powerpc/platforms/44x/Kconfig |7 +++ include/asm-powerpc/kvm_para.h | 37 ++--- 5 files changed, 76 insertions(+), 3 deletions(-) [diff] diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -80,6 +80,8 @@ obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o +obj-$(CONFIG_KVM_GUEST)+= kvm.o + ifneq ($(CONFIG_PPC_INDIRECT_IO),y) obj-y += iomap.o endif diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c new file mode 100644 --- /dev/null +++ b/arch/powerpc/kernel/kvm.c @@ -0,0 +1,30 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright IBM Corp. 2008 + * + * Authors: + * Hollis Blanchard [EMAIL PROTECTED] + * Christian Ehrhardt [EMAIL PROTECTED] + */ + +#include linux/percpu.h +#include linux/mm.h +#include linux/kvm_para.h + +void __init kvm_guest_init(void) +{ + if (!kvm_para_available()) + return; +} diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -17,6 +17,7 @@ #include linux/cpu.h #include linux/console.h #include linux/lmb.h +#include linux/kvm_para.h #include asm/io.h #include asm/prom.h @@ -319,5 +320,7 @@ ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress(arch: exit, 0x3eab); + kvm_guest_init(); + paging_init(); } diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -152,3 +152,10 @@ # 44x errata/workaround config symbols, selected by the CPU models above config IBM440EP_ERR42 bool + +config KVM_GUEST + bool KVM Guest support + depends on EXPERIMENTAL + help + This option enables various optimizations for running under the KVM + hypervisor. diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h --- a/include/asm-powerpc/kvm_para.h +++ b/include/asm-powerpc/kvm_para.h @@ -14,7 +14,9 @@ * * Copyright IBM Corp. 2008 * - * Authors: Hollis Blanchard [EMAIL PROTECTED] + * Authors: + * Hollis Blanchard [EMAIL PROTECTED] + * Christian Ehrhardt [EMAIL PROTECTED] */ #ifndef __POWERPC_KVM_PARA_H__ @@ -22,15 +24,44 @@ #ifdef __KERNEL__ +#include linux/of.h + +static struct kvmppc_para_features { + char *dtcell; + int feature; +} para_features[] = { +}; + static inline int kvm_para_available(void) { - return 0; + struct device_node *dn; + + dn = of_find_node_by_path(/hypervisor); + + return !!dn; } static inline unsigned int kvm_arch_para_features(void) { - return 0; + struct device_node *dn; + const int *dtval; + unsigned int features = 0; + int i; + + dn = of_find_node_by_path(/hypervisor); + if (!dn) + return 0; + + for (i = 0; i ARRAY_SIZE(para_features)-1; i++) { + dtval = of_get_property(dn, para_features[i].dtcell, NULL); + if (dtval *dtval == 1) + features |= (1 para_features[i].feature); + } + + return features; } + +void kvm_guest_init(void); #endif /* __KERNEL__ */ ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 5/6] kvmppc: magic page paravirtualization - guest part
From: Christian Ehrhardt [EMAIL PROTECTED] This patch adds the guest handling for the magic page mechanism. A Hypervisor can modify the device tree passed to the guest. Using that already existing interface a guest can simply detect available hypervisor features and agree on the supported ones using hypercalls. In this example it is checked for the feature switch feature,pv-magicpage in the hypervisor node and additional data which represents the size the hypervisor requests in data,pv-magicpage-size. When the guest read that data and wants to support it the memory is allocated and passed to the hypervisor using the KVM_HCALL_RESERVE_MAGICPAGE hypercall. Signed-off-by: Christian Ehrhardt [EMAIL PROTECTED] --- [diffstat] arch/powerpc/kernel/kvm.c | 48 + include/asm-powerpc/kvm_para.h | 27 ++- 2 files changed, 74 insertions(+), 1 deletion(-) [diff] diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -22,9 +22,57 @@ #include linux/percpu.h #include linux/mm.h #include linux/kvm_para.h +#include linux/bootmem.h + +/* + * this is guest memory granted to the hypervisor; + * the hypervisor can place data in this area and rewrite + * privileged instructions to read from this area without + * trapping. + * Only the Hypervisor needs to be aware of the structure layout + * which makes the guest more felxible - the guest only guarantees + * the size which is requested by the hypervisor and read from a + * device tree entry. + */ +void *kvm_magicpage; + +static void __init kvmppc_register_magic_page(void) +{ + unsigned long paddr; + int size; + long err; + + size = kvmppc_pv_read_data(KVM_PVDATA_MAGICPAGE_SIZE); + if (size 0) { + printk(KERN_ERR%s: couldn't read size for kvmppc style + paravirtualization support (got %d)\n, + __func__, size); + return; + } + + /* FIXME Guest SMP needs that percpu +* On SMP we might also need a free implementation */ + kvm_magicpage = alloc_bootmem(size); + if (!kvm_magicpage) { + printk(KERN_ERR%s - failed to allocate %d bytes\n, +__func__, size); + return; + } + + paddr = (unsigned long)__pa(kvm_magicpage); + err = kvm_hypercall1(KVM_HCALL_RESERVE_MAGICPAGE, paddr); + if (err) + printk(KERN_ERR%s: couldn't register magic page\n, __func__); + else + printk(KERN_NOTICE%s: registered %d bytes for + virtualization support\n, __func__, size); +} void __init kvm_guest_init(void) { if (!kvm_para_available()) return; + + if (kvm_para_has_feature(KVM_FEATURE_PPCPV_MAGICPAGE)) + kvmppc_register_magic_page(); } diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h --- a/include/asm-powerpc/kvm_para.h +++ b/include/asm-powerpc/kvm_para.h @@ -28,10 +28,18 @@ #define KVM_HYPERCALL_BIN 0x03ff +#define KVM_HCALL_RESERVE_MAGICPAGE0 + +#define KVM_PVDATA_MAGICPAGE_SIZE data,pv-magicpage-size + +/* List of PV features supported, returned as a bitfield */ +#define KVM_FEATURE_PPCPV_MAGICPAGE0 + static struct kvmppc_para_features { char *dtcell; int feature; } para_features[] = { + { feature,pv-magicpage, KVM_FEATURE_PPCPV_MAGICPAGE } }; static inline int kvm_para_available(void) @@ -54,13 +62,30 @@ if (!dn) return 0; - for (i = 0; i ARRAY_SIZE(para_features)-1; i++) { + for (i = 0; i ARRAY_SIZE(para_features); i++) { dtval = of_get_property(dn, para_features[i].dtcell, NULL); if (dtval *dtval == 1) features |= (1 para_features[i].feature); } return features; +} + +/* reads the specified data field out of the hypervisor node */ +static inline int kvmppc_pv_read_data(char *dtcell) +{ + struct device_node *dn; + const int *dtval; + + dn = of_find_node_by_path(/hypervisor); + if (!dn) + return -EINVAL; + + dtval = of_get_property(dn, dtcell, NULL); + if (dtval) + return *dtval; + else + return -EINVAL; } void kvm_guest_init(void); ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 3/6] kvmppc: add hypercall infrastructure - guest part
From: Christian Ehrhardt [EMAIL PROTECTED] This adds the guest portion of the hypercall infrastructure, basically an illegal instruction with a defined layout. See http://kvm.qumranet.com/kvmwiki/PowerPC_Hypercall_ABI for more detail on the hypercall ABI for powerpc. Signed-off-by: Christian Ehrhardt [EMAIL PROTECTED] --- [diffstat] kvm_para.h | 16 1 file changed, 16 insertions(+) [diff] diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h --- a/include/asm-powerpc/kvm_para.h +++ b/include/asm-powerpc/kvm_para.h @@ -25,6 +25,8 @@ #ifdef __KERNEL__ #include linux/of.h + +#define KVM_HYPERCALL_BIN 0x03ff static struct kvmppc_para_features { char *dtcell; @@ -63,6 +65,20 @@ void kvm_guest_init(void); +static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) +{ + register unsigned long hcall asm (r0) = nr; + register unsigned long arg1 asm (r3) = p1; + register long ret asm (r11); + + asm volatile(.long %1 + : =r(ret) + : i(KVM_HYPERCALL_BIN), r(hcall), r(arg1) + : r4, r5, r6, r7, r8, + r9, r10, r12, cc); + return ret; +} + #endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */ ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 6/6] kvmppc: kvm-userspace: device tree modification for magicpage
From: Christian Ehrhardt [EMAIL PROTECTED] This patch to kvm-userspace connects the other host guest patches in this series. On guest initialization it checks the hosts capabilities for the magicpage mechanism. If available the device tree passed to the guest gets the hypervisor node added and in that node the feature flag and the requested magic page size (read from the host kernel via an ioctl) is stored. Signed-off-by: Christian Ehrhardt [EMAIL PROTECTED] --- [diffstat] libkvm/libkvm-powerpc.c |6 ++ libkvm/libkvm.h |6 ++ qemu/hw/device_tree.c | 10 ++ qemu/hw/device_tree.h |1 + qemu/hw/ppc440_bamboo.c | 15 +++ qemu/qemu-kvm-powerpc.c |5 + qemu/qemu-kvm.h |1 + 7 files changed, 44 insertions(+) [diff] diff --git a/libkvm/libkvm-powerpc.c b/libkvm/libkvm-powerpc.c --- a/libkvm/libkvm-powerpc.c +++ b/libkvm/libkvm-powerpc.c @@ -19,6 +19,7 @@ #include libkvm.h #include kvm-powerpc.h +#include sys/ioctl.h #include errno.h #include stdio.h #include inttypes.h @@ -105,6 +106,11 @@ return 0; } +int kvm_get_magicpage_size(kvm_context_t kvm) +{ + return ioctl(kvm-fd, KVM_GET_PPCPV_MAGICPAGE_SIZE, 0); +} + int kvm_arch_run(struct kvm_run *run, kvm_context_t kvm, int vcpu) { int ret = 0; diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h --- a/libkvm/libkvm.h +++ b/libkvm/libkvm.h @@ -639,6 +639,12 @@ #endif +#ifdef KVM_CAP_PPCPV_MAGICPAGE + +int kvm_get_magicpage_size(kvm_context_t kvm); + +#endif + int kvm_translate(kvm_context_t kvm, int vcpu, struct kvm_translation *tr); #endif diff --git a/qemu/hw/device_tree.c b/qemu/hw/device_tree.c --- a/qemu/hw/device_tree.c +++ b/qemu/hw/device_tree.c @@ -190,4 +190,14 @@ exit(1); } } + +void dt_add_subnode(void *fdt, const char *name, char *node_path) +{ + int offset; + offset = get_offset_of_node(fdt, node_path); + if (fdt_add_subnode(fdt, offset, name) 0) { + printf(Unable to create device tree node '%s'\n, name); + exit(1); + } +} #endif diff --git a/qemu/hw/device_tree.h b/qemu/hw/device_tree.h --- a/qemu/hw/device_tree.h +++ b/qemu/hw/device_tree.h @@ -23,4 +23,5 @@ uint32_t *val_array, int size); void dt_string(void *fdt, char *node_path, char *property, char *string); +void dt_add_subnode(void *fdt, const char *name, char *node_path); #endif diff --git a/qemu/hw/ppc440_bamboo.c b/qemu/hw/ppc440_bamboo.c --- a/qemu/hw/ppc440_bamboo.c +++ b/qemu/hw/ppc440_bamboo.c @@ -51,6 +51,7 @@ uint32_t cpu_freq; uint32_t timebase_freq; uint32_t mem_reg_property[]={0, 0, ram_size}; + int pv_magicpage_size; printf(%s: START\n, __func__); @@ -167,6 +168,20 @@ dt_cell(fdt, /chosen, linux,initrd-end, (initrd_base + initrd_size)); dt_string(fdt, /chosen, bootargs, (char *)kernel_cmdline); + + if (kvm_enabled() +kvm_qemu_check_extension(KVM_CAP_PPCPV_MAGICPAGE)) { + pv_magicpage_size = kvmppc_pv_get_magicpage_size(); + if (pv_magicpage_size 0) { + fprintf(stderr, %s: error reading magic page size\n, +__func__); + exit(1); + } + dt_add_subnode(fdt, hypervisor, /); + dt_cell(fdt, /hypervisor, feature,pv-magicpage, 1); + dt_cell(fdt, /hypervisor, data,pv-magicpage-size, + pv_magicpage_size); + } #endif if (kvm_enabled()) { diff --git a/qemu/qemu-kvm-powerpc.c b/qemu/qemu-kvm-powerpc.c --- a/qemu/qemu-kvm-powerpc.c +++ b/qemu/qemu-kvm-powerpc.c @@ -214,6 +214,11 @@ return 0; /* XXX ignore failed DCR ops */ } +int kvmppc_pv_get_magicpage_size(void) +{ + return kvm_get_magicpage_size(kvm_context); +} + int mmukvm_get_physical_address(CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int access_type) { diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h --- a/qemu/qemu-kvm.h +++ b/qemu/qemu-kvm.h @@ -86,6 +86,7 @@ #ifdef TARGET_PPC int handle_powerpc_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data); int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data); +int kvmppc_pv_get_magicpage_size(); #endif #if !defined(SYS_signalfd) ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 0/6][RFC] kvmppc: paravirtualization interface
From: Christian Ehrhardt [EMAIL PROTECTED] This patch series implements a paravirtualization interface using: - the device tree mechanism to pass hypervisor informations to the guest - hypercalls for guest-host calls - an example exploiter of that interface (magic page) This is work in progress, but working so far. I just start to really exploit the fuctionality behind the magic page mechanism therefor I can't provide any performance improvements so far, but it is evolved enough for RFC and to start the standardization discussion. The used hypercall ABI was already discussed on the embedded-hypervisor mailing list and is available at http://kvm.qumranet.com/kvmwiki/PowerPC_Hypercall_ABI The device tree format used here (=base for the discussions on embedded-hypervisor) is the following. - A node hypervisor to show the general availability of some hypervisor data - flags for features like the example feature,pv-magicpage setting 1 = available, everything else = unavailable - Some features might need to pass more data and can use an entry in the device tree like the example of data,pv-magicpage-size Parties on cc: linuxppc-dev@ozlabs.org The patches affect code in the generic powerpc bootsetup so I would be happy about comments if the hooks are ok that way. [EMAIL PROTECTED] This power.org TSC discusses about standardization of the virtualization interfaces. This patch series is perfectly suited due to it's simple changes to start the discussion about the device tree there. [EMAIL PROTECTED] The code is made for kvm on powerpc which lives on this list. [patches in series] Subject: [PATCH 1/6] kvmppc: read device tree hypervisor node infrastructure Providing the guest functionality to read hypervisor features from the device tree and adding the basic hook to the powerpc boot6setup code Subject: [PATCH 2/6] kvmppc: add hypercall infrastructure - host part Subject: [PATCH 3/6] kvmppc: add hypercall infrastructure - guest part patch 23 add the hypercall infrastruture as mentioned above Subject: [PATCH 4/6] kvmppc: magic page hypercall - host part Subject: [PATCH 5/6] kvmppc: magic page paravirtualization - guest part patch 45 add the magic page mechanism which will later on be used for binary rewriting the guest. Subject: [PATCH 6/6] kvmppc: kvm-userspace: device tree modification for magicpage This connects host and guest reading host capabilities and modifying the device tree passed to the guest accordingly --- [diffstat] arch/powerpc/kernel/kvm.c| 48 +++ arch/powerpc/kvm/emulate.c |5 +++ b/arch/powerpc/kernel/Makefile |2 + b/arch/powerpc/kernel/kvm.c | 30 + b/arch/powerpc/kernel/setup_32.c |3 ++ b/arch/powerpc/kvm/emulate.c | 27 +++ b/arch/powerpc/kvm/powerpc.c | 18 - b/arch/powerpc/platforms/44x/Kconfig |7 + b/include/asm-powerpc/kvm_para.h | 37 -- b/include/linux/kvm.h|6 b/libkvm/libkvm-powerpc.c|6 b/libkvm/libkvm.h|6 b/qemu/hw/device_tree.c | 10 +++ b/qemu/hw/device_tree.h |1 b/qemu/hw/ppc440_bamboo.c| 15 ++ b/qemu/qemu-kvm-powerpc.c|5 +++ b/qemu/qemu-kvm.h|1 include/asm-powerpc/kvm_para.h | 47 +- 18 files changed, 269 insertions(+), 5 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 4/6] kvmppc: magic page hypercall - host part
From: Christian Ehrhardt [EMAIL PROTECTED] This adds the host part of the magic page registration. This is a memory area of the guest granted to the host. The patch just introduces the infrastruture to receive the guest paddr. This is work in progress and it is intended to later on use this memory as storage area a guest can read unprivileged (using binary rewriting to change privileges instructions). Signed-off-by: Christian Ehrhardt [EMAIL PROTECTED] --- [diffstat] arch/powerpc/kvm/emulate.c |5 + arch/powerpc/kvm/powerpc.c | 18 +- include/asm-powerpc/kvm_para.h |2 ++ include/linux/kvm.h|6 ++ 4 files changed, 30 insertions(+), 1 deletion(-) [diff] diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -208,6 +208,11 @@ int ret = 0; switch (vcpu-arch.gpr[0]) { + case KVM_HCALL_RESERVE_MAGICPAGE: + /* FIXME TODO implement the real fuctionality using that */ + printk(KERN_ERR%s - receive magicpage address 0x%x\n, + __func__, vcpu-arch.gpr[3]); + break; default: printk(KERN_ERRunknown hypercall %d\n, vcpu-arch.gpr[0]); kvmppc_dump_vcpu(vcpu); diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -148,6 +148,9 @@ case KVM_CAP_COALESCED_MMIO: r = KVM_COALESCED_MMIO_PAGE_OFFSET; break; + case KVM_CAP_PPCPV_MAGICPAGE: + r = 1; + break; default: r = 0; break; @@ -159,7 +162,20 @@ long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { - return -EINVAL; + long r = -EINVAL; + + switch (ioctl) { + case KVM_GET_PPCPV_MAGICPAGE_SIZE: + r = -EINVAL; + if (arg) + goto out; + r = 1024; + break; + default: + r = -EINVAL; + } +out: + return r; } int kvm_arch_set_memory_region(struct kvm *kvm, diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h --- a/include/asm-powerpc/kvm_para.h +++ b/include/asm-powerpc/kvm_para.h @@ -24,6 +24,8 @@ #define KVM_HYPERCALL_BIN 0x03ff +#define KVM_HCALL_RESERVE_MAGICPAGE0 + static inline int kvm_para_available(void) { return 0; diff --git a/include/linux/kvm.h b/include/linux/kvm.h --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -365,6 +365,11 @@ #define KVM_TRACE_PAUSE _IO(KVMIO, 0x07) #define KVM_TRACE_DISABLE _IO(KVMIO, 0x08) /* + * ioctls for powerpc paravirtualization extensions + */ +#define KVM_GET_PPCPV_MAGICPAGE_SIZE _IO(KVMIO, 0x09) + +/* * Extension capability list. */ #define KVM_CAP_IRQCHIP 0 @@ -382,6 +387,7 @@ #define KVM_CAP_PV_MMU 13 #define KVM_CAP_MP_STATE 14 #define KVM_CAP_COALESCED_MMIO 15 +#define KVM_CAP_PPCPV_MAGICPAGE 16 /* * ioctls for VM fds ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 2/6] kvmppc: add hypercall infrastructure - host part
From: Christian Ehrhardt [EMAIL PROTECTED] This adds the host portion of the hypercall infrastructure which receives the guest calls - no specific hcall function is implemented in this patch. Signed-off-by: Christian Ehrhardt [EMAIL PROTECTED] --- [diffstat] arch/powerpc/kvm/emulate.c | 27 +++ include/asm-powerpc/kvm_para.h |2 ++ 2 files changed, 29 insertions(+) [diff] diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -203,6 +203,24 @@ kvmppc_set_msr(vcpu, vcpu-arch.srr1); } +static int kvmppc_do_hypercall(struct kvm_vcpu *vcpu) +{ + int ret = 0; + + switch (vcpu-arch.gpr[0]) { + default: + printk(KERN_ERRunknown hypercall %d\n, vcpu-arch.gpr[0]); + kvmppc_dump_vcpu(vcpu); + ret = -ENOSYS; + } + + vcpu-arch.gpr[11] = ret; + vcpu-arch.pc += 4; /* Advance past hypercall instruction. */ + + return ret; +} + + /* XXX to do: * lhax * lhaux @@ -232,6 +250,15 @@ int advance = 1; switch (get_op(inst)) { + case 0: + if (inst == KVM_HYPERCALL_BIN) { + kvmppc_do_hypercall(vcpu); + advance = 0; /* kvmppc_do_hypercall handles the PC. */ + } else { + printk(KERN_ERRunknown op %d\n, get_op(inst)); + emulated = EMULATE_FAIL; + } + break; case 3: /* trap */ printk(trap!\n); kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM); diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h --- a/include/asm-powerpc/kvm_para.h +++ b/include/asm-powerpc/kvm_para.h @@ -22,6 +22,8 @@ #ifdef __KERNEL__ +#define KVM_HYPERCALL_BIN 0x03ff + static inline int kvm_para_available(void) { return 0; ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [alsa-devel] [PATCH 1/2] Support internal I2S clock sources on MPC5200
On Tue, Jul 22, 2008 at 07:53:49PM -0400, Jon Smirl wrote: Support internal I2S clock sources on MPC5200 Looks good from an ASoC point of view. There's quite a few checkpatch warnings that should be fixed (all fairly straightforward, though) but other than that I'm happy to apply it with Grant's ack. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [alsa-devel] [PATCH 2/2] Allow a custom ASOC machine driver with soc-of-simple
On Tue, Jul 22, 2008 at 07:53:51PM -0400, Jon Smirl wrote: Allow a custom ASOC machine driver with soc-of-simple As with the clocking configuration: this looks fine from an ASoC point of view but please fix the checkpatch warnings. However... /* Only register the device if both the codec and platform have * been registered */ - if ((!of_soc-device.codec_data) || (!of_soc-platform_node)) + if ((!of_soc-device.codec_data) || (!of_soc-platform_node) || !machine_name) return; ...this doesn't just allow a custom machine driver, it requires that something configures at least the machine name. That's not a problem from the ASoC point of view but possibly from the PowerPC side? ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [RFC] 4xx hardware watchpoint support
On Jul 22, 2008, at 8:47 PM, Luis Machado wrote: Hi, That, or adding a small function to move the bits to the appropriate registers (set_dbcr or set_dac_events). Do you think it's worth to support this facility on 405's processors? If so, i'll gladly work on a solution to it. I would think so. There's really no difference from a userspace perspective, so gdb watchpoints could be valuable there too. I'll leave it up to you though. As the 440 support is ready and the 405 needs additional tweaking due to the use of DBCR1 instead of DBCR0 and due to a different position scheme of the DAC1R/DAC1W flags inside DBCR1, i'd say we should include this code and handle the 405 case later. We might have to handle it anyway if we're going to pursue the hardware breakpoint interface work in the future. I've fixed some formatting problems. Tested on a 440 Taishan board and on a PPC970. Both worked as they should. Ok? I'd like to test this on some Freescale Book-e parts. Is there a gdb patch or some user space ptrace test you have? - k ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [alsa-devel] [PATCH 2/2] Allow a custom ASOC machine driver with soc-of-simple
On 7/23/08, Mark Brown [EMAIL PROTECTED] wrote: On Tue, Jul 22, 2008 at 07:53:51PM -0400, Jon Smirl wrote: Allow a custom ASOC machine driver with soc-of-simple As with the clocking configuration: this looks fine from an ASoC point of view but please fix the checkpatch warnings. However... /* Only register the device if both the codec and platform have * been registered */ - if ((!of_soc-device.codec_data) || (!of_soc-platform_node)) + if ((!of_soc-device.codec_data) || (!of_soc-platform_node) || !machine_name) return; ...this doesn't just allow a custom machine driver, it requires that something configures at least the machine name. That's not a problem from the ASoC point of view but possibly from the PowerPC side? You have to configure at least the name. Otherwise if the machine driver is the last to register, how do you know to hold off the final registration and wait for the machine driver to appear? Or is it ok for me to change these after the platform device has been created? of_soc-dai_link.ops = machine_ops; of_soc-machine.name = machine_name; I have to have the machine driver in order to control my external clock chips. -- Jon Smirl [EMAIL PROTECTED] ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
arch/powerpc/kernel/stacktrace.c: Removed duplicated include
Removed duplicated include file linux/module.h in arch/powerpc/kernel/stacktrace.c. Signed-off-by: Huang Weiyi [EMAIL PROTECTED] diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index f258964..b0dbb1d 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -13,7 +13,6 @@ #include linux/module.h #include linux/sched.h #include linux/stacktrace.h -#include linux/module.h #include asm/ptrace.h #include asm/processor.h ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: PIXIS gpio controller and gpio flags
On Mon, Jul 21, 2008 at 02:12:20PM -0700, Trent Piepho wrote: On Mon, 21 Jul 2008, Anton Vorontsov wrote: On Sat, Jul 19, 2008 at 02:08:01PM -0700, Trent Piepho wrote: It doesn't look like you have any way to unset the active low flag. What if I unload the leds-gpio driver (or another gpio user) and then try to use the gpio with something else? The active low flag is stuck on! Why would you want to unset the flags? It is specified in the device tree, and can't be changed. Specifying different flags for the same GPIO would be an error (plus, Linux forbids shared gpios, so you simply can't specify one gpio for several devices). You can't use the same gpio for two different things at the same time, but you can load a driver, unload it, and then load another. Hm.. yeah, this might happen. Now I tend to think that transparent active-low handling wasn't that good idea after all. So, something like of_gpio_is_active_low(device_node, gpioidx) should be implemented instead. This function will parse the gpio's = flags. Please speak up if you have any better ideas though. Thanks for bringing this up, -- Anton Vorontsov email: [EMAIL PROTECTED] irc://irc.freenode.net/bd2 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
DTS configuration of external interrupts on 8347
I have a small problem with a port of linux 2.6.26 to a custom board. Our board is almost identical to the Analogue Micro asp 8347 board, so I'm using Kumar Gala's excellent fsl tree (thank you Kumar) as it already has a defconfig for the asp. Thanks also to Bryan O'Donoghue for pointing us in the direction of the asp port in the first place. The problem we have is I am unable to request an external interrupt. We have an FPGA which has an interrupt line - HW IRQ_0, so thats linux IRQ 48. I have added the following to the dts file: [EMAIL PROTECTED] { interrupts = 48 8; interrupt-parent = ipic; } but whenever I call request_irq() it returns -ENOSYS. The driver loads fine, and the open function does very little - a call to ioremap() - which works, and a call to request_irq() which does not. Is there anything else I have to do to configure this interrupt? Regards, Richard. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 0/2][RT] powerpc - fix bug in irq reverse mapping radix tree
Hi, here are 2 patches for fixing the following bug occuring on IBM pSeries under an RT kernel: BUG: sleeping function called from invalid context swapper(1) at kernel/rtmutex.c:739 in_atomic():1 [0002], irqs_disabled():1 Call Trace: [c001e20f3340] [c0010370] .show_stack+0x70/0x1bc (unreliable) [c001e20f33f0] [c0049380] .__might_sleep+0x11c/0x138 [c001e20f3470] [c02a2f64] .__rt_spin_lock+0x3c/0x98 [c001e20f34f0] [c00c3f20] .kmem_cache_alloc+0x68/0x184 [c001e20f3590] [c0193f3c] .radix_tree_node_alloc+0xf0/0x144 [c001e20f3630] [c0195190] .radix_tree_insert+0x18c/0x2fc [c001e20f36f0] [c000c710] .irq_radix_revmap+0x1a4/0x1e4 [c001e20f37b0] [c003b3f0] .xics_startup+0x30/0x54 [c001e20f3840] [c008b864] .setup_irq+0x26c/0x370 [c001e20f38f0] [c008ba68] .request_irq+0x100/0x158 [c001e20f39a0] [c01ee9c0] .hvc_open+0xb4/0x148 [c001e20f3a40] [c01d72ec] .tty_open+0x200/0x368 [c001e20f3af0] [c00ce928] .chrdev_open+0x1f4/0x25c [c001e20f3ba0] [c00c8bf0] .__dentry_open+0x188/0x2c8 [c001e20f3c50] [c00c8dec] .do_filp_open+0x50/0x70 [c001e20f3d70] [c00c8e8c] .do_sys_open+0x80/0x148 [c001e20f3e20] [c000928c] .init_post+0x4c/0x100 [c001e20f3ea0] [c03c0e0c] .kernel_init+0x428/0x478 [c001e20f3f90] [c0027448] .kernel_thread+0x4c/0x68 The root cause of this bug lies in the fact that the XICS interrupt controller uses a radix tree for its reverse irq mapping and that we cannot allocate the tree nodes (even GFP_ATOMIC) with preemption disabled. In fact, we have 2 nested preemption disabling when we want to allocate a new node: - setup_irq() does a spin_lock_irqsave() before calling xics_startup() which then calls irq_radix_revmap() to insert a new node in the tree - irq_radix_revmap() also does a spin_lock_irqsave() (in irq_radix_wrlock()) before the radix_tree_insert() The first patch moves the call to irq_radix_revmap() from xics_startup() out to xics_host_map_direct() and xics_host_map_lpar() which are called with preemption enabled. The second patch is a little more involved in that it takes advantage of the concurrent radix tree to simplify the locking requirements and allows to allocate a new node outside a preemption disabled section. I just hope I've correctly understood the concurrent radix trees semantic and got the (absence of) locking right. Sebastien. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 1/2][RT] powerpc - XICS: move the call to irq_radix_revmap from xics_startup to xics_host_map
From: Sebastien Dugue [EMAIL PROTECTED] Date: Tue, 22 Jul 2008 13:05:24 +0200 Subject: [PATCH][RT] powerpc - XICS: move the call to irq_radix_revmap from xics_startup to xics_host_map This patch moves the insertion of an irq into the reverse mapping radix tree from xics_startup() into xics_host_map(). The reason for this change is that xics_startup() is called with preemption disabled (which is not the case for xics_host_map()) which is a problem under a preempt-rt kernel as we cannot even allocate GFP_ATOMIC memory for the radix tree nodes. Signed-off-by: Sebastien Dugue [EMAIL PROTECTED] Cc: Benjamin Herrenschmidt [EMAIL PROTECTED] Cc: Paul Mackerras [EMAIL PROTECTED] Cc: Michael Ellerman [EMAIL PROTECTED] --- arch/powerpc/platforms/pseries/xics.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) Index: linux-2.6.25.8-rt7/arch/powerpc/platforms/pseries/xics.c === --- linux-2.6.25.8-rt7.orig/arch/powerpc/platforms/pseries/xics.c +++ linux-2.6.25.8-rt7/arch/powerpc/platforms/pseries/xics.c @@ -311,12 +311,6 @@ static void xics_mask_irq(unsigned int v static unsigned int xics_startup(unsigned int virq) { - unsigned int irq; - - /* force a reverse mapping of the interrupt so it gets in the cache */ - irq = (unsigned int)irq_map[virq].hwirq; - irq_radix_revmap(xics_host, irq); - /* unmask it */ xics_unmask_irq(virq); return 0; @@ -529,8 +523,14 @@ static int xics_host_match(struct irq_ho static int xics_host_map_direct(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { + unsigned int irq; + pr_debug(xics: map_direct virq %d, hwirq 0x%lx\n, virq, hw); + /* force a reverse mapping of the interrupt so it gets in the cache */ + irq = (unsigned int)irq_map[virq].hwirq; + irq_radix_revmap(xics_host, irq); + get_irq_desc(virq)-status |= IRQ_LEVEL; set_irq_chip_and_handler(virq, xics_pic_direct, handle_fasteoi_irq); return 0; @@ -539,8 +539,14 @@ static int xics_host_map_direct(struct i static int xics_host_map_lpar(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { + unsigned int irq; + pr_debug(xics: map_direct virq %d, hwirq 0x%lx\n, virq, hw); + /* force a reverse mapping of the interrupt so it gets in the cache */ + irq = (unsigned int)irq_map[virq].hwirq; + irq_radix_revmap(xics_host, irq); + get_irq_desc(virq)-status |= IRQ_LEVEL; set_irq_chip_and_handler(virq, xics_pic_lpar, handle_fasteoi_irq); return 0; ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 2/2][RT] powerpc - Make the irq reverse mapping radix tree lockless
From: Sebastien Dugue [EMAIL PROTECTED] Date: Tue, 22 Jul 2008 11:56:41 +0200 Subject: [PATCH][RT] powerpc - Make the irq reverse mapping radix tree lockless The radix tree used by interrupt controllers for their irq reverse mapping (currently only the XICS found on pSeries) have a complex locking scheme dating back to before the advent of the concurrent radix tree on preempt-rt. Take advantage of this and of the fact that the items of the tree are pointers to a static array (irq_map) elements which can never go under us to simplify the locking. Concurrency between readers and writers are handled by the intrinsic properties of the concurrent radix tree. Concurrency between the tree initialization which is done asynchronously with readers and writers access is handled via an atomic variable (revmap_trees_allocated) set when the tree has been initialized and checked before any reader or writer access just like we used to check for tree.gfp_mask != 0 before. Signed-off-by: Sebastien Dugue [EMAIL PROTECTED] Cc: Benjamin Herrenschmidt [EMAIL PROTECTED] Cc: Paul Mackerras [EMAIL PROTECTED] --- arch/powerpc/kernel/irq.c | 102 -- 1 file changed, 27 insertions(+), 75 deletions(-) Index: linux-2.6.25.8-rt7/arch/powerpc/kernel/irq.c === --- linux-2.6.25.8-rt7.orig/arch/powerpc/kernel/irq.c +++ linux-2.6.25.8-rt7/arch/powerpc/kernel/irq.c @@ -403,8 +403,7 @@ void do_softirq(void) static LIST_HEAD(irq_hosts); static DEFINE_RAW_SPINLOCK(irq_big_lock); -static DEFINE_PER_CPU(unsigned int, irq_radix_reader); -static unsigned int irq_radix_writer; +static atomic_t revmap_trees_allocated = ATOMIC_INIT(0); struct irq_map_entry irq_map[NR_IRQS]; static unsigned int irq_virq_count = NR_IRQS; static struct irq_host *irq_default_host; @@ -547,57 +546,6 @@ void irq_set_virq_count(unsigned int cou irq_virq_count = count; } -/* radix tree not lockless safe ! we use a brlock-type mecanism - * for now, until we can use a lockless radix tree - */ -static void irq_radix_wrlock(unsigned long *flags) -{ - unsigned int cpu, ok; - - spin_lock_irqsave(irq_big_lock, *flags); - irq_radix_writer = 1; - smp_mb(); - do { - barrier(); - ok = 1; - for_each_possible_cpu(cpu) { - if (per_cpu(irq_radix_reader, cpu)) { - ok = 0; - break; - } - } - if (!ok) - cpu_relax(); - } while(!ok); -} - -static void irq_radix_wrunlock(unsigned long flags) -{ - smp_wmb(); - irq_radix_writer = 0; - spin_unlock_irqrestore(irq_big_lock, flags); -} - -static void irq_radix_rdlock(unsigned long *flags) -{ - local_irq_save(*flags); - __get_cpu_var(irq_radix_reader) = 1; - smp_mb(); - if (likely(irq_radix_writer == 0)) - return; - __get_cpu_var(irq_radix_reader) = 0; - smp_wmb(); - spin_lock(irq_big_lock); - __get_cpu_var(irq_radix_reader) = 1; - spin_unlock(irq_big_lock); -} - -static void irq_radix_rdunlock(unsigned long flags) -{ - __get_cpu_var(irq_radix_reader) = 0; - local_irq_restore(flags); -} - static int irq_setup_virq(struct irq_host *host, unsigned int virq, irq_hw_number_t hwirq) { @@ -752,7 +700,6 @@ void irq_dispose_mapping(unsigned int vi { struct irq_host *host; irq_hw_number_t hwirq; - unsigned long flags; if (virq == NO_IRQ) return; @@ -784,15 +731,20 @@ void irq_dispose_mapping(unsigned int vi if (hwirq host-revmap_data.linear.size) host-revmap_data.linear.revmap[hwirq] = NO_IRQ; break; - case IRQ_HOST_MAP_TREE: + case IRQ_HOST_MAP_TREE: { + DEFINE_RADIX_TREE_CONTEXT(ctx, host-revmap_data.tree); + /* Check if radix tree allocated yet */ - if (host-revmap_data.tree.gfp_mask == 0) + if (atomic_read(revmap_trees_allocated) == 0) break; - irq_radix_wrlock(flags); - radix_tree_delete(host-revmap_data.tree, hwirq); - irq_radix_wrunlock(flags); + + radix_tree_lock(ctx); + radix_tree_delete(ctx.tree, hwirq); + radix_tree_unlock(ctx); + break; } + } /* Destroy map */ smp_mb(); @@ -845,22 +797,20 @@ unsigned int irq_radix_revmap(struct irq struct radix_tree_root *tree; struct irq_map_entry *ptr; unsigned int virq; - unsigned long flags; WARN_ON(host-revmap_type != IRQ_HOST_MAP_TREE); - /* Check if the radix tree exist yet. We test the value of -* the gfp_mask for that. Sneaky but
Re: [alsa-devel] [PATCH 2/2] Allow a custom ASOC machine driver with soc-of-simple
On Wed, Jul 23, 2008 at 10:09:01AM -0400, Jon Smirl wrote: On 7/23/08, Mark Brown [EMAIL PROTECTED] wrote: ...this doesn't just allow a custom machine driver, it requires that something configures at least the machine name. That's not a problem from the ASoC point of view but possibly from the PowerPC side? You have to configure at least the name. Otherwise if the machine driver is the last to register, how do you know to hold off the final registration and wait for the machine driver to appear? I understand why you have made this change but it's a substantial change which should at least be documented in the changelog (I'd expect to see some mention of how this is supposed to be configured, for example). I'd also expect something to handle the existing user. Like I said, I'm not entirely sure that you're supposed to be using this driver if you want a machine driver: this is a machine driver and I'm not sure if it's supposed to cover all cases or not. Grant? Or is it ok for me to change these after the platform device has been created? of_soc-dai_link.ops = machine_ops; of_soc-machine.name = machine_name; No. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [alsa-devel] [PATCH 2/2] Allow a custom ASOC machine driver with soc-of-simple
On 7/23/08, Mark Brown [EMAIL PROTECTED] wrote: On Wed, Jul 23, 2008 at 10:09:01AM -0400, Jon Smirl wrote: On 7/23/08, Mark Brown [EMAIL PROTECTED] wrote: ...this doesn't just allow a custom machine driver, it requires that something configures at least the machine name. That's not a problem from the ASoC point of view but possibly from the PowerPC side? You have to configure at least the name. Otherwise if the machine driver is the last to register, how do you know to hold off the final registration and wait for the machine driver to appear? I understand why you have made this change but it's a substantial change which should at least be documented in the changelog (I'd expect to see some mention of how this is supposed to be configured, for example). I'd also expect something to handle the existing user. This is a modification to Grant's new driver. Grant is the only other user. Like I said, I'm not entirely sure that you're supposed to be using this driver if you want a machine driver: this is a machine driver and I'm not sure if it's supposed to cover all cases or not. Grant? Or is it ok for me to change these after the platform device has been created? of_soc-dai_link.ops = machine_ops; of_soc-machine.name = machine_name; No. -- Jon Smirl [EMAIL PROTECTED] ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH] libfdt: Fix 'make install' target handling of .h files.
The definition of LIBFDT_INCLUDES was accidentally dropped. Put it back and add srcdir prefix handling for it. Signed-off-by: Jon Loeliger [EMAIL PROTECTED] --- Makefile |4 +++- libfdt/Makefile.libfdt |1 + 2 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Makefile b/Makefile index e871855..0222dc0 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ install: all $(INSTALL) -d $(DESTDIR)$(LIBDIR) $(INSTALL) -m 644 $(LIBFDT_lib) $(DESTDIR)$(LIBDIR) $(INSTALL) -d $(DESTDIR)$(INCLUDEDIR) - $(INSTALL) -m 644 $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES)) $(DESTDIR)$(INCLUDEDIR) + $(INSTALL) -m 644 $(LIBFDT_include) $(DESTDIR)$(INCLUDEDIR) # # Rules for versioning @@ -140,6 +140,8 @@ endif LIBFDT_objdir = libfdt LIBFDT_srcdir = libfdt LIBFDT_lib = $(LIBFDT_objdir)/libfdt.a +LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES)) + include $(LIBFDT_srcdir)/Makefile.libfdt .PHONY: libfdt diff --git a/libfdt/Makefile.libfdt b/libfdt/Makefile.libfdt index f4f495b..6c42acf 100644 --- a/libfdt/Makefile.libfdt +++ b/libfdt/Makefile.libfdt @@ -3,5 +3,6 @@ # This is not a complete Makefile of itself. Instead, it is designed to # be easily embeddable into other systems of Makefiles. # +LIBFDT_INCLUDES = fdt.h libfdt.h LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) -- 1.5.6.3.439.g1e10 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [alsa-devel] [PATCH 2/2] Allow a custom ASOC machine driver with soc-of-simple
On Wed, Jul 23, 2008 at 11:16:17AM -0400, Jon Smirl wrote: On 7/23/08, Mark Brown [EMAIL PROTECTED] wrote: I'd also expect something to handle the existing user. This is a modification to Grant's new driver. Grant is the only other user. Right, hence my use of the singular : ) . Since you are adding this new of_snd_soc_register_machine() Grant's existing platform won't be calling it yet and will therefore stop instantiating the ASoC subsystem until it is changed to do so. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [RFC] 4xx hardware watchpoint support
Some comment, first the above negate conditional looks rather ugly, I'd rather do a #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) dbcr0 case #else dabr case #endif Yes, it makes sense. I'll switch it around. second I wonder why we have the notify_die only for one case, that seems rather odd. Looking further the notify_die is even more odd because DIE_DABR_MATCH doesn't actually appear anywhere else in the kernel. I'd suggest simply removing it. DIE_DABR_MATCH doesn't appear anywhere else because there is only a single function responsible for handling the DABR/DAC events on powerPC with this modification. It would make sense to call this to both the DAC/DABR cases though (i.e. taking it out of the #ifdef), what do you think? Can you redo this in the normal Linux comment style, ala: /* * For processors using DABR (i.e. 970), the bottom 3 bits are flags. * It was assumed, on previous implementations, that 3 bits were * passed together with the data address, fitting the design of the * DABR register, as follows: * * bit 0: Read flag * bit 1: Write flag * bit 2: Breakpoint translation * * Thus, we use them here as so. */ and similar in few other places. Will do, thanks for reviewing this one. Regards, Luis ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [RFC] 4xx hardware watchpoint support
On Wed, 2008-07-23 at 11:53 -0400, Josh Boyer wrote: Shouldn't this (and other places) be: #if defined(CONFIG_44x) || defined(CONFIG_BOOKE) if you are going to exclude 40x for now? Otherwise this is still enabled on 405 and setting the wrong register. josh Yes, sorry. I wasn't aware of this specific define value. It makes things easier to support 405's later. Like so? This addresses Christoph's comments as well. Signed-off-by: Luis Machado [EMAIL PROTECTED] Index: linux-2.6.26/arch/powerpc/kernel/entry_32.S === --- linux-2.6.26.orig/arch/powerpc/kernel/entry_32.S2008-07-23 07:44:57.0 -0700 +++ linux-2.6.26/arch/powerpc/kernel/entry_32.S 2008-07-23 07:50:31.0 -0700 @@ -148,7 +148,7 @@ /* Check to see if the dbcr0 register is set up to debug. Use the internal debug mode bit to do this. */ lwz r12,THREAD_DBCR0(r12) - andis. r12,r12,[EMAIL PROTECTED] + andis. r12,r12,(DBCR0_IDM | DBSR_DAC1R | DBSR_DAC1W)@h beq+3f /* From user and task is ptraced - load up global dbcr0 */ li r12,-1 /* clear all pending debug events */ @@ -292,7 +292,7 @@ /* If the process has its own DBCR0 value, load it up. The internal debug mode bit tells us that dbcr0 should be loaded. */ lwz r0,THREAD+THREAD_DBCR0(r2) - andis. r10,r0,[EMAIL PROTECTED] + andis. r10,r0,(DBCR0_IDM | DBSR_DAC1R | DBSR_DAC1W)@h bnel- load_dbcr0 #endif #ifdef CONFIG_44x @@ -720,7 +720,7 @@ /* Check whether this process has its own DBCR0 value. The internal debug mode bit tells us that dbcr0 should be loaded. */ lwz r0,THREAD+THREAD_DBCR0(r2) - andis. r10,r0,[EMAIL PROTECTED] + andis. r10,r0,(DBCR0_IDM | DBSR_DAC1R | DBSR_DAC1W)@h bnel- load_dbcr0 #endif Index: linux-2.6.26/arch/powerpc/kernel/process.c === --- linux-2.6.26.orig/arch/powerpc/kernel/process.c 2008-07-23 07:44:57.0 -0700 +++ linux-2.6.26/arch/powerpc/kernel/process.c 2008-07-23 07:50:31.0 -0700 @@ -47,6 +47,8 @@ #ifdef CONFIG_PPC64 #include asm/firmware.h #endif +#include linux/kprobes.h +#include linux/kdebug.h extern unsigned long _get_SP(void); @@ -239,6 +241,35 @@ } #endif /* CONFIG_SMP */ +void do_dabr(struct pt_regs *regs, unsigned long address, + unsigned long error_code) +{ + siginfo_t info; + + if (notify_die(DIE_DABR_MATCH, dabr_match, regs, error_code, + 11, SIGSEGV) == NOTIFY_STOP) + return; + + if (debugger_dabr_match(regs)) + return; + + /* Clear the DAC and struct entries. One shot trigger */ +#if (defined(CONFIG_44x) || defined(CONFIG_BOOKE)) + mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) ~(DBSR_DAC1R | DBSR_DAC1W + | DBCR0_IDM)); +#endif + + /* Clear the DABR */ + set_dabr(0); + + /* Deliver the signal to userspace */ + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_HWBKPT; + info.si_addr = (void __user *)address; + force_sig_info(SIGTRAP, info, current); +} + static DEFINE_PER_CPU(unsigned long, current_dabr); int set_dabr(unsigned long dabr) @@ -254,6 +285,11 @@ #if defined(CONFIG_PPC64) || defined(CONFIG_6xx) mtspr(SPRN_DABR, dabr); #endif + +#if defined(CONFIG_44x) || defined(CONFIG_BOOKE) + mtspr(SPRN_DAC1, dabr); +#endif + return 0; } @@ -337,6 +373,12 @@ if (unlikely(__get_cpu_var(current_dabr) != new-thread.dabr)) set_dabr(new-thread.dabr); +#if defined(CONFIG_44x) || defined(CONFIG_BOOKE) + /* If new thread DAC (HW breakpoint) is the same then leave it */ + if (new-thread.dabr) + set_dabr(new-thread.dabr); +#endif + new_thread = new-thread; old_thread = current-thread; @@ -525,6 +567,10 @@ if (current-thread.dabr) { current-thread.dabr = 0; set_dabr(0); + +#if defined(CONFIG_44x) || defined(CONFIG_BOOKE) + current-thread.dbcr0 = ~(DBSR_DAC1R | DBSR_DAC1W); +#endif } } Index: linux-2.6.26/arch/powerpc/kernel/ptrace.c === --- linux-2.6.26.orig/arch/powerpc/kernel/ptrace.c 2008-07-23 07:44:57.0 -0700 +++ linux-2.6.26/arch/powerpc/kernel/ptrace.c 2008-07-23 07:53:45.0 -0700 @@ -703,7 +703,7 @@ if (regs != NULL) { #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) - task-thread.dbcr0 = DBCR0_IDM | DBCR0_IC; + task-thread.dbcr0 |= DBCR0_IDM | DBCR0_IC; regs-msr |= MSR_DE; #else regs-msr |= MSR_SE; @@ -716,9 +716,16 @@ { struct
Re: [RFC] 4xx hardware watchpoint support
On Jul 23, 2008, at 10:53 AM, Josh Boyer wrote: On Tue, 22 Jul 2008 22:47:58 -0300 Luis Machado [EMAIL PROTECTED] wrote: Hi, That, or adding a small function to move the bits to the appropriate registers (set_dbcr or set_dac_events). Do you think it's worth to support this facility on 405's processors? If so, i'll gladly work on a solution to it. I would think so. There's really no difference from a userspace perspective, so gdb watchpoints could be valuable there too. I'll leave it up to you though. As the 440 support is ready and the 405 needs additional tweaking due to the use of DBCR1 instead of DBCR0 and due to a different position scheme of the DAC1R/DAC1W flags inside DBCR1, i'd say we should include this code and handle the 405 case later. That's fine with me, but I have one question below then. Index: linux-2.6.26/arch/powerpc/kernel/signal.c === --- linux-2.6.26.orig/arch/powerpc/kernel/signal.c 2008-07-20 16:56:57.0 -0700 +++ linux-2.6.26/arch/powerpc/kernel/signal.c 2008-07-22 16:47:22.0 -0700 @@ -145,8 +145,12 @@ * user space. The DABR will have been cleared if it * triggered inside the kernel. */ - if (current-thread.dabr) + if (current-thread.dabr) { set_dabr(current-thread.dabr); +#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) + mtspr(SPRN_DBCR0, current-thread.dbcr0); +#endif Shouldn't this (and other places) be: #if defined(CONFIG_44x) || defined(CONFIG_BOOKE) if you are going to exclude 40x for now? Otherwise this is still enabled on 405 and setting the wrong register. if we are ignoring 40x this can just be CONFIG_BOOKE. CONFIG_44x sets CONFIG_BOOKE. - k ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: DTS configuration of external interrupts on 8347
On Wed, 23 Jul 2008 15:58:38 +0100 Richard Whitlock [EMAIL PROTECTED] wrote: I have a small problem with a port of linux 2.6.26 to a custom board. Our board is almost identical to the Analogue Micro asp 8347 board, so I'm using Kumar Gala's excellent fsl tree (thank you Kumar) as it already has a defconfig for the asp. Thanks also to Bryan O'Donoghue for pointing us in the direction of the asp port in the first place. The problem we have is I am unable to request an external interrupt. We have an FPGA which has an interrupt line - HW IRQ_0, so thats linux IRQ 48. I have added the following to the dts file: [EMAIL PROTECTED] { interrupts = 48 8; interrupt-parent = ipic; } but whenever I call request_irq() it returns -ENOSYS. The driver loads fine, and the open function does very little - a call to ioremap() - which works, and a call to request_irq() which does not. Is there anything else I have to do to configure this interrupt? I don't think you have enough information in the dts. We do the same thing on the warp (you can look at the warp.dts): [EMAIL PROTECTED],0 { compatible = pika,fpga; reg = 0x0002 0x 0x1000; interrupts = 0x18 0x8; interrupt-parent = UIC0; }; You need the compatible, maybe kfaf,fpga, and I believe the reg entry although you could try without it. You then can use: of_find_compatible_node irq_of_parse_and_map request_irq platforms/44x/warp.c shows an example using the ad7414. Just change the ad7414 string to your compatible string. Cheers, Sean ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Xilinx linux Wiki
Hello All, This message is an advertisement for the new Xilinx wiki at http://xilinx.wikidot.com/ . I think this could be a useful and longstanding resource that could help bring new members into the Embedded Linux for Xilinx community rather quickly. Because this project isn't completely within the focus of this mailing list I apologize; I really believe that it may be of interest to many people that work here though. If you have any comments on the place of a wiki like this or are aware of any other community resources with active contributions, please reply. Thanks, Jake Poteet ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 00/16 v4] powerpc: pSeries Cooperative Memory Overcommitment support
This is version 4 of the full patchset pulling in all prior changes posted to the list. Two patches sent separately to apply on top of the prior set have been included in this set. Cooperative Memory Overcommitment (CMO) is a pSeries platform feature that enables the allocation of more memory to a set logical partitions than is physically present. For example, a system with 16Gb of memory can be configured to simultaneously run 3 logical partitions each with 8Gb of memory allocated to them. The system firmware can page out memory as needed to meet the needs of each partition. To minimize the effects of firmware paging memory, the Collaborative Memory Manager (CMM) driver acts as a balloon driver to work with firmware to provide memory ahead of any paging needs. The OS is provided with an entitlement of IO memory for device drivers to map. This amount varies with the number of virtual IO adapters present and can change as devices are hot-plugged. The VIO bus code distributes this memory to devices. Logical partitions supporting CMO may only have virtual IO devices, physical devices are not supported. Above the entitled level, IO mappings can fail and the IOMMU needed be updated to handle this change. Virtual IO adapters have been updated to handle DMA mapping failures and to size their entitlement needs. Platform support for for CMM and hot-plug entitlement events are also included in the following patches. The changes should have minimal impact to non-CMO enabled environments. This patch set has been written against 2.6.26 and has been tested at that level. Regards, Robert Jennings ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 01/16 v4] powerpc: Remove extraneous error reporting for hcall failures in lparcfg
From: Nathan Fontenot [EMAIL PROTECTED] Remove the extraneous error reporting used when a hcall made from lparcfg fails. Signed-off-by: Nathan Fontenot [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] Acked-by: Paul Mackerras [EMAIL PROTECTED] --- arch/powerpc/kernel/lparcfg.c | 32 1 file changed, 32 deletions(-) Index: b/arch/powerpc/kernel/lparcfg.c === --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -129,33 +129,6 @@ static int iseries_lparcfg_data(struct s /* * Methods used to fetch LPAR data when running on a pSeries platform. */ -static void log_plpar_hcall_return(unsigned long rc, char *tag) -{ - switch(rc) { - case 0: - return; - case H_HARDWARE: - printk(KERN_INFO plpar-hcall (%s) - Hardware fault\n, tag); - return; - case H_FUNCTION: - printk(KERN_INFO plpar-hcall (%s) - Function not allowed\n, tag); - return; - case H_AUTHORITY: - printk(KERN_INFO plpar-hcall (%s) - Not authorized to this function\n, tag); - return; - case H_PARAMETER: - printk(KERN_INFO plpar-hcall (%s) - Bad parameter(s)\n,tag); - return; - default: - printk(KERN_INFO plpar-hcall (%s) - Unexpected rc(0x%lx)\n, tag, rc); - } -} - /* * H_GET_PPP hcall returns info in 4 parms. * entitled_capacity,unallocated_capacity, @@ -191,8 +164,6 @@ static unsigned int h_get_ppp(unsigned l *aggregation = retbuf[2]; *resource = retbuf[3]; - log_plpar_hcall_return(rc, H_GET_PPP); - return rc; } @@ -205,9 +176,6 @@ static void h_pic(unsigned long *pool_id *pool_idle_time = retbuf[0]; *num_procs = retbuf[1]; - - if (rc != H_AUTHORITY) - log_plpar_hcall_return(rc, H_PIC); } #define SPLPAR_CHARACTERISTICS_TOKEN 20 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 02/16 v4] powerpc: Split processor entitlement retrieval and gat
hering to helper routines From: Nathan Fotenot [EMAIL PROTECTED] Split the retrieval and setting of processor entitlement and weight into helper routines. This also removes the printing of the raw values returned from h_get_ppp, the values are already parsed and printed. Signed-off-by: Nathan Fontenot [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- Updated patch to remove checking the return code from the h_call for H_PIC. This reverts the reporting back to its original state. --- arch/powerpc/kernel/lparcfg.c | 166 ++ 1 file changed, 88 insertions(+), 78 deletions(-) Index: b/arch/powerpc/kernel/lparcfg.c === --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -167,7 +167,8 @@ static unsigned int h_get_ppp(unsigned l return rc; } -static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) +static unsigned h_pic(unsigned long *pool_idle_time, + unsigned long *num_procs) { unsigned long rc; unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; @@ -176,6 +177,51 @@ static void h_pic(unsigned long *pool_id *pool_idle_time = retbuf[0]; *num_procs = retbuf[1]; + + return rc; +} + +/* + * parse_ppp_data + * Parse out the data returned from h_get_ppp and h_pic + */ +static void parse_ppp_data(struct seq_file *m) +{ + unsigned long h_entitled, h_unallocated; + unsigned long h_aggregation, h_resource; + int rc; + + rc = h_get_ppp(h_entitled, h_unallocated, h_aggregation, + h_resource); + if (rc) + return; + + seq_printf(m, partition_entitled_capacity=%ld\n, h_entitled); + seq_printf(m, group=%ld\n, (h_aggregation 2 * 8) 0x); + seq_printf(m, system_active_processors=%ld\n, + (h_resource 0 * 8) 0x); + + /* pool related entries are apropriate for shared configs */ + if (lppaca[0].shared_proc) { + unsigned long pool_idle_time, pool_procs; + + seq_printf(m, pool=%ld\n, (h_aggregation 0 * 8) 0x); + + /* report pool_capacity in percentage */ + seq_printf(m, pool_capacity=%ld\n, + ((h_resource 2 * 8) 0x) * 100); + + h_pic(pool_idle_time, pool_procs); + seq_printf(m, pool_idle_time=%ld\n, pool_idle_time); + seq_printf(m, pool_num_procs=%ld\n, pool_procs); + } + + seq_printf(m, unallocated_capacity_weight=%ld\n, + (h_resource 4 * 8) 0xFF); + + seq_printf(m, capacity_weight=%ld\n, (h_resource 5 * 8) 0xFF); + seq_printf(m, capped=%ld\n, (h_resource 6 * 8) 0x01); + seq_printf(m, unallocated_capacity=%ld\n, h_unallocated); } #define SPLPAR_CHARACTERISTICS_TOKEN 20 @@ -302,60 +348,11 @@ static int pseries_lparcfg_data(struct s partition_active_processors = lparcfg_count_active_processors(); if (firmware_has_feature(FW_FEATURE_SPLPAR)) { - unsigned long h_entitled, h_unallocated; - unsigned long h_aggregation, h_resource; - unsigned long pool_idle_time, pool_procs; - unsigned long purr; - - h_get_ppp(h_entitled, h_unallocated, h_aggregation, - h_resource); - - seq_printf(m, R4=0x%lx\n, h_entitled); - seq_printf(m, R5=0x%lx\n, h_unallocated); - seq_printf(m, R6=0x%lx\n, h_aggregation); - seq_printf(m, R7=0x%lx\n, h_resource); - - purr = get_purr(); - /* this call handles the ibm,get-system-parameter contents */ parse_system_parameter_string(m); + parse_ppp_data(m); - seq_printf(m, partition_entitled_capacity=%ld\n, h_entitled); - - seq_printf(m, group=%ld\n, (h_aggregation 2 * 8) 0x); - - seq_printf(m, system_active_processors=%ld\n, - (h_resource 0 * 8) 0x); - - /* pool related entries are apropriate for shared configs */ - if (lppaca[0].shared_proc) { - - h_pic(pool_idle_time, pool_procs); - - seq_printf(m, pool=%ld\n, - (h_aggregation 0 * 8) 0x); - - /* report pool_capacity in percentage */ - seq_printf(m, pool_capacity=%ld\n, - ((h_resource 2 * 8) 0x) * 100); - - seq_printf(m, pool_idle_time=%ld\n, pool_idle_time); - - seq_printf(m, pool_num_procs=%ld\n, pool_procs); - } - - seq_printf(m, unallocated_capacity_weight=%ld\n, - (h_resource 4 * 8) 0xFF); - - seq_printf(m,
[PATCH 03/16 v4] powerpc: Add memory entitlement capabilities to /proc/ppc64/lparcfg
From: Nathan Fontenot [EMAIL PROTECTED] Update /proc/ppc64/lparcfg to enable displaying of Cooperative Memory Overcommitment statistics as reported by the H_GET_MPP hcall. This also updates the lparcfg interface to allow setting memory entitlement and weight. Signed-off-by: Nathan Fontenot [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- Updated patch, increment the lparcfg module version number. --- arch/powerpc/kernel/lparcfg.c | 121 ++ include/asm-powerpc/hvcall.h | 18 ++ 2 files changed, 137 insertions(+), 2 deletions(-) Index: b/arch/powerpc/kernel/lparcfg.c === --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -35,7 +35,7 @@ #include asm/prom.h #include asm/vdso_datapage.h -#define MODULE_VERS 1.7 +#define MODULE_VERS 1.8 #define MODULE_NAME lparcfg /* #define LPARCFG_DEBUG */ @@ -129,6 +129,35 @@ static int iseries_lparcfg_data(struct s /* * Methods used to fetch LPAR data when running on a pSeries platform. */ +/** + * h_get_mpp + * H_GET_MPP hcall returns info in 7 parms + */ +int h_get_mpp(struct hvcall_mpp_data *mpp_data) +{ + int rc; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + + rc = plpar_hcall9(H_GET_MPP, retbuf); + + mpp_data-entitled_mem = retbuf[0]; + mpp_data-mapped_mem = retbuf[1]; + + mpp_data-group_num = (retbuf[2] 2 * 8) 0x; + mpp_data-pool_num = retbuf[2] 0x; + + mpp_data-mem_weight = (retbuf[3] 7 * 8) 0xff; + mpp_data-unallocated_mem_weight = (retbuf[3] 6 * 8) 0xff; + mpp_data-unallocated_entitlement = retbuf[3] 0x; + + mpp_data-pool_size = retbuf[4]; + mpp_data-loan_request = retbuf[5]; + mpp_data-backing_mem = retbuf[6]; + + return rc; +} +EXPORT_SYMBOL(h_get_mpp); + /* * H_GET_PPP hcall returns info in 4 parms. * entitled_capacity,unallocated_capacity, @@ -224,6 +253,44 @@ static void parse_ppp_data(struct seq_fi seq_printf(m, unallocated_capacity=%ld\n, h_unallocated); } +/** + * parse_mpp_data + * Parse out data returned from h_get_mpp + */ +static void parse_mpp_data(struct seq_file *m) +{ + struct hvcall_mpp_data mpp_data; + int rc; + + rc = h_get_mpp(mpp_data); + if (rc) + return; + + seq_printf(m, entitled_memory=%ld\n, mpp_data.entitled_mem); + + if (mpp_data.mapped_mem != -1) + seq_printf(m, mapped_entitled_memory=%ld\n, + mpp_data.mapped_mem); + + seq_printf(m, entitled_memory_group_number=%d\n, mpp_data.group_num); + seq_printf(m, entitled_memory_pool_number=%d\n, mpp_data.pool_num); + + seq_printf(m, entitled_memory_weight=%d\n, mpp_data.mem_weight); + seq_printf(m, unallocated_entitled_memory_weight=%d\n, + mpp_data.unallocated_mem_weight); + seq_printf(m, unallocated_io_mapping_entitlement=%ld\n, + mpp_data.unallocated_entitlement); + + if (mpp_data.pool_size != -1) + seq_printf(m, entitled_memory_pool_size=%ld bytes\n, + mpp_data.pool_size); + + seq_printf(m, entitled_memory_loan_request=%ld\n, + mpp_data.loan_request); + + seq_printf(m, backing_memory=%ld bytes\n, mpp_data.backing_mem); +} + #define SPLPAR_CHARACTERISTICS_TOKEN 20 #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) @@ -351,6 +418,7 @@ static int pseries_lparcfg_data(struct s /* this call handles the ibm,get-system-parameter contents */ parse_system_parameter_string(m); parse_ppp_data(m); + parse_mpp_data(m); seq_printf(m, purr=%ld\n, get_purr()); } else {/* non SPLPAR case */ @@ -414,6 +482,43 @@ static ssize_t update_ppp(u64 *entitleme return retval; } +/** + * update_mpp + * + * Update the memory entitlement and weight for the partition. Caller must + * specify either a new entitlement or weight, not both, to be updated + * since the h_set_mpp call takes both entitlement and weight as parameters. + */ +static ssize_t update_mpp(u64 *entitlement, u8 *weight) +{ + struct hvcall_mpp_data mpp_data; + u64 new_entitled; + u8 new_weight; + ssize_t rc; + + rc = h_get_mpp(mpp_data); + if (rc) + return rc; + + if (entitlement) { + new_weight = mpp_data.mem_weight; + new_entitled = *entitlement; + } else if (weight) { + new_weight = *weight; + new_entitled = mpp_data.entitled_mem; + } else + return -EINVAL; + + pr_debug(%s: current_entitled = %lu, current_weight = %u\n, +__FUNCTION__, mpp_data.entitled_mem, mpp_data.mem_weight); + + pr_debug(%s: new_entitled = %lu, new_weight = %u\n, +
[PATCH 04/16 v4] powerpc: Split retrieval of processor entitlement data into a helper routine
Split the retrieval of processor entitlement data returned in the H_GET_PPP hcall into its own helper routine. Signed-off-by: Nathan Fontenot [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- Updated patch to correct the reporting of pool_capcity. --- arch/powerpc/kernel/lparcfg.c | 81 -- 1 file changed, 46 insertions(+), 35 deletions(-) Index: b/arch/powerpc/kernel/lparcfg.c === --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -158,6 +158,18 @@ int h_get_mpp(struct hvcall_mpp_data *mp } EXPORT_SYMBOL(h_get_mpp); +struct hvcall_ppp_data { + u64 entitlement; + u64 unallocated_entitlement; + u16 group_num; + u16 pool_num; + u8 capped; + u8 weight; + u8 unallocated_weight; + u16 active_procs_in_pool; + u16 active_system_procs; +}; + /* * H_GET_PPP hcall returns info in 4 parms. * entitled_capacity,unallocated_capacity, @@ -178,20 +190,24 @@ EXPORT_SYMBOL(h_get_mpp); * - Active processors in Physical Processor Pool. * - Processors active on platform. */ -static unsigned int h_get_ppp(unsigned long *entitled, - unsigned long *unallocated, - unsigned long *aggregation, - unsigned long *resource) +static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data) { unsigned long rc; unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; rc = plpar_hcall(H_GET_PPP, retbuf); - *entitled = retbuf[0]; - *unallocated = retbuf[1]; - *aggregation = retbuf[2]; - *resource = retbuf[3]; + ppp_data-entitlement = retbuf[0]; + ppp_data-unallocated_entitlement = retbuf[1]; + + ppp_data-group_num = (retbuf[2] 2 * 8) 0x; + ppp_data-pool_num = retbuf[2] 0x; + + ppp_data-capped = (retbuf[3] 6 * 8) 0x01; + ppp_data-weight = (retbuf[3] 5 * 8) 0xff; + ppp_data-unallocated_weight = (retbuf[3] 4 * 8) 0xff; + ppp_data-active_procs_in_pool = (retbuf[3] 2 * 8) 0x; + ppp_data-active_system_procs = retbuf[3] 0x; return rc; } @@ -216,41 +232,40 @@ static unsigned h_pic(unsigned long *poo */ static void parse_ppp_data(struct seq_file *m) { - unsigned long h_entitled, h_unallocated; - unsigned long h_aggregation, h_resource; + struct hvcall_ppp_data ppp_data; int rc; - rc = h_get_ppp(h_entitled, h_unallocated, h_aggregation, - h_resource); + rc = h_get_ppp(ppp_data); if (rc) return; - seq_printf(m, partition_entitled_capacity=%ld\n, h_entitled); - seq_printf(m, group=%ld\n, (h_aggregation 2 * 8) 0x); - seq_printf(m, system_active_processors=%ld\n, - (h_resource 0 * 8) 0x); + seq_printf(m, partition_entitled_capacity=%ld\n, + ppp_data.entitlement); + seq_printf(m, group=%d\n, ppp_data.group_num); + seq_printf(m, system_active_processors=%d\n, + ppp_data.active_system_procs); /* pool related entries are apropriate for shared configs */ if (lppaca[0].shared_proc) { unsigned long pool_idle_time, pool_procs; - seq_printf(m, pool=%ld\n, (h_aggregation 0 * 8) 0x); + seq_printf(m, pool=%d\n, ppp_data.pool_num); /* report pool_capacity in percentage */ - seq_printf(m, pool_capacity=%ld\n, - ((h_resource 2 * 8) 0x) * 100); + seq_printf(m, pool_capacity=%d\n, + ppp_data.active_procs_in_pool * 100); h_pic(pool_idle_time, pool_procs); seq_printf(m, pool_idle_time=%ld\n, pool_idle_time); seq_printf(m, pool_num_procs=%ld\n, pool_procs); } - seq_printf(m, unallocated_capacity_weight=%ld\n, - (h_resource 4 * 8) 0xFF); - - seq_printf(m, capacity_weight=%ld\n, (h_resource 5 * 8) 0xFF); - seq_printf(m, capped=%ld\n, (h_resource 6 * 8) 0x01); - seq_printf(m, unallocated_capacity=%ld\n, h_unallocated); + seq_printf(m, unallocated_capacity_weight=%d\n, + ppp_data.unallocated_weight); + seq_printf(m, capacity_weight=%d\n, ppp_data.weight); + seq_printf(m, capped=%d\n, ppp_data.capped); + seq_printf(m, unallocated_capacity=%ld\n, + ppp_data.unallocated_entitlement); } /** @@ -449,31 +464,27 @@ static int pseries_lparcfg_data(struct s static ssize_t update_ppp(u64 *entitlement, u8 *weight) { - unsigned long current_entitled; - unsigned long dummy; - unsigned long resource; - u8 current_weight, new_weight;
[PATCH 05/16 v4] powerpc: Enable CMO feature during platform setup
From: Robert Jennings [EMAIL PROTECTED] For Cooperative Memory Overcommitment (CMO), set the FW_FEATURE_CMO flag in powerpc_firmware_features from the rtas ibm,get-system-parameters table prior to calling iommu_init_early_pSeries. With this, any CMO specific functionality can be controlled by checking: firmware_has_feature(FW_FEATURE_CMO) Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- Correct string conversion for rtas value being read for CMO configuration. A value of -1 in the string indicates that CMO is not enabled and we had used simple_strtoul rather than simple_strtol. --- arch/powerpc/platforms/pseries/setup.c | 71 + include/asm-powerpc/firmware.h |3 + 2 files changed, 73 insertions(+), 1 deletion(-) Index: b/arch/powerpc/platforms/pseries/setup.c === --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -314,6 +314,76 @@ static int pseries_set_xdabr(unsigned lo H_DABRX_KERNEL | H_DABRX_USER); } +#define CMO_CHARACTERISTICS_TOKEN 44 +#define CMO_MAXLENGTH 1026 + +/** + * fw_cmo_feature_init - FW_FEATURE_CMO is not stored in ibm,hypertas-functions, + * handle that here. (Stolen from parse_system_parameter_string) + */ +void pSeries_cmo_feature_init(void) +{ + char *ptr, *key, *value, *end; + int call_status; + int PrPSP = -1; + int SecPSP = -1; + + pr_debug( - fw_cmo_feature_init()\n); + spin_lock(rtas_data_buf_lock); + memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); + call_status = rtas_call(rtas_token(ibm,get-system-parameter), 3, 1, + NULL, + CMO_CHARACTERISTICS_TOKEN, + __pa(rtas_data_buf), + RTAS_DATA_BUF_SIZE); + + if (call_status != 0) { + spin_unlock(rtas_data_buf_lock); + pr_debug(CMO not available\n); + pr_debug( - fw_cmo_feature_init()\n); + return; + } + + end = rtas_data_buf + CMO_MAXLENGTH - 2; + ptr = rtas_data_buf + 2;/* step over strlen value */ + key = value = ptr; + + while (*ptr (ptr = end)) { + /* Separate the key and value by replacing '=' with '\0' and +* point the value at the string after the '=' +*/ + if (ptr[0] == '=') { + ptr[0] = '\0'; + value = ptr + 1; + } else if (ptr[0] == '\0' || ptr[0] == ',') { + /* Terminate the string containing the key/value pair */ + ptr[0] = '\0'; + + if (key == value) { + pr_debug(Malformed key/value pair\n); + /* Never found a '=', end processing */ + break; + } + + if (0 == strcmp(key, PrPSP)) + PrPSP = simple_strtol(value, NULL, 10); + else if (0 == strcmp(key, SecPSP)) + SecPSP = simple_strtol(value, NULL, 10); + value = key = ptr + 1; + } + ptr++; + } + + if (PrPSP != -1 || SecPSP != -1) { + pr_info(CMO enabled\n); + pr_debug(CMO enabled, PrPSP=%d, SecPSP=%d\n, PrPSP, SecPSP); + powerpc_firmware_features |= FW_FEATURE_CMO; + } else + pr_debug(CMO not enabled, PrPSP=%d, SecPSP=%d\n, PrPSP, SecPSP); + spin_unlock(rtas_data_buf_lock); + pr_debug( - fw_cmo_feature_init()\n); +} + /* * Early initialization. Relocation is on but do not reference unbolted pages */ @@ -329,6 +399,7 @@ static void __init pSeries_init_early(vo else if (firmware_has_feature(FW_FEATURE_XDABR)) ppc_md.set_dabr = pseries_set_xdabr; + pSeries_cmo_feature_init(); iommu_init_early_pSeries(); pr_debug( - pSeries_init_early()\n); Index: b/include/asm-powerpc/firmware.h === --- a/include/asm-powerpc/firmware.h +++ b/include/asm-powerpc/firmware.h @@ -46,6 +46,7 @@ #define FW_FEATURE_PS3_LV1 ASM_CONST(0x0080) #define FW_FEATURE_BEATASM_CONST(0x0100) #define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0200) +#define FW_FEATURE_CMO ASM_CONST(0x0400) #ifndef __ASSEMBLY__ @@ -58,7 +59,7 @@ enum { FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ | FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN | FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE | - FW_FEATURE_SPLPAR | FW_FEATURE_LPAR, + FW_FEATURE_SPLPAR |
[PATCH 06/16 v4] powerpc: Utilities to set firmware page state
From: Brian King [EMAIL PROTECTED] Newer versions of firmware support page states, which are used by the collaborative memory manager (future patch) to loan pages to the hypervisor for use by other partitions. Signed-off-by: Brian King [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- arch/powerpc/platforms/pseries/plpar_wrappers.h | 10 ++ include/asm-powerpc/hvcall.h|5 + 2 files changed, 15 insertions(+) Index: b/arch/powerpc/platforms/pseries/plpar_wrappers.h === --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -42,6 +42,16 @@ static inline long register_slb_shadow(u return vpa_call(0x3, cpu, vpa); } +static inline long plpar_page_set_loaned(unsigned long vpa) +{ + return plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa, 0); +} + +static inline long plpar_page_set_active(unsigned long vpa) +{ + return plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa, 0); +} + extern void vpa_init(int cpu); static inline long plpar_pte_enter(unsigned long flags, Index: b/include/asm-powerpc/hvcall.h === --- a/include/asm-powerpc/hvcall.h +++ b/include/asm-powerpc/hvcall.h @@ -92,6 +92,11 @@ #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_PAGE_STATE_CHANGE(1UL(63-28)) +#define H_PAGE_UNUSED ((1UL(63-29)) | (1UL(63-30))) +#define H_PAGE_SET_UNUSED (H_PAGE_STATE_CHANGE | H_PAGE_UNUSED) +#define H_PAGE_SET_LOANED (H_PAGE_SET_UNUSED | (1UL(63-31))) +#define H_PAGE_SET_ACTIVE H_PAGE_STATE_CHANGE #define H_AVPN (1UL(63-32)) /* An avpn is provided as a sanity test */ #define H_ANDCOND (1UL(63-33)) #define H_ICACHE_INVALIDATE(1UL(63-40)) /* icbi, etc. (ignored for IO pages) */ ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 07/16 v4] powerpc: Add collaborative memory manager
From: Brian King [EMAIL PROTECTED] Adds a collaborative memory manager, which acts as a simple balloon driver for System p machines that support cooperative memory overcommitment (CMO). Adds a platform configuration option for CMO called PPC_SMLPAR. Signed-off-by: Brian King [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- Added a config option PPC_SMLPAR (Support for shared-memory logical partitions) to the platform. This will select LPARCFG and address the issue where h_get_mpp() may not have been present when compiling. This new config option is now used to #ifdef out code in the vio bus patch that follows and the arch vector patch that enables the code for firmware. --- arch/powerpc/platforms/pseries/Kconfig | 23 ++ arch/powerpc/platforms/pseries/Makefile |1 + arch/powerpc/platforms/pseries/cmm.c| 468 3 files changed, 492 insertions(+) Index: b/arch/powerpc/platforms/pseries/Kconfig === --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -40,3 +40,26 @@ config PPC_PSERIES_DEBUG depends on PPC_PSERIES PPC_EARLY_DEBUG bool Enable extra debug logging in platforms/pseries default y + +config PPC_SMLPAR + bool Support for shared-memory logical partitions + depends on PPC_PSERIES + select LPARCFG + default y + help + Select this option to enable shared memory partition support. + With this option a system running in an LPAR can be given more + memory than physically available and will allow firmware to + balance memory across many LPARs. + +config CMM + tristate Collaborative memory management + depends on PPC_SMLPAR + default y + help + Select this option, if you want to enable the kernel interface + to reduce the memory size of the system. This is accomplished + by allocating pages of memory and put them on hold. This only + makes sense for a system running in an LPAR where the unused pages + will be reused for other LPARs. The interface allows firmware to + balance memory across many LPARs. Index: b/arch/powerpc/platforms/pseries/Makefile === --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o obj-$(CONFIG_PHYP_DUMP)+= phyp_dump.o +obj-$(CONFIG_CMM) += cmm.o Index: b/arch/powerpc/platforms/pseries/cmm.c === --- /dev/null +++ b/arch/powerpc/platforms/pseries/cmm.c @@ -0,0 +1,468 @@ +/* + * Collaborative memory management interface. + * + * Copyright (C) 2008 IBM Corporation + * Author(s): Brian King ([EMAIL PROTECTED]), + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include linux/ctype.h +#include linux/delay.h +#include linux/errno.h +#include linux/fs.h +#include linux/init.h +#include linux/kthread.h +#include linux/module.h +#include linux/oom.h +#include linux/sched.h +#include linux/stringify.h +#include linux/swap.h +#include linux/sysdev.h +#include asm/firmware.h +#include asm/hvcall.h +#include asm/mmu.h +#include asm/pgalloc.h +#include asm/uaccess.h + +#include plpar_wrappers.h + +#define CMM_DRIVER_VERSION 1.0.0 +#define CMM_DEFAULT_DELAY 1 +#define CMM_DEBUG 0 +#define CMM_DISABLE0 +#define CMM_OOM_KB 1024 +#define CMM_MIN_MEM_MB 256 +#define KB2PAGES(_p) ((_p)(PAGE_SHIFT-10)) +#define PAGES2KB(_p) ((_p)(PAGE_SHIFT-10)) + +static unsigned int delay = CMM_DEFAULT_DELAY; +static unsigned int oom_kb = CMM_OOM_KB; +static unsigned int cmm_debug = CMM_DEBUG; +static unsigned int cmm_disabled = CMM_DISABLE; +static unsigned long min_mem_mb = CMM_MIN_MEM_MB; +static struct sys_device cmm_sysdev; + +MODULE_AUTHOR(Brian King [EMAIL PROTECTED]); +MODULE_DESCRIPTION(IBM System p Collaborative Memory Manager); +MODULE_LICENSE(GPL);
[PATCH 08/16 v4] powerpc: Add CMO paging statistics
From: Brian King [EMAIL PROTECTED] With the addition of Cooperative Memory Overcommitment (CMO) support for IBM Power Systems, two fields have been added to the VPA to report paging statistics. Add support in lparcfg to report them to userspace. Signed-off-by: Brian King [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- arch/powerpc/kernel/lparcfg.c | 20 include/asm-powerpc/lppaca.h |5 - 2 files changed, 24 insertions(+), 1 deletion(-) Index: b/arch/powerpc/kernel/lparcfg.c === --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -409,6 +409,25 @@ static int lparcfg_count_active_processo return count; } +static void pseries_cmo_data(struct seq_file *m) +{ + int cpu; + unsigned long cmo_faults = 0; + unsigned long cmo_fault_time = 0; + + if (!firmware_has_feature(FW_FEATURE_CMO)) + return; + + for_each_possible_cpu(cpu) { + cmo_faults += lppaca[cpu].cmo_faults; + cmo_fault_time += lppaca[cpu].cmo_fault_time; + } + + seq_printf(m, cmo_faults=%lu\n, cmo_faults); + seq_printf(m, cmo_fault_time_usec=%lu\n, + cmo_fault_time / tb_ticks_per_usec); +} + static int pseries_lparcfg_data(struct seq_file *m, void *v) { int partition_potential_processors; @@ -434,6 +453,7 @@ static int pseries_lparcfg_data(struct s parse_system_parameter_string(m); parse_ppp_data(m); parse_mpp_data(m); + pseries_cmo_data(m); seq_printf(m, purr=%ld\n, get_purr()); } else {/* non SPLPAR case */ Index: b/include/asm-powerpc/lppaca.h === --- a/include/asm-powerpc/lppaca.h +++ b/include/asm-powerpc/lppaca.h @@ -125,7 +125,10 @@ struct lppaca { // NOTE: This value will ALWAYS be zero for dedicated processors and // will NEVER be zero for shared processors (ie, initialized to a 1). volatile u32 yield_count; // PLIC increments each dispatchx00-x03 - u8 reserved6[124]; // Reserved x04-x7F + u32 reserved6; + volatile u64 cmo_faults;// CMO page fault count x08-x0F + volatile u64 cmo_fault_time;// CMO page fault time x10-x17 + u8 reserved7[104]; // Reserved x18-x7F //= // CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 09/16 v4] powerpc: iommu enablement for CMO
To support Cooperative Memory Overcommitment (CMO), we need to check for failure from some of the tce hcalls. These changes for the pseries platform affect the powerpc architecture; patches for the other affected platforms are included in this patch. pSeries platform IOMMU code changes: * platform TCE functions must handle H_NOT_ENOUGH_RESOURCES errors and return an error. Architecture IOMMU code changes: * Calls to ppc_md.tce_build need to check return values and return DMA_MAPPING_ERROR for transient errors. Architecture changes: * struct machdep_calls for tce_build*_pSeriesLP functions need to change to indicate failure. * all other platforms will need updates to iommu functions to match the new calling semantics; they will return 0 on success. The other platforms default configs have been built, but no further testing was performed. Signed-off-by: Robert Jennings [EMAIL PROTECTED] Acked-by: Olof Johansson [EMAIL PROTECTED] --- Rebased against tree now that it contains Mark Nelson's patch powerpc/dma: implement new dma_*map*_attrs() interfaces to preserve the 'attrs' field in [un]map_sg, [un]map_single functions. Rebased against tree now that it contains Michael Ellerman's patch Fix sparse warnings in arch/powerpc/platforms/pseries and made a correction in tce_buildmulti_pSeriesLP for this new code as necessary. --- arch/powerpc/kernel/iommu.c| 28 ++ arch/powerpc/platforms/cell/iommu.c|3 +- arch/powerpc/platforms/iseries/iommu.c |3 +- arch/powerpc/platforms/pasemi/iommu.c |3 +- arch/powerpc/platforms/pseries/iommu.c | 42 + arch/powerpc/sysdev/dart_iommu.c |3 +- include/asm-powerpc/machdep.h |2 +- 7 files changed, 64 insertions(+), 20 deletions(-) Index: b/arch/powerpc/kernel/iommu.c === --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -49,6 +49,8 @@ static int novmerge = 1; static int protect4gb = 1; +static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int); + static inline unsigned long iommu_num_pages(unsigned long vaddr, unsigned long slen) { @@ -191,6 +193,7 @@ static dma_addr_t iommu_alloc(struct dev { unsigned long entry, flags; dma_addr_t ret = DMA_ERROR_CODE; + int build_fail; spin_lock_irqsave((tbl-it_lock), flags); @@ -205,9 +208,21 @@ static dma_addr_t iommu_alloc(struct dev ret = entry IOMMU_PAGE_SHIFT;/* Set the return dma address */ /* Put the TCEs in the HW table */ - ppc_md.tce_build(tbl, entry, npages, (unsigned long)page IOMMU_PAGE_MASK, -direction, attrs); + build_fail = ppc_md.tce_build(tbl, entry, npages, + (unsigned long)page IOMMU_PAGE_MASK, + direction, attrs); + + /* ppc_md.tce_build() only returns non-zero for transient errors. +* Clean up the table bitmap in this case and return +* DMA_ERROR_CODE. For all other errors the functionality is +* not altered. +*/ + if (unlikely(build_fail)) { + __iommu_free(tbl, ret, npages); + spin_unlock_irqrestore((tbl-it_lock), flags); + return DMA_ERROR_CODE; + } /* Flush/invalidate TLB caches if necessary */ if (ppc_md.tce_flush) @@ -276,7 +291,7 @@ int iommu_map_sg(struct device *dev, str dma_addr_t dma_next = 0, dma_addr; unsigned long flags; struct scatterlist *s, *outs, *segstart; - int outcount, incount, i; + int outcount, incount, i, build_fail = 0; unsigned int align; unsigned long handle; unsigned int max_seg_size; @@ -337,8 +352,11 @@ int iommu_map_sg(struct device *dev, str npages, entry, dma_addr); /* Insert into HW table */ - ppc_md.tce_build(tbl, entry, npages, vaddr IOMMU_PAGE_MASK, -direction, attrs); + build_fail = ppc_md.tce_build(tbl, entry, npages, + vaddr IOMMU_PAGE_MASK, + direction, attrs); + if(unlikely(build_fail)) + goto failure; /* If we are in an open segment, try merging */ if (segstart != s) { Index: b/arch/powerpc/platforms/cell/iommu.c === --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -172,7 +172,7 @@ static void invalidate_tce_cache(struct } } -static void tce_build_cell(struct iommu_table *tbl, long index, long npages, +static int tce_build_cell(struct iommu_table *tbl, long index, long npages,
[PATCH 10/16 v4] powerpc: vio bus support for CMO
From: Robert Jennings [EMAIL PROTECTED] This is a large patch but the normal code path is not affected. For non-pSeries platforms the code is ifdef'ed out and for non-CMO enabled pSeries systems this does not affect the normal code path. Devices that do not perform DMA operations do not need modification with this patch. The function get_desired_dma was renamed from get_io_entitlement for clarity. Overview Cooperative Memory Overcommitment (CMO) allows for a set of OS partitions to be run with less RAM than the aggregate needs of the group of partitions. The firmware will balance memory between the partitions and page in/out memory as needed. Based on the number and type of IO adpaters preset each partition is allocated an amount of memory for DMA operations and this allocation will be guaranteed to the partition; this is referred to as the partition's 'entitlement'. Partitions running in a CMO environment can only have virtual IO devices present. The VIO bus layer will manage the IO entitlement for the system. Accounting, at a system and per-device level, is tracked in the VIO bus code and exposed via sysfs. A set of dma_ops functions are added to the bus to allow for this accounting. Bus initialization At initialization, the bus will calculate the minimum needs of the system based on providing each device present with a standard minimum entitlement along with a spare allocation for the bus to handle hotplug events. If the minimum needs can not be met the system boot will be halted. Device changes The significant changes for devices while running under CMO are that the devices must specify how much dedicated IO entitlement they desire and must also handle DMA mapping errors that can occur due to constrained IO memory. The virtual IO drivers are modified to silence errors when DMA mappings fail for CMO and handle these failures gracefully. Each devices will be guaranteed a minimum entitlement that can always be mapped. Devices will specify how much entitlement they desire and the VIO bus will attempt to provide for this. Devices can change their desired entitlement level at any point in time to address particular needs (via vio_cmo_set_dev_desired()), not just at device probe time. VIO bus changes The system will have a particular entitlement level available from which it can provide memory to the devices. The bus defines two pools of memory within this entitlement, the reserved and excess pools. Each device is provided with it's own entitlement no less than a system defined minimum entitlement and no greater than what the device has specified as it's desired entitlement. The entitlement provided to devices comes from the reserve pool. The reserve pool can also contain a spare allocation as large as the system defined minimum entitlement which is used for device hotplug events. Any entitlement not needed to fulfill the needs of a reserve pool is placed in the excess pool. Each device is guaranteed that it can map up to it's entitled level; additional mapping are possible as long as there is unmapped memory in the excess pool. Bus probe As the system starts, each device is given an entitlement equal only to the system defined minimum entitlement. The reserve pool is equal to the sum of these entitlements, plus a spare allocation. The VIO bus also tracks the aggregate desired entitlement of all the devices. If the system desired entitlement is greater than the size of the reserve pool, when devices unmap IO memory it will be reserved and a balance operation will be scheduled for some time in the future. Entitlement balancing The balance function tries to fairly distribute entitlement between the devices in the system with the goal of providing each device with it's desired amount of entitlement. Devices using more than what would be ideal will have their entitled set-point adjusted; this will effectively set a goal for lower IO memory usage as future mappings can fail and deallocations will trigger a balance operation to distribute the newly unmapped memory. A fair distribution of entitlement can take several balance operations to achieve. Entitlement changes and device DLPAR events will alter the state of CMO and will trigger balance operations. Hotplug events The VIO bus allows for changes in system entitlement at run-time via 'vio_cmo_entitlement_update()'. When devices are added the hotplug device event will be preceded by a system entitlement increase and this is reversed when devices are removed. The following changes are made that the VIO bus layer for CMO: * add IO memory accounting per device structure. * add IO memory entitlement query function to driver structure. * during vio bus probe, if CMO is enabled, check that driver has memory entitlement query function defined. Fail if function not defined. * fail to register driver if io entitlement function not defined. * create set of dma_ops at vio level for CMO that will track allocations and
[PATCH 11/16 v4] powerpc: Verify CMO memory entitlement updates with virtual I/O
From: Nathan Fontenot [EMAIL PROTECTED] Verify memory entitlement updates can be handled by vio. Signed-off-by: Nathan Fontenot [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- arch/powerpc/kernel/lparcfg.c | 10 ++ 1 file changed, 10 insertions(+) Index: b/arch/powerpc/kernel/lparcfg.c === --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -34,6 +34,7 @@ #include asm/time.h #include asm/prom.h #include asm/vdso_datapage.h +#include asm/vio.h #define MODULE_VERS 1.8 #define MODULE_NAME lparcfg @@ -527,6 +528,15 @@ static ssize_t update_mpp(u64 *entitleme u8 new_weight; ssize_t rc; + if (entitlement) { + /* Check with vio to ensure the new memory entitlement +* can be handled. +*/ + rc = vio_cmo_entitlement_update(*entitlement); + if (rc) + return rc; + } + rc = h_get_mpp(mpp_data); if (rc) return rc; ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 12/16 v4] ibmveth: Automatically enable larger rx buffer pools for larger mtu
From: Santiago Leon [EMAIL PROTECTED] Activates larger rx buffer pools when the MTU is changed to a larger value. This patch de-activates the large rx buffer pools when the MTU changes to a smaller value. Signed-off-by: Santiago Leon [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- We would like to take this patch through linuxppc-dev with the full change set for this feature. We are copying netdev for review and ack. --- drivers/net/ibmveth.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) Index: b/drivers/net/ibmveth.c === --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1054,7 +1054,6 @@ static int ibmveth_change_mtu(struct net { struct ibmveth_adapter *adapter = dev-priv; int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; - int reinit = 0; int i, rc; if (new_mtu IBMVETH_MAX_MTU) @@ -1067,15 +1066,21 @@ static int ibmveth_change_mtu(struct net if (i == IbmVethNumBufferPools) return -EINVAL; + /* Deactivate all the buffer pools so that the next loop can activate + only the buffer pools necessary to hold the new MTU */ + for (i = 0; i IbmVethNumBufferPools; i++) + if (adapter-rx_buff_pool[i].active) { + ibmveth_free_buffer_pool(adapter, +adapter-rx_buff_pool[i]); + adapter-rx_buff_pool[i].active = 0; + } + /* Look for an active buffer pool that can hold the new MTU */ for(i = 0; iIbmVethNumBufferPools; i++) { - if (!adapter-rx_buff_pool[i].active) { - adapter-rx_buff_pool[i].active = 1; - reinit = 1; - } + adapter-rx_buff_pool[i].active = 1; if (new_mtu_oh adapter-rx_buff_pool[i].buff_size) { - if (reinit netif_running(adapter-netdev)) { + if (netif_running(adapter-netdev)) { adapter-pool_config = 1; ibmveth_close(adapter-netdev); adapter-pool_config = 0; @@ -1402,14 +1407,15 @@ const char * buf, size_t count) return -EPERM; } - pool-active = 0; if (netif_running(netdev)) { adapter-pool_config = 1; ibmveth_close(netdev); + pool-active = 0; adapter-pool_config = 0; if ((rc = ibmveth_open(netdev))) return rc; } + pool-active = 0; } } else if (attr == veth_num_attr) { if (value = 0 || value IBMVETH_MAX_POOL_COUNT) ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 13/16 v4] ibmveth: enable driver for CMO
Enable ibmveth for Cooperative Memory Overcommitment (CMO). For this driver it means calculating a desired amount of IO memory based on the current MTU and updating this value with the bus when MTU changes occur. Because DMA mappings can fail, we have added a bounce buffer for temporary cases where the driver can not map IO memory for the buffer pool. The following changes are made to enable the driver for CMO: * DMA mapping errors will not result in error messages if entitlement has been exceeded and resources were not available. * DMA mapping errors are handled gracefully, ibmveth_replenish_buffer_pool() is corrected to check the return from dma_map_single and fail gracefully. * The driver will have a get_desired_dma function defined to function in a CMO environment. * When the MTU is changed, the driver will update the device IO entitlement Signed-off-by: Robert Jennings [EMAIL PROTECTED] Signed-off-by: Brian King [EMAIL PROTECTED] Signed-off-by: Santiago Leon [EMAIL PROTECTED] --- We would like to take this patch through linuxppc-dev with the full change set for this feature. We are copying netdev for review and ack. --- drivers/net/ibmveth.c | 169 -- drivers/net/ibmveth.h |5 + 2 files changed, 140 insertions(+), 34 deletions(-) Index: b/drivers/net/ibmveth.c === --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -33,6 +33,7 @@ */ #include linux/module.h +#include linux/moduleparam.h #include linux/types.h #include linux/errno.h #include linux/ioport.h @@ -52,7 +53,9 @@ #include asm/hvcall.h #include asm/atomic.h #include asm/vio.h +#include asm/iommu.h #include asm/uaccess.h +#include asm/firmware.h #include linux/seq_file.h #include ibmveth.h @@ -94,8 +97,10 @@ static void ibmveth_proc_register_adapte static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); +static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev); static struct kobj_type ktype_veth_pool; + #ifdef CONFIG_PROC_FS #define IBMVETH_PROC_DIR ibmveth static struct proc_dir_entry *ibmveth_proc_dir; @@ -226,16 +231,16 @@ static void ibmveth_replenish_buffer_poo u32 i; u32 count = pool-size - atomic_read(pool-available); u32 buffers_added = 0; + struct sk_buff *skb; + unsigned int free_index, index; + u64 correlator; + unsigned long lpar_rc; + dma_addr_t dma_addr; mb(); for(i = 0; i count; ++i) { - struct sk_buff *skb; - unsigned int free_index, index; - u64 correlator; union ibmveth_buf_desc desc; - unsigned long lpar_rc; - dma_addr_t dma_addr; skb = alloc_skb(pool-buff_size, GFP_ATOMIC); @@ -255,6 +260,9 @@ static void ibmveth_replenish_buffer_poo dma_addr = dma_map_single(adapter-vdev-dev, skb-data, pool-buff_size, DMA_FROM_DEVICE); + if (dma_mapping_error(dma_addr)) + goto failure; + pool-free_map[free_index] = IBM_VETH_INVALID_MAP; pool-dma_addr[index] = dma_addr; pool-skbuff[index] = skb; @@ -267,20 +275,9 @@ static void ibmveth_replenish_buffer_poo lpar_rc = h_add_logical_lan_buffer(adapter-vdev-unit_address, desc.desc); - if(lpar_rc != H_SUCCESS) { - pool-free_map[free_index] = index; - pool-skbuff[index] = NULL; - if (pool-consumer_index == 0) - pool-consumer_index = pool-size - 1; - else - pool-consumer_index--; - dma_unmap_single(adapter-vdev-dev, - pool-dma_addr[index], pool-buff_size, - DMA_FROM_DEVICE); - dev_kfree_skb_any(skb); - adapter-replenish_add_buff_failure++; - break; - } else { + if (lpar_rc != H_SUCCESS) + goto failure; + else { buffers_added++; adapter-replenish_add_buff_success++; } @@ -288,6 +285,24 @@ static void ibmveth_replenish_buffer_poo mb(); atomic_add(buffers_added, (pool-available)); + return; + +failure: + pool-free_map[free_index] = index; + pool-skbuff[index] = NULL; + if (pool-consumer_index == 0) + pool-consumer_index = pool-size - 1; + else + pool-consumer_index--; + if (!dma_mapping_error(dma_addr)) +
[PATCH 14/16 v4] ibmvscsi: driver enablement for CMO
From: Robert Jennings [EMAIL PROTECTED] Enable the driver to function in a Cooperative Memory Overcommitment (CMO) environment. The following changes are made to enable the driver for CMO: * DMA mapping errors will not result in error messages if entitlement has been exceeded and resources were not available. * The driver has a get_desired_dma function defined to function in a CMO environment. It will indicate how much IO memory it would like to function. Signed-off-by: Robert Jennings [EMAIL PROTECTED] Acked by: Brian King [EMAIL PROTECTED] --- We would like to take this patch through linuxppc-dev with the full change set for this feature. We are copying linux-scsi for review and ack. --- drivers/scsi/ibmvscsi/ibmvscsi.c | 45 +-- drivers/scsi/ibmvscsi/ibmvscsi.h |2 ++ 2 files changed, 40 insertions(+), 7 deletions(-) Index: b/drivers/scsi/ibmvscsi/ibmvscsi.c === --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -72,6 +72,7 @@ #include linux/delay.h #include asm/firmware.h #include asm/vio.h +#include asm/firmware.h #include scsi/scsi.h #include scsi/scsi_cmnd.h #include scsi/scsi_host.h @@ -426,8 +427,10 @@ static int map_sg_data(struct scsi_cmnd SG_ALL * sizeof(struct srp_direct_buf), evt_struct-ext_list_token, 0); if (!evt_struct-ext_list) { - sdev_printk(KERN_ERR, cmd-device, - Can't allocate memory for indirect table\n); + if (!firmware_has_feature(FW_FEATURE_CMO)) + sdev_printk(KERN_ERR, cmd-device, + Can't allocate memory + for indirect table\n); return 0; } } @@ -743,7 +746,9 @@ static int ibmvscsi_queuecommand(struct srp_cmd-lun = ((u64) lun) 48; if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata-dev)) { - sdev_printk(KERN_ERR, cmnd-device, couldn't convert cmd to srp_cmd\n); + if (!firmware_has_feature(FW_FEATURE_CMO)) + sdev_printk(KERN_ERR, cmnd-device, + couldn't convert cmd to srp_cmd\n); free_event_struct(hostdata-pool, evt_struct); return SCSI_MLQUEUE_HOST_BUSY; } @@ -855,7 +860,10 @@ static void send_mad_adapter_info(struct DMA_BIDIRECTIONAL); if (dma_mapping_error(req-buffer)) { - dev_err(hostdata-dev, Unable to map request_buffer for adapter_info!\n); + if (!firmware_has_feature(FW_FEATURE_CMO)) + dev_err(hostdata-dev, + Unable to map request_buffer for + adapter_info!\n); free_event_struct(hostdata-pool, evt_struct); return; } @@ -1400,7 +1408,9 @@ static int ibmvscsi_do_host_config(struc DMA_BIDIRECTIONAL); if (dma_mapping_error(host_config-buffer)) { - dev_err(hostdata-dev, dma_mapping error getting host config\n); + if (!firmware_has_feature(FW_FEATURE_CMO)) + dev_err(hostdata-dev, + dma_mapping error getting host config\n); free_event_struct(hostdata-pool, evt_struct); return -1; } @@ -1604,7 +1614,7 @@ static struct scsi_host_template driver_ .eh_host_reset_handler = ibmvscsi_eh_host_reset_handler, .slave_configure = ibmvscsi_slave_configure, .change_queue_depth = ibmvscsi_change_queue_depth, - .cmd_per_lun = 16, + .cmd_per_lun = IBMVSCSI_CMDS_PER_LUN_DEFAULT, .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, .this_id = -1, .sg_tablesize = SG_ALL, @@ -1613,6 +1623,26 @@ static struct scsi_host_template driver_ }; /** + * ibmvscsi_get_desired_dma - Calculate IO memory desired by the driver + * + * @vdev: struct vio_dev for the device whose desired IO mem is to be returned + * + * Return value: + * Number of bytes of IO data the driver will need to perform well. + */ +static unsigned long ibmvscsi_get_desired_dma(struct vio_dev *vdev) +{ + /* iu_storage data allocated in initialize_event_pool */ + unsigned long desired_io = max_requests * sizeof(union viosrp_iu); + + /* add io space for sg data */ + desired_io += (IBMVSCSI_MAX_SECTORS_DEFAULT * +IBMVSCSI_CMDS_PER_LUN_DEFAULT); + + return desired_io; +} + +/** * Called by bus code for each adapter */ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id
[PATCH 15/16 v4] ibmvfc: Add support for collaborative memory overcommit
From: Brian King [EMAIL PROTECTED] Adds support to the ibmvfc driver for collaborative memory overcommit. Signed-off-by: Brian King [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- We would like to take this patch through linuxppc-dev with the full change set for this feature. We are copying linux-scsi for review and ack. --- drivers/scsi/ibmvscsi/ibmvfc.c | 15 +++ 1 file changed, 15 insertions(+) Index: b/drivers/scsi/ibmvscsi/ibmvfc.c === --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3819,6 +3819,20 @@ static int ibmvfc_remove(struct vio_dev return 0; } +/** + * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver + * @vdev: vio device struct + * + * Return value: + * Number of bytes the driver will need to DMA map at the same time in + * order to perform well. + */ +static unsigned long ibmvfc_get_desired_dma(struct vio_dev *vdev) +{ + unsigned long pool_dma = max_requests * sizeof(union ibmvfc_iu); + return pool_dma + ((512 * 1024) * driver_template.cmd_per_lun); +} + static struct vio_device_id ibmvfc_device_table[] __devinitdata = { {fcp, IBM,vfc-client}, { , } @@ -3829,6 +3843,7 @@ static struct vio_driver ibmvfc_driver = .id_table = ibmvfc_device_table, .probe = ibmvfc_probe, .remove = ibmvfc_remove, + .get_desired_dma = ibmvfc_get_desired_dma, .driver = { .name = IBMVFC_NAME, .owner = THIS_MODULE, ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 16/16 v4] powerpc: Update arch vector to indicate support for CMO
From: Nathan Fontenot [EMAIL PROTECTED] Update the architecture vector to indicate that Cooperative Memory Overcommitment is supported if CONFIG_PPC_SMLPAR is set. Signed-off-by: Nathan Fontenot [EMAIL PROTECTED] Signed-off-by: Robert Jennings [EMAIL PROTECTED] --- This is the last patch in the series. Committing it will signal to the platform firmware is CMO enabled. Made this dependent on CONFIG_PPC_SMLPAR so that we don't advertise functionality when the kernel isn't supporting it. --- arch/powerpc/kernel/prom_init.c |9 - 1 file changed, 8 insertions(+), 1 deletion(-) Index: b/arch/powerpc/kernel/prom_init.c === --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -643,6 +643,11 @@ static void __init early_cmdline_parse(v #else #define OV5_MSI0x00 #endif /* CONFIG_PCI_MSI */ +#ifdef CONFIG_PPC_SMLPAR +#define OV5_CMO0x80/* Cooperative Memory Overcommitment */ +#else +#define OV5_CMO0x00 +#endif /* * The architecture vector has an array of PVR mask/value pairs, @@ -687,10 +692,12 @@ static unsigned char ibm_architecture_ve 0, /* don't halt */ /* option vector 5: PAPR/OF options */ - 3 - 2, /* length */ + 5 - 2, /* length */ 0, /* don't ignore, don't halt */ OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | OV5_DONATE_DEDICATE_CPU | OV5_MSI, + 0, + OV5_CMO, }; /* Old method - ELF header with PT_NOTE sections */ ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH] Remove kmalloc call in handling writes to lparcfg
There are only 4 valid name=value pairs for writes to /proc/ppc64/lparcfg. Current code allocates a buffer to copy this information in from the user. Since the longest name=value pair will easily fit into a buffer of 64 characters, simply put the buffer on the stack instead of allocating the buffer. NOTE: This patch applies on top of the CMO patches. Signed-off-by: Nathan Fotenot [EMAIL PROTECTED] --- Index: linux-2.6.git/arch/powerpc/kernel/lparcfg.c === --- linux-2.6.git.orig/arch/powerpc/kernel/lparcfg.c2008-07-22 13:17:40.0 -0500 +++ linux-2.6.git/arch/powerpc/kernel/lparcfg.c 2008-07-23 13:40:50.0 -0500 @@ -573,29 +573,27 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf, size_t count, loff_t * off) { - char *kbuf; + int kbuf_sz = 64; + char kbuf[kbuf_sz]; char *tmp; u64 new_entitled, *new_entitled_ptr = new_entitled; u8 new_weight, *new_weight_ptr = new_weight; - ssize_t retval = -ENOMEM; + ssize_t retval; if (!firmware_has_feature(FW_FEATURE_SPLPAR) || firmware_has_feature(FW_FEATURE_ISERIES)) return -EINVAL; - kbuf = kmalloc(count, GFP_KERNEL); - if (!kbuf) - goto out; + if (count kbuf_sz) + return -EINVAL; - retval = -EFAULT; if (copy_from_user(kbuf, buf, count)) - goto out; + return -EFAULT; - retval = -EINVAL; kbuf[count - 1] = '\0'; tmp = strchr(kbuf, '='); if (!tmp) - goto out; + return -EINVAL; *tmp++ = '\0'; @@ -603,32 +601,32 @@ char *endp; *new_entitled_ptr = (u64) simple_strtoul(tmp, endp, 10); if (endp == tmp) - goto out; + return -EINVAL; retval = update_ppp(new_entitled_ptr, NULL); } else if (!strcmp(kbuf, capacity_weight)) { char *endp; *new_weight_ptr = (u8) simple_strtoul(tmp, endp, 10); if (endp == tmp) - goto out; + return -EINVAL; retval = update_ppp(NULL, new_weight_ptr); } else if (!strcmp(kbuf, entitled_memory)) { char *endp; *new_entitled_ptr = (u64) simple_strtoul(tmp, endp, 10); if (endp == tmp) - goto out; + return -EINVAL; retval = update_mpp(new_entitled_ptr, NULL); } else if (!strcmp(kbuf, entitled_memory_weight)) { char *endp; *new_weight_ptr = (u8) simple_strtoul(tmp, endp, 10); if (endp == tmp) - goto out; + return -EINVAL; retval = update_mpp(NULL, new_weight_ptr); } else - goto out; + return -EINVAL; if (retval == H_SUCCESS || retval == H_CONSTRAINED) { retval = count; @@ -644,8 +642,6 @@ retval = -EIO; } -out: - kfree(kbuf); return retval; } ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH / RFC] net: don't grab a mutex within a timer context in gianfar
From: Sebastian Siewior [EMAIL PROTECTED] I got the following backtrace while network was unavailble: |NETDEV WATCHDOG: eth0: transmit timed out |BUG: sleeping function called from invalid context at /home/bigeasy/git/linux-2.6-powerpc/kernel/mutex.c:87 |in_atomic():1, irqs_disabled():0 |Call Trace: |[c0383d90] [c0006dd8] show_stack+0x48/0x184 (unreliable) |[c0383db0] [c001e938] __might_sleep+0xe0/0xf4 |[c0383dc0] [c025a43c] mutex_lock+0x24/0x3c |[c0383de0] [c019005c] phy_stop+0x20/0x70 |[c0383df0] [c018d4ec] stop_gfar+0x28/0xf4 |[c0383e10] [c018e8c4] gfar_timeout+0x30/0x60 |[c0383e20] [c01fe7c0] dev_watchdog+0xa8/0x144 |[c0383e30] [c002f93c] run_timer_softirq+0x148/0x1c8 |[c0383e60] [c002b084] __do_softirq+0x5c/0xc4 |[c0383e80] [c00046fc] do_softirq+0x3c/0x54 |[c0383e90] [c002ac60] irq_exit+0x3c/0x5c |[c0383ea0] [c000b378] timer_interrupt+0xe0/0xf8 |[c0383ec0] [c000e5ac] ret_from_except+0x0/0x18 |[c0383f80] [c000804c] cpu_idle+0xcc/0xdc |[c0383fa0] [c025c07c] etext+0x7c/0x90 |[c0383fc0] [c0338960] start_kernel+0x294/0x2a8 |[c0383ff0] [c3dc] skpinv+0x304/0x340 |[ cut here ] The phylock was once a spinlock but got changed into a mutex via commit 35b5f6b1a aka [PHYLIB: Locking fixes for PHY I/O potentially sleeping] Signed-off-by: Sebastian Siewior [EMAIL PROTECTED] --- bug report @ http://marc.info/?l=linux-netdevm=121638307116389w=2 I moved it into a workqueue, this is what tg3 does. I would convert the other three drivers unless $dude suggests a better method or somebody else takes care drivers/net/gianfar.c | 22 ++ drivers/net/gianfar.h |2 ++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 25bdd08..caa6cbd 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -112,6 +112,7 @@ const char gfar_driver_version[] = 1.3; static int gfar_enet_open(struct net_device *dev); static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev); +static void gfar_reset_task(struct work_struct *work); static void gfar_timeout(struct net_device *dev); static int gfar_close(struct net_device *dev); struct sk_buff *gfar_new_skb(struct net_device *dev); @@ -216,6 +217,7 @@ static int gfar_probe(struct platform_device *pdev) spin_lock_init(priv-txlock); spin_lock_init(priv-rxlock); + INIT_WORK(priv-reset_task, gfar_reset_task); platform_set_drvdata(pdev, dev); @@ -1132,6 +1134,7 @@ static int gfar_close(struct net_device *dev) napi_disable(priv-napi); #endif + cancel_work_sync(priv-reset_task); stop_gfar(dev); /* Disconnect from the PHY */ @@ -1246,13 +1249,16 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) return 0; } -/* gfar_timeout gets called when a packet has not been +/* gfar_reset_task gets scheduled when a packet has not been * transmitted after a set amount of time. * For now, assume that clearing out all the structures, and - * starting over will fix the problem. */ -static void gfar_timeout(struct net_device *dev) + * starting over will fix the problem. + */ +static void gfar_reset_task(struct work_struct *work) { - dev-stats.tx_errors++; + struct gfar_private *priv = container_of(work, struct gfar_private, + reset_task); + struct net_device *dev = priv-dev; if (dev-flags IFF_UP) { stop_gfar(dev); @@ -1262,6 +1268,14 @@ static void gfar_timeout(struct net_device *dev) netif_schedule(dev); } +static void gfar_timeout(struct net_device *dev) +{ + struct gfar_private *priv = netdev_priv(dev); + + dev-stats.tx_errors++; + schedule_work(priv-reset_task); +} + /* Interrupt Handler for Transmit complete */ static int gfar_clean_tx_ring(struct net_device *dev) { diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 27f37c8..d983a6a 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -759,6 +759,8 @@ struct gfar_private { uint32_t msg_enable; + struct work_struct reset_task; + /* Network Statistics */ struct gfar_extra_stats extra_stats; }; -- 1.5.5.2 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [RFC] [0/5] tuning options for PPC64
Hi, and thanks for the feedback. To make it short, the conclusions I draw from that are: - let the cpu type be choosen optionaly - both target cpu and tuning cpu should be selectable - if one cpu gets choosen, it should select some feature flag, mcpu and mtune option automatically in Kconfig.cputypes - if none gets choosen, all features will be selected (is this save?) I found these ppc64 cpu specific candidates for CONFIG_FEATURE-X: Altivec (G4, G5, POWER6+7, PA6T) BAT64 aka POWER3 (Power3) FPU (all) Std_MMU (all) Virt_CPU_Accounting (all, except PA6T?) VSX (power7) There are probably some more features present, which are currently enabled by some ifdefs for PPC64 and POWER4 (e.g. powermac/feature.c). I will not touch them due to my little knowledge and just keep these symbols. I guess this will become another long weekend ;-) Marvin On Monday 21 July 2008 09:02:47 Marvin wrote: Hi, the following five patches should lay a foundation to more fine-grained tuning on PPC64 cpus. They must be applied in order. The motivation are the discussions of serveral cpu specific optimizations in the past on this list, cleanup of the wired Makefile/CONFIG_POWERx constructs and at least the ownership of a PS3. The patches intoduce CONFIG_TUNE_some_cpu and CONFIG_OPT_EXCLUSIVE, with the aim to cover two common cases: - distributions want a common kernel, bootable on all ppc64 machines and tune for a certain cpu - high end users don't care about older cpus and want to compile a kernel with their favorite mcpu option I know there is also the possibility of mcpu=x and mtune=y, yx but this can be tackled in the next step (hopefully). I know this will bring up some conserns, but my initial findings grepping the defconfigs show: - CONFIG_POWER3 enables BATS only it is also used the enable some configs it is used always in combination with CONFIG_POWER4 - CONFIG_POWER4 is always combined with CONFIG_PPC64 and vice versa all POWER3 || POWER4 || PPC64 can be replaced by PPC64 - There seems to be no support for 32-bit kernels on ppc64 machines I hope for some feedback, so this new scheme (or some other) can be included to mainstream kernel. Greetings Marvin ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: bug: mutex_lock() in interrupt conntext via phy_stop() in gianfar
On Mon, 2008-07-21 at 17:57 -0500, Nate Case wrote: On Fri, 2008-07-18 at 14:10 +0200, Sebastian Siewior wrote: Commit 35b5f6b1a aka [PHYLIB: Locking fixes for PHY I/O potentially sleeping] changed the phydev-lock from spinlock into a mutex. Now, the following code path got triggered while NFS was unavailable: [snip] |[ 194.864733] BUG: sleeping function called from invalid context at /home/bigeasy/git/linux-2.6-powerpc/kernel/mutex.c:87 |[ 194.875529] in_atomic():1, irqs_disabled():0 |[ 194.879805] Call Trace: |[ 194.882250] [c0383d90] [c0006dd8] show_stack+0x48/0x184 (unreliable) |[ 194.888649] [c0383db0] [c001e938] __might_sleep+0xe0/0xf4 |[ 194.894069] [c0383dc0] [c025a43c] mutex_lock+0x24/0x3c |[ 194.899234] [c0383de0] [c019005c] phy_stop+0x20/0x70 |[ 194.904234] [c0383df0] [c018d4ec] stop_gfar+0x28/0xf4 |[ 194.909305] [c0383e10] [c018e8c4] gfar_timeout+0x30/0x60 |[ 194.914638] [c0383e20] [c01fe7c0] dev_watchdog+0xa8/0x144 Hmm.. I'm not sure what the best solution is to this. Make the stop_gfar() call happen in a workqueue, and make a similar change to ucc_geth, fec_mpc52xx, and fs_enet? Modify phy_stop() to do the work in a workqueue conditionally if in interrupt context? Between these two I'd lean toward the latter. Does anyone have any better ideas? Move the reset task to a workqueue. Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 0/2][RT] powerpc - fix bug in irq reverse mapping radix tree
The root cause of this bug lies in the fact that the XICS interrupt controller uses a radix tree for its reverse irq mapping and that we cannot allocate the tree nodes (even GFP_ATOMIC) with preemption disabled. Is that yet another caes of -rt changing some basic kernel semantics ? In fact, we have 2 nested preemption disabling when we want to allocate a new node: - setup_irq() does a spin_lock_irqsave() before calling xics_startup() which then calls irq_radix_revmap() to insert a new node in the tree - irq_radix_revmap() also does a spin_lock_irqsave() (in irq_radix_wrlock()) before the radix_tree_insert() The first patch moves the call to irq_radix_revmap() from xics_startup() out to xics_host_map_direct() and xics_host_map_lpar() which are called with preemption enabled. I suppose that would work. The second patch is a little more involved in that it takes advantage of the concurrent radix tree to simplify the locking requirements and allows to allocate a new node outside a preemption disabled section. I just hope I've correctly understood the concurrent radix trees semantic and got the (absence of) locking right. Hrm, that will need some scrutinity. Thanks for looking at this. Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: PIXIS gpio controller and gpio flags
On Wed, 23 Jul 2008, Anton Vorontsov wrote: On Mon, Jul 21, 2008 at 02:12:20PM -0700, Trent Piepho wrote: On Mon, 21 Jul 2008, Anton Vorontsov wrote: On Sat, Jul 19, 2008 at 02:08:01PM -0700, Trent Piepho wrote: It doesn't look like you have any way to unset the active low flag. What if I unload the leds-gpio driver (or another gpio user) and then try to use the gpio with something else? The active low flag is stuck on! Why would you want to unset the flags? It is specified in the device tree, and can't be changed. Specifying different flags for the same GPIO would be an error (plus, Linux forbids shared gpios, so you simply can't specify one gpio for several devices). You can't use the same gpio for two different things at the same time, but you can load a driver, unload it, and then load another. Hm.. yeah, this might happen. Now I tend to think that transparent active-low handling wasn't that good idea after all. So, something like of_gpio_is_active_low(device_node, gpioidx) should be implemented instead. This function will parse the gpio's = flags. Please speak up if you have any better ideas though. The flags could be provided via of_get_gpio. E.g., something like of_get_gpio(, u32 *flags), and if flags is non-NULL the gpio flags are left there. of_get_gpio already has the flags and some other of_get_* functions return multiple things like this. Or just have an active low property for the led: led.active_low = !!of_get_property(np, active-low, NULL); Pretty simple, just one line of code. At least if one looks just at leds-gpio, that's obviously the simplest way. Is active low a property of the led or a property of the gpio? I guess one could argue either way. It seems like putting one line of code leds-gpio driver is better than putting much more complex code into the gpio controller driver. And each gpio controller has to have that code too. Now you could say that each gpio user needing to support inverting gpios is a lot of code too, but I don't think it's necessary. Active low LEDs are common since gpios can usually sink more current than they can source. But other gpio users, like the I2C, SPI, MDIO drivers etc., haven't had a need to support inverting each signal. I'm also loathe to add software gpio inverting to my mpc8572 gpio driver. In addition to some LEDs there is also a bit-banged JTAG bus on the CPU GPIOs. I had to go to great lengths to get it fast enough and each instruction added to a gpio operation is going to cost me MHz. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH] powerpc/cell: set fixed mapping to weak if we find a pcie-endpoint
From: Mark Nelson [EMAIL PROTECTED] At the moment the fixed mapping is by default strongly ordered (the iommu_fixed=weak boot option must be used to make the fixed mapping weakly ordered). If we're on a setup where the southbridge is being used in endpoint mode (triblade and CAB boards) the default should be a weakly ordered fixed mapping. This adds a check so that if a node of type pcie-endpoint can be found in the device tree the fixed mapping is set to be weak by default (but can be overridden using iommu_fixed=strong). Signed-off-by: Mark Nelson [EMAIL PROTECTED] Acked-by: Arnd Bergmann [EMAIL PROTECTED] --- arch/powerpc/platforms/cell/iommu.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) Index: upstream/arch/powerpc/platforms/cell/iommu.c === --- upstream.orig/arch/powerpc/platforms/cell/iommu.c +++ upstream/arch/powerpc/platforms/cell/iommu.c @@ -1150,12 +1150,23 @@ static int iommu_fixed_disabled; static int __init setup_iommu_fixed(char *str) { + struct device_node *pciep = NULL; + if (strcmp(str, off) == 0) iommu_fixed_disabled = 1; - else if (strcmp(str, weak) == 0) + /* If we can find a pcie-endpoint in the device tree assume that +* we're on a triblade or a CAB so by default the fixed mapping +* should be set to be weakly ordered; but only if the boot +* option WASN'T set for strong ordering +*/ + pciep = of_find_node_by_type(NULL, pcie-endpoint); + + if (strcmp(str, weak) == 0 || (pciep strcmp(str, strong) != 0)) iommu_fixed_is_weak = 1; + of_node_put(pciep); + return 1; } __setup(iommu_fixed=, setup_iommu_fixed); ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 1/6] kvmppc: read device tree hypervisor node infrastructure
On Wed, Jul 23, 2008 at 10:36:42AM +0200, [EMAIL PROTECTED] wrote: Hi Christian, A few comments inlined ... diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h --- a/include/asm-powerpc/kvm_para.h +++ b/include/asm-powerpc/kvm_para.h @@ -14,7 +14,9 @@ * * Copyright IBM Corp. 2008 * - * Authors: Hollis Blanchard [EMAIL PROTECTED] + * Authors: + * Hollis Blanchard [EMAIL PROTECTED] + * Christian Ehrhardt [EMAIL PROTECTED] */ #ifndef __POWERPC_KVM_PARA_H__ @@ -22,15 +24,44 @@ #ifdef __KERNEL__ +#include linux/of.h + +static struct kvmppc_para_features { + char *dtcell; + int feature; +} para_features[] = { +}; + static inline int kvm_para_available(void) { - return 0; + struct device_node *dn; + + dn = of_find_node_by_path(/hypervisor); You need an of_node_put(dn); + + return !!dn; } static inline unsigned int kvm_arch_para_features(void) { - return 0; + struct device_node *dn; + const int *dtval; + unsigned int features = 0; + int i; + + dn = of_find_node_by_path(/hypervisor); + if (!dn) + return 0; + + for (i = 0; i ARRAY_SIZE(para_features)-1; i++) { Why -1? Isn't ARRAY_SIZE(para_features) adequate? + dtval = of_get_property(dn, para_features[i].dtcell, NULL); + if (dtval *dtval == 1) + features |= (1 para_features[i].feature); + } + You need an of_node_put(dn); + return features; } Yours Tony linux.conf.auhttp://www.marchsouth.org/ Jan 19 - 24 2009 The Australian Linux Technical Conference! ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 2/6] kvmppc: add hypercall infrastructure - host part
On Wed, Jul 23, 2008 at 10:36:43AM +0200, [EMAIL PROTECTED] wrote: From: Christian Ehrhardt [EMAIL PROTECTED] Hi Christian, A few comments diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -203,6 +203,24 @@ kvmppc_set_msr(vcpu, vcpu-arch.srr1); } +static int kvmppc_do_hypercall(struct kvm_vcpu *vcpu) +{ + int ret = 0; + + switch (vcpu-arch.gpr[0]) { + default: + printk(KERN_ERRunknown hypercall %d\n, vcpu-arch.gpr[0]); I think the preffered style is printk(KERN_ERR ...) You've made the same style mistake in most of you printk()'s in your other patches aswell. Yours Tony linux.conf.auhttp://www.marchsouth.org/ Jan 19 - 24 2009 The Australian Linux Technical Conference! ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 3/6] kvmppc: add hypercall infrastructure - guest part
On Wed, Jul 23, 2008 at 10:36:44AM +0200, [EMAIL PROTECTED] wrote: From: Christian Ehrhardt [EMAIL PROTECTED] Hi Christian, This adds the guest portion of the hypercall infrastructure, basically an illegal instruction with a defined layout. See http://kvm.qumranet.com/kvmwiki/PowerPC_Hypercall_ABI for more detail on the hypercall ABI for powerpc. Signed-off-by: Christian Ehrhardt [EMAIL PROTECTED] --- [diffstat] kvm_para.h | 16 1 file changed, 16 insertions(+) [diff] diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h --- a/include/asm-powerpc/kvm_para.h +++ b/include/asm-powerpc/kvm_para.h @@ -25,6 +25,8 @@ #ifdef __KERNEL__ #include linux/of.h + +#define KVM_HYPERCALL_BIN 0x03ff Ummm didn't you add this in patch 2 of 6? Yours Tony linux.conf.auhttp://www.marchsouth.org/ Jan 19 - 24 2009 The Australian Linux Technical Conference! ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 4/6] kvmppc: magic page hypercall - host part
On Wed, Jul 23, 2008 at 10:36:45AM +0200, [EMAIL PROTECTED] wrote: Hi Christian, long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { - return -EINVAL; + long r = -EINVAL; + + switch (ioctl) { + case KVM_GET_PPCPV_MAGICPAGE_SIZE: + r = -EINVAL; Not needed you set it on the declaration. + if (arg) + goto out; + r = 1024; Ummm what does 1024 represent? can it me #defined? or at least add a comment. + break; + default: + r = -EINVAL; Not needed you set it on the declaration. + } +out: + return r; } Yours Tony linux.conf.auhttp://www.marchsouth.org/ Jan 19 - 24 2009 The Australian Linux Technical Conference! ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 5/6] kvmppc: magic page paravirtualization - guest part
On Wed, Jul 23, 2008 at 10:36:46AM +0200, [EMAIL PROTECTED] wrote: Hi Christian, snip +/* + * this is guest memory granted to the hypervisor; + * the hypervisor can place data in this area and rewrite + * privileged instructions to read from this area without + * trapping. + * Only the Hypervisor needs to be aware of the structure layout + * which makes the guest more felxible - the guest only guarantees + * the size which is requested by the hypervisor and read from a + * device tree entry. + */ +void *kvm_magicpage; static? snip +/* reads the specified data field out of the hypervisor node */ +static inline int kvmppc_pv_read_data(char *dtcell) +{ + struct device_node *dn; + const int *dtval; + + dn = of_find_node_by_path(/hypervisor); + if (!dn) + return -EINVAL; + + dtval = of_get_property(dn, dtcell, NULL); + if (dtval) + return *dtval; + else + return -EINVAL; You need an of_node_put(dn) in this function somewhere. Yours Tony linux.conf.auhttp://www.marchsouth.org/ Jan 19 - 24 2009 The Australian Linux Technical Conference! ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 0/6][RFC] kvmppc: paravirtualization interface
On Wed, Jul 23, 2008 at 10:36:41AM +0200, [EMAIL PROTECTED] wrote: From: Christian Ehrhardt [EMAIL PROTECTED] This patch series implements a paravirtualization interface using: - the device tree mechanism to pass hypervisor informations to the guest - hypercalls for guest-host calls - an example exploiter of that interface (magic page) This is work in progress, but working so far. I just start to really exploit the fuctionality behind the magic page mechanism therefor I can't provide any performance improvements so far, but it is evolved enough for RFC and to start the standardization discussion. Are you aiming this for the current merge window, ie for 2.6.27? Yours Tony linux.conf.auhttp://www.marchsouth.org/ Jan 19 - 24 2009 The Australian Linux Technical Conference! ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Getting GPIO to build again
I just synced up to linus/master CC arch/powerpc/platforms/52xx/mpc52xx_gpio.o In file included from arch/powerpc/platforms/52xx/mpc52xx_gpio.c:22: include/linux/of_gpio.h:26: error: field 'gc' has incomplete type include/linux/of_gpio.h: In function 'to_of_gpio_chip': include/linux/of_gpio.h:34: warning: type defaults to 'int' in declaration of '__mptr' include/linux/of_gpio.h:34: warning: initialization from incompatible pointer type In file included from include/asm/gpio.h:18, from arch/powerpc/platforms/52xx/mpc52xx_gpio.c:26: include/asm-generic/gpio.h: At top level: include/asm-generic/gpio.h:24: error: redefinition of 'gpio_is_valid' include/linux/gpio.h:24: error: previous definition of 'gpio_is_valid' was here In file included from arch/powerpc/platforms/52xx/mpc52xx_gpio.c:26: include/asm/gpio.h:27: error: redefinition of 'gpio_get_value' include/linux/gpio.h:50: error: previous definition of 'gpio_get_value' was here include/asm/gpio.h:32: error: redefinition of 'gpio_set_value' include/linux/gpio.h:57: error: previous definition of 'gpio_set_value' was here include/asm/gpio.h:37: error: redefinition of 'gpio_cansleep' include/linux/gpio.h:63: error: previous definition of 'gpio_cansleep' was here include/asm/gpio.h:45: error: redefinition of 'gpio_to_irq' include/linux/gpio.h:83: error: previous definition of 'gpio_to_irq' was here include/asm/gpio.h:50: error: redefinition of 'irq_to_gpio' include/linux/gpio.h:90: error: previous definition of 'irq_to_gpio' was here make[2]: *** [arch/powerpc/platforms/52xx/mpc52xx_gpio.o] Error 1 make[1]: *** [arch/powerpc/platforms/52xx] Error 2 make: *** [arch/powerpc/platforms] Error 2 -- Jon Smirl [EMAIL PROTECTED] ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: Getting GPIO to build again
This lets me build again, no clue if it is the correct fix. diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 3a7a11a..e14dbe3 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -3,6 +3,7 @@ config OF_DEVICE depends on OF (SPARC || PPC_OF) config OF_GPIO + select GENERIC_GPIO def_bool y depends on OF PPC_OF HAVE_GPIO_LIB help -- Jon Smirl [EMAIL PROTECTED] ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] [V2] powerpc: Xilinx: PS2: driver updates based on review
Hi John, On Thu, Jul 10, 2008 at 12:34:43PM -0700, John Linn wrote: Review comments were incorporated to improve the driver. 1. Some data was eliminated that was not needed. 2. Renaming of variables for clarity. 3. Removed unneeded type casting. 4. Changed to use dev_err rather than other I/O. 5. Merged together some functions. 6. Added kerneldoc format to functions. There were some changes made to the original version of the patch that I applied so this one did not patch cleanly. I think I fixed it up right but if you could give it a look over before I commit it that would be great. Thanks! -- Dmitry Input: xilinx_ps2 - various cleanups From: John Linn [EMAIL PROTECTED] Review comments were incorporated to improve the driver. 1. Some data was eliminated that was not needed. 2. Renaming of variables for clarity. 3. Removed unneeded type casting. 4. Changed to use dev_err rather than other I/O. 5. Merged together some functions. 6. Added kerneldoc format to functions. Signed-off-by: Sadanand [EMAIL PROTECTED] Signed-off-by: John Linn [EMAIL PROTECTED] Acked-by: Peter Korsgaard [EMAIL PROTECTED] Acked-by: Grant Likely [EMAIL PROTECTED] Signed-off-by: Dmitry Torokhov [EMAIL PROTECTED] --- drivers/input/serio/xilinx_ps2.c | 211 +++--- 1 files changed, 108 insertions(+), 103 deletions(-) diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 0ed044d..85515cf 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -58,23 +58,20 @@ /* Mask for all the Receive Interrupts */ #define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \ - XPS2_IPIXR_RX_FULL) +XPS2_IPIXR_RX_FULL) /* Mask for all the Interrupts */ #define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \ - XPS2_IPIXR_WDT_TOUT) +XPS2_IPIXR_WDT_TOUT) /* Global Interrupt Enable mask */ #define XPS2_GIER_GIE_MASK 0x8000 struct xps2data { int irq; - u32 phys_addr; - u32 remap_size; spinlock_t lock; - u8 rxb; /* Rx buffer */ void __iomem *base_address; /* virt. address of control registers */ - unsigned int dfl; + unsigned int flags; struct serio serio; /* serio */ }; @@ -82,8 +79,13 @@ struct xps2data { /* XPS PS/2 data transmission calls */ // -/* - * xps2_recv() will attempt to receive a byte of data from the PS/2 port. +/** + * xps2_recv() - attempts to receive a byte from the PS/2 port. + * @drvdata: pointer to ps2 device private data structure + * @byte: address where the read data will be copied + * + * If there is any data available in the PS/2 receiver, this functions reads + * the data, otherwise it returns error. */ static int xps2_recv(struct xps2data *drvdata, u8 *byte) { @@ -116,33 +118,27 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id) /* Check which interrupt is active */ if (intr_sr XPS2_IPIXR_RX_OVF) - printk(KERN_WARNING %s: receive overrun error\n, - drvdata-serio.name); + dev_warn(drvdata-serio.dev.parent, receive overrun error\n); if (intr_sr XPS2_IPIXR_RX_ERR) - drvdata-dfl |= SERIO_PARITY; + drvdata-flags |= SERIO_PARITY; if (intr_sr (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT)) - drvdata-dfl |= SERIO_TIMEOUT; + drvdata-flags |= SERIO_TIMEOUT; if (intr_sr XPS2_IPIXR_RX_FULL) { - status = xps2_recv(drvdata, drvdata-rxb); + status = xps2_recv(drvdata, c); /* Error, if a byte is not received */ if (status) { - printk(KERN_ERR - %s: wrong rcvd byte count (%d)\n, - drvdata-serio.name, status); + dev_err(drvdata-serio.dev.parent, + wrong rcvd byte count (%d)\n, status); } else { - c = drvdata-rxb; - serio_interrupt(drvdata-serio, c, drvdata-dfl); - drvdata-dfl = 0; + serio_interrupt(drvdata-serio, c, drvdata-flags); + drvdata-flags = 0; } } - if (intr_sr XPS2_IPIXR_TX_ACK) - drvdata-dfl = 0; - return IRQ_HANDLED; } @@ -150,8 +146,15 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id) /* serio callbacks */ /***/ -/* - * sxps2_write() sends a byte out through the PS/2 interface. +/** + * sxps2_write() - sends a byte out through the PS/2 port. + * @pserio:pointer to the serio structure of the PS/2 port + *
section .dummy lma 0xc0294310 overlaps previous sections
Anybody else seeing these? With Linus' latest I get three of these warnings: .tmp_vmlinux1, .tmp_vmlinux2, and vmlinux. The kernel boots. Cheers, Sean ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH v2] powerpc/cell: set fixed mapping to weak if we find a pcie-endpoint
From: Mark Nelson [EMAIL PROTECTED] At the moment the fixed mapping is by default strongly ordered (the iommu_fixed=weak boot option must be used to make the fixed mapping weakly ordered). If we're on a setup where the southbridge is being used in endpoint mode (triblade and CAB boards) the default should be a weakly ordered fixed mapping. This adds a check so that if a node of type pcie-endpoint can be found in the device tree the fixed mapping is set to be weak by default (but can be overridden using iommu_fixed=strong). Signed-off-by: Mark Nelson [EMAIL PROTECTED] Acked-by: Arnd Bergmann [EMAIL PROTECTED] --- Updated thanks to Stephen Rothwell's tip that pciep didn't need to be initialized Sorry for any confusion arch/powerpc/platforms/cell/iommu.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) Index: upstream/arch/powerpc/platforms/cell/iommu.c === --- upstream.orig/arch/powerpc/platforms/cell/iommu.c +++ upstream/arch/powerpc/platforms/cell/iommu.c @@ -1150,12 +1150,23 @@ static int iommu_fixed_disabled; static int __init setup_iommu_fixed(char *str) { + struct device_node *pciep; + if (strcmp(str, off) == 0) iommu_fixed_disabled = 1; - else if (strcmp(str, weak) == 0) + /* If we can find a pcie-endpoint in the device tree assume that +* we're on a triblade or a CAB so by default the fixed mapping +* should be set to be weakly ordered; but only if the boot +* option WASN'T set for strong ordering +*/ + pciep = of_find_node_by_type(NULL, pcie-endpoint); + + if (strcmp(str, weak) == 0 || (pciep strcmp(str, strong) != 0)) iommu_fixed_is_weak = 1; + of_node_put(pciep); + return 1; } __setup(iommu_fixed=, setup_iommu_fixed); ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: Getting GPIO to build again
On Wed, Jul 23, 2008 at 11:09:59PM -0400, Jon Smirl wrote: I just synced up to linus/master There is a fix for this in my tree for the 5200, but ben/paulus haven't pulled it yet. g. CC arch/powerpc/platforms/52xx/mpc52xx_gpio.o In file included from arch/powerpc/platforms/52xx/mpc52xx_gpio.c:22: include/linux/of_gpio.h:26: error: field 'gc' has incomplete type include/linux/of_gpio.h: In function 'to_of_gpio_chip': include/linux/of_gpio.h:34: warning: type defaults to 'int' in declaration of '__mptr' include/linux/of_gpio.h:34: warning: initialization from incompatible pointer type In file included from include/asm/gpio.h:18, from arch/powerpc/platforms/52xx/mpc52xx_gpio.c:26: include/asm-generic/gpio.h: At top level: include/asm-generic/gpio.h:24: error: redefinition of 'gpio_is_valid' include/linux/gpio.h:24: error: previous definition of 'gpio_is_valid' was here In file included from arch/powerpc/platforms/52xx/mpc52xx_gpio.c:26: include/asm/gpio.h:27: error: redefinition of 'gpio_get_value' include/linux/gpio.h:50: error: previous definition of 'gpio_get_value' was here include/asm/gpio.h:32: error: redefinition of 'gpio_set_value' include/linux/gpio.h:57: error: previous definition of 'gpio_set_value' was here include/asm/gpio.h:37: error: redefinition of 'gpio_cansleep' include/linux/gpio.h:63: error: previous definition of 'gpio_cansleep' was here include/asm/gpio.h:45: error: redefinition of 'gpio_to_irq' include/linux/gpio.h:83: error: previous definition of 'gpio_to_irq' was here include/asm/gpio.h:50: error: redefinition of 'irq_to_gpio' include/linux/gpio.h:90: error: previous definition of 'irq_to_gpio' was here make[2]: *** [arch/powerpc/platforms/52xx/mpc52xx_gpio.o] Error 1 make[1]: *** [arch/powerpc/platforms/52xx] Error 2 make: *** [arch/powerpc/platforms] Error 2 -- Jon Smirl [EMAIL PROTECTED] ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev