Re: [PATCH v2] mm/ksm: ignore STABLE_FLAG of rmap_item->address in rmap_walk_ksm
[+Hugh Dickins] Cheers, Jia On 5/4/2018 11:11 AM, Jia He Wrote: In our armv8a server(QDF2400), I noticed lots of WARN_ON caused by PAGE_SIZE unaligned for rmap_item->address under memory pressure tests(start 20 guests and run memhog in the host). --begin-- [ 410.853828] WARNING: CPU: 4 PID: 4641 at arch/arm64/kvm/../../../virt/kvm/arm/mmu.c:1826 kvm_age_hva_handler+0xc0/0xc8 [ 410.864518] Modules linked in: vhost_net vhost tap xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 ip6t_rpfilter ipt_REJECT nf_reject_ipv4 ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter rpcrdma ib_isert iscsi_target_mod ib_iser libiscsi scsi_transport_iscsi ib_srpt target_core_mod ib_srp scsi_transport_srp ib_ipoib rdma_ucm ib_ucm ib_umad rdma_cm ib_cm iw_cm mlx5_ib vfat fat ib_uverbs dm_mirror dm_region_hash ib_core dm_log dm_mod crc32_ce ipmi_ssif sg nfsd [ 410.935101] auth_rpcgss nfs_acl lockd grace sunrpc ip_tables xfs libcrc32c mlx5_core ixgbe mlxfw devlink mdio ahci_platform libahci_platform qcom_emac libahci hdma hdma_mgmt i2c_qup [ 410.951369] CPU: 4 PID: 4641 Comm: memhog Tainted: GW 4.17.0-rc3+ #8 [ 410.959104] Hardware name: [ 410.969791] pstate: 8045 (Nzcv daif +PAN -UAO) [ 410.974575] pc : kvm_age_hva_handler+0xc0/0xc8 [ 410.979012] lr : handle_hva_to_gpa+0xa8/0xe0 [ 410.983274] sp : 801761553290 [ 410.986581] x29: 801761553290 x28: [ 410.991888] x27: 0002 x26: [ 410.997195] x25: 801765430058 x24: 080b5608 [ 411.002501] x23: x22: 8017ccb84000 [ 411.007807] x21: 03ff x20: 8017ccb84000 [ 411.013113] x19: fe00 x18: 08fb3c08 [ 411.018419] x17: x16: 0060001645820bd3 [ 411.023725] x15: 80176aacbc08 x14: [ 411.029031] x13: 0040 x12: 0228 [ 411.034337] x11: x10: [ 411.039643] x9 : 0010 x8 : 0004 [ 411.044949] x7 : x6 : 8017f077 [ 411.050255] x5 : fffda59f0200 x4 : [ 411.055561] x3 : x2 : fe00 [ 411.060867] x1 : 03ff x0 : 2000 [ 411.066173] Call trace: [ 411.068614] kvm_age_hva_handler+0xc0/0xc8 [ 411.072703] handle_hva_to_gpa+0xa8/0xe0 [ 411.076619] kvm_age_hva+0x4c/0xe8 [ 411.080014] kvm_mmu_notifier_clear_flush_young+0x54/0x98 [ 411.085408] __mmu_notifier_clear_flush_young+0x6c/0xa0 [ 411.090627] page_referenced_one+0x154/0x1d8 [ 411.094890] rmap_walk_ksm+0x12c/0x1d0 [ 411.098632] rmap_walk+0x94/0xa0 [ 411.101854] page_referenced+0x194/0x1b0 [ 411.105770] shrink_page_list+0x674/0xc28 [ 411.109772] shrink_inactive_list+0x26c/0x5b8 [ 411.114122] shrink_node_memcg+0x35c/0x620 [ 411.118211] shrink_node+0x100/0x430 [ 411.121778] do_try_to_free_pages+0xe0/0x3a8 [ 411.126041] try_to_free_pages+0xe4/0x230 [ 411.130045] __alloc_pages_nodemask+0x564/0xdc0 [ 411.134569] alloc_pages_vma+0x90/0x228 [ 411.138398] do_anonymous_page+0xc8/0x4d0 [ 411.142400] __handle_mm_fault+0x4a0/0x508 [ 411.146489] handle_mm_fault+0xf8/0x1b0 [ 411.150321] do_page_fault+0x218/0x4b8 [ 411.154064] do_translation_fault+0x90/0xa0 [ 411.158239] do_mem_abort+0x68/0xf0 [ 411.161721] el0_da+0x24/0x28 ---end--- In rmap_walk_ksm, the rmap_item->address might still have the STABLE_FLAG, then the start and end in handle_hva_to_gpa might not be PAGE_SIZE aligned. Thus it will cause exceptions in handle_hva_to_gpa on arm64. This patch fixes it by ignoring(not removing) the low bits of address when doing rmap_walk_ksm. Signed-off-by: jia...@hxt-semitech.com --- v2: refine the codes as suggested by Claudio Imbrenda mm/ksm.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mm/ksm.c b/mm/ksm.c index e3cbf9a..e6a9640 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -199,6 +199,8 @@ struct rmap_item { #define SEQNR_MASK0x0ff /* low bits of unstable tree seqnr */ #define UNSTABLE_FLAG 0x100 /* is a node of the unstable tree */ #define STABLE_FLAG 0x200 /* is listed from the stable tree */ +#define KSM_FLAG_MASK (SEQNR_MASK|UNSTABLE_FLAG|STABLE_FLAG) + /* to mask all the flags */ /* The stable and unstable tree heads */ static struct rb_root one_stable_tree[1] = { RB_ROOT }; @@ -2570,10 +2572,15 @@ void rmap_walk_ksm(struct page *page, struct rmap_walk_control *rwc)
Re: [PATCH v2] mm/ksm: ignore STABLE_FLAG of rmap_item->address in rmap_walk_ksm
[+Hugh Dickins] Cheers, Jia On 5/4/2018 11:11 AM, Jia He Wrote: In our armv8a server(QDF2400), I noticed lots of WARN_ON caused by PAGE_SIZE unaligned for rmap_item->address under memory pressure tests(start 20 guests and run memhog in the host). --begin-- [ 410.853828] WARNING: CPU: 4 PID: 4641 at arch/arm64/kvm/../../../virt/kvm/arm/mmu.c:1826 kvm_age_hva_handler+0xc0/0xc8 [ 410.864518] Modules linked in: vhost_net vhost tap xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 ip6t_rpfilter ipt_REJECT nf_reject_ipv4 ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter rpcrdma ib_isert iscsi_target_mod ib_iser libiscsi scsi_transport_iscsi ib_srpt target_core_mod ib_srp scsi_transport_srp ib_ipoib rdma_ucm ib_ucm ib_umad rdma_cm ib_cm iw_cm mlx5_ib vfat fat ib_uverbs dm_mirror dm_region_hash ib_core dm_log dm_mod crc32_ce ipmi_ssif sg nfsd [ 410.935101] auth_rpcgss nfs_acl lockd grace sunrpc ip_tables xfs libcrc32c mlx5_core ixgbe mlxfw devlink mdio ahci_platform libahci_platform qcom_emac libahci hdma hdma_mgmt i2c_qup [ 410.951369] CPU: 4 PID: 4641 Comm: memhog Tainted: GW 4.17.0-rc3+ #8 [ 410.959104] Hardware name: [ 410.969791] pstate: 8045 (Nzcv daif +PAN -UAO) [ 410.974575] pc : kvm_age_hva_handler+0xc0/0xc8 [ 410.979012] lr : handle_hva_to_gpa+0xa8/0xe0 [ 410.983274] sp : 801761553290 [ 410.986581] x29: 801761553290 x28: [ 410.991888] x27: 0002 x26: [ 410.997195] x25: 801765430058 x24: 080b5608 [ 411.002501] x23: x22: 8017ccb84000 [ 411.007807] x21: 03ff x20: 8017ccb84000 [ 411.013113] x19: fe00 x18: 08fb3c08 [ 411.018419] x17: x16: 0060001645820bd3 [ 411.023725] x15: 80176aacbc08 x14: [ 411.029031] x13: 0040 x12: 0228 [ 411.034337] x11: x10: [ 411.039643] x9 : 0010 x8 : 0004 [ 411.044949] x7 : x6 : 8017f077 [ 411.050255] x5 : fffda59f0200 x4 : [ 411.055561] x3 : x2 : fe00 [ 411.060867] x1 : 03ff x0 : 2000 [ 411.066173] Call trace: [ 411.068614] kvm_age_hva_handler+0xc0/0xc8 [ 411.072703] handle_hva_to_gpa+0xa8/0xe0 [ 411.076619] kvm_age_hva+0x4c/0xe8 [ 411.080014] kvm_mmu_notifier_clear_flush_young+0x54/0x98 [ 411.085408] __mmu_notifier_clear_flush_young+0x6c/0xa0 [ 411.090627] page_referenced_one+0x154/0x1d8 [ 411.094890] rmap_walk_ksm+0x12c/0x1d0 [ 411.098632] rmap_walk+0x94/0xa0 [ 411.101854] page_referenced+0x194/0x1b0 [ 411.105770] shrink_page_list+0x674/0xc28 [ 411.109772] shrink_inactive_list+0x26c/0x5b8 [ 411.114122] shrink_node_memcg+0x35c/0x620 [ 411.118211] shrink_node+0x100/0x430 [ 411.121778] do_try_to_free_pages+0xe0/0x3a8 [ 411.126041] try_to_free_pages+0xe4/0x230 [ 411.130045] __alloc_pages_nodemask+0x564/0xdc0 [ 411.134569] alloc_pages_vma+0x90/0x228 [ 411.138398] do_anonymous_page+0xc8/0x4d0 [ 411.142400] __handle_mm_fault+0x4a0/0x508 [ 411.146489] handle_mm_fault+0xf8/0x1b0 [ 411.150321] do_page_fault+0x218/0x4b8 [ 411.154064] do_translation_fault+0x90/0xa0 [ 411.158239] do_mem_abort+0x68/0xf0 [ 411.161721] el0_da+0x24/0x28 ---end--- In rmap_walk_ksm, the rmap_item->address might still have the STABLE_FLAG, then the start and end in handle_hva_to_gpa might not be PAGE_SIZE aligned. Thus it will cause exceptions in handle_hva_to_gpa on arm64. This patch fixes it by ignoring(not removing) the low bits of address when doing rmap_walk_ksm. Signed-off-by: jia...@hxt-semitech.com --- v2: refine the codes as suggested by Claudio Imbrenda mm/ksm.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mm/ksm.c b/mm/ksm.c index e3cbf9a..e6a9640 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -199,6 +199,8 @@ struct rmap_item { #define SEQNR_MASK0x0ff /* low bits of unstable tree seqnr */ #define UNSTABLE_FLAG 0x100 /* is a node of the unstable tree */ #define STABLE_FLAG 0x200 /* is listed from the stable tree */ +#define KSM_FLAG_MASK (SEQNR_MASK|UNSTABLE_FLAG|STABLE_FLAG) + /* to mask all the flags */ /* The stable and unstable tree heads */ static struct rb_root one_stable_tree[1] = { RB_ROOT }; @@ -2570,10 +2572,15 @@ void rmap_walk_ksm(struct page *page, struct rmap_walk_control *rwc)
Re: [PATCH v5 2/5] efi: Add embedded peripheral firmware support
Hi Hans, One comment below, which I missed in review before. On 29 April 2018 at 11:35, Hans de Goedewrote: > Just like with PCI options ROMs, which we save in the setup_efi_pci* > functions from arch/x86/boot/compressed/eboot.c, the EFI code / ROM itself > sometimes may contain data which is useful/necessary for peripheral drivers > to have access to. > > Specifically the EFI code may contain an embedded copy of firmware which > needs to be (re)loaded into the peripheral. Normally such firmware would be > part of linux-firmware, but in some cases this is not feasible, for 2 > reasons: > > 1) The firmware is customized for a specific use-case of the chipset / use > with a specific hardware model, so we cannot have a single firmware file > for the chipset. E.g. touchscreen controller firmwares are compiled > specifically for the hardware model they are used with, as they are > calibrated for a specific model digitizer. > > 2) Despite repeated attempts we have failed to get permission to > redistribute the firmware. This is especially a problem with customized > firmwares, these get created by the chip vendor for a specific ODM and the > copyright may partially belong with the ODM, so the chip vendor cannot > give a blanket permission to distribute these. > > This commit adds support for finding peripheral firmware embedded in the > EFI code and making this available to peripheral drivers through the > standard firmware loading mechanism. > > Note we check the EFI_BOOT_SERVICES_CODE for embedded firmware near the end > of start_kernel(), just before calling rest_init(), this is on purpose > because the typical EFI_BOOT_SERVICES_CODE memory-segment is too large for > early_memremap(), so the check must be done after mm_init(). This relies > on EFI_BOOT_SERVICES_CODE not being free-ed until efi_free_boot_services() > is called, which means that this will only work on x86 for now. > > Reported-by: Dave Olsthoorn > Suggested-by: Peter Jones > Acked-by: Ard Biesheuvel > Signed-off-by: Hans de Goede > --- [...] > diff --git a/drivers/firmware/efi/embedded-firmware.c > b/drivers/firmware/efi/embedded-firmware.c > new file mode 100644 > index ..22a0f598b53d > --- /dev/null > +++ b/drivers/firmware/efi/embedded-firmware.c > @@ -0,0 +1,149 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Support for extracting embedded firmware for peripherals from EFI code, > + * > + * Copyright (c) 2018 Hans de Goede > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct embedded_fw { > + struct list_head list; > + const char *name; > + void *data; > + size_t length; > +}; > + > +static LIST_HEAD(found_fw_list); > + > +static const struct dmi_system_id * const embedded_fw_table[] = { > + NULL > +}; > + > +/* > + * Note the efi_check_for_embedded_firmwares() code currently makes the > + * following 2 assumptions. This may needs to be revisited if embedded > firmware > + * is found where this is not true: > + * 1) The firmware is only found in EFI_BOOT_SERVICES_CODE memory segments > + * 2) The firmware always starts at an offset which is a multiple of 8 bytes > + */ > +static int __init efi_check_md_for_embedded_firmware( > + efi_memory_desc_t *md, const struct efi_embedded_fw_desc *desc) > +{ > + struct embedded_fw *fw; > + u64 i, size; > + u32 crc; > + u8 *mem; > + > + size = md->num_pages << EFI_PAGE_SHIFT; > + mem = memremap(md->phys_addr, size, MEMREMAP_WB); > + if (!mem) { > + pr_err("Error mapping EFI mem at %#llx\n", md->phys_addr); > + return -ENOMEM; > + } > + > + size -= desc->length; > + for (i = 0; i < size; i += 8) { > + if (*((u64 *)(mem + i)) != *((u64 *)desc->prefix)) > + continue; > + Please use the proper APIs here to cast u8* to u64*, i.e., either use get_unaligned64() or use memcmp() > + /* Seed with ~0, invert to match crc32 userspace utility */ > + crc = ~crc32(~0, mem + i, desc->length); > + if (crc == desc->crc) > + break; > + } > + > + memunmap(mem); > + > + if (i >= size) > + return -ENOENT; > + > + pr_info("Found EFI embedded fw '%s' crc %08x\n", desc->name, > desc->crc); > + > + fw = kmalloc(sizeof(*fw), GFP_KERNEL); > + if (!fw) > + return -ENOMEM; > + > + mem = memremap(md->phys_addr + i, desc->length, MEMREMAP_WB); > + if (!mem) { > + pr_err("Error mapping embedded firmware\n"); > + goto error_free_fw; > + } > + fw->data = kmemdup(mem, desc->length, GFP_KERNEL); > + memunmap(mem); > + if (!fw->data) > + goto error_free_fw; > + >
Re: [PATCH v5 2/5] efi: Add embedded peripheral firmware support
Hi Hans, One comment below, which I missed in review before. On 29 April 2018 at 11:35, Hans de Goede wrote: > Just like with PCI options ROMs, which we save in the setup_efi_pci* > functions from arch/x86/boot/compressed/eboot.c, the EFI code / ROM itself > sometimes may contain data which is useful/necessary for peripheral drivers > to have access to. > > Specifically the EFI code may contain an embedded copy of firmware which > needs to be (re)loaded into the peripheral. Normally such firmware would be > part of linux-firmware, but in some cases this is not feasible, for 2 > reasons: > > 1) The firmware is customized for a specific use-case of the chipset / use > with a specific hardware model, so we cannot have a single firmware file > for the chipset. E.g. touchscreen controller firmwares are compiled > specifically for the hardware model they are used with, as they are > calibrated for a specific model digitizer. > > 2) Despite repeated attempts we have failed to get permission to > redistribute the firmware. This is especially a problem with customized > firmwares, these get created by the chip vendor for a specific ODM and the > copyright may partially belong with the ODM, so the chip vendor cannot > give a blanket permission to distribute these. > > This commit adds support for finding peripheral firmware embedded in the > EFI code and making this available to peripheral drivers through the > standard firmware loading mechanism. > > Note we check the EFI_BOOT_SERVICES_CODE for embedded firmware near the end > of start_kernel(), just before calling rest_init(), this is on purpose > because the typical EFI_BOOT_SERVICES_CODE memory-segment is too large for > early_memremap(), so the check must be done after mm_init(). This relies > on EFI_BOOT_SERVICES_CODE not being free-ed until efi_free_boot_services() > is called, which means that this will only work on x86 for now. > > Reported-by: Dave Olsthoorn > Suggested-by: Peter Jones > Acked-by: Ard Biesheuvel > Signed-off-by: Hans de Goede > --- [...] > diff --git a/drivers/firmware/efi/embedded-firmware.c > b/drivers/firmware/efi/embedded-firmware.c > new file mode 100644 > index ..22a0f598b53d > --- /dev/null > +++ b/drivers/firmware/efi/embedded-firmware.c > @@ -0,0 +1,149 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Support for extracting embedded firmware for peripherals from EFI code, > + * > + * Copyright (c) 2018 Hans de Goede > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct embedded_fw { > + struct list_head list; > + const char *name; > + void *data; > + size_t length; > +}; > + > +static LIST_HEAD(found_fw_list); > + > +static const struct dmi_system_id * const embedded_fw_table[] = { > + NULL > +}; > + > +/* > + * Note the efi_check_for_embedded_firmwares() code currently makes the > + * following 2 assumptions. This may needs to be revisited if embedded > firmware > + * is found where this is not true: > + * 1) The firmware is only found in EFI_BOOT_SERVICES_CODE memory segments > + * 2) The firmware always starts at an offset which is a multiple of 8 bytes > + */ > +static int __init efi_check_md_for_embedded_firmware( > + efi_memory_desc_t *md, const struct efi_embedded_fw_desc *desc) > +{ > + struct embedded_fw *fw; > + u64 i, size; > + u32 crc; > + u8 *mem; > + > + size = md->num_pages << EFI_PAGE_SHIFT; > + mem = memremap(md->phys_addr, size, MEMREMAP_WB); > + if (!mem) { > + pr_err("Error mapping EFI mem at %#llx\n", md->phys_addr); > + return -ENOMEM; > + } > + > + size -= desc->length; > + for (i = 0; i < size; i += 8) { > + if (*((u64 *)(mem + i)) != *((u64 *)desc->prefix)) > + continue; > + Please use the proper APIs here to cast u8* to u64*, i.e., either use get_unaligned64() or use memcmp() > + /* Seed with ~0, invert to match crc32 userspace utility */ > + crc = ~crc32(~0, mem + i, desc->length); > + if (crc == desc->crc) > + break; > + } > + > + memunmap(mem); > + > + if (i >= size) > + return -ENOENT; > + > + pr_info("Found EFI embedded fw '%s' crc %08x\n", desc->name, > desc->crc); > + > + fw = kmalloc(sizeof(*fw), GFP_KERNEL); > + if (!fw) > + return -ENOMEM; > + > + mem = memremap(md->phys_addr + i, desc->length, MEMREMAP_WB); > + if (!mem) { > + pr_err("Error mapping embedded firmware\n"); > + goto error_free_fw; > + } > + fw->data = kmemdup(mem, desc->length, GFP_KERNEL); > + memunmap(mem); > + if (!fw->data) > + goto error_free_fw; > + > + fw->name = desc->name; > + fw->length = desc->length; > + list_add(>list, _fw_list); > + > + return
Re: [PATCH v2 2/2] mm: vmalloc: Pass proper vm_start into debugobjects
On 5/4/2018 3:12 AM, Andrew Morton wrote: On Tue, 17 Apr 2018 16:13:48 +0530 Chintan Pandyawrote: Client can call vunmap with some intermediate 'addr' which may not be the start of the VM area. Entire unmap code works with vm->vm_start which is proper but debug object API is called with 'addr'. This could be a problem within debug objects. Pass proper start address into debug object API. --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1124,15 +1124,15 @@ void vm_unmap_ram(const void *mem, unsigned int count) BUG_ON(addr > VMALLOC_END); BUG_ON(!PAGE_ALIGNED(addr)); - debug_check_no_locks_freed(mem, size); - if (likely(count <= VMAP_MAX_ALLOC)) { + debug_check_no_locks_freed(mem, size); vb_free(mem, size); return; } va = find_vmap_area(addr); BUG_ON(!va); + debug_check_no_locks_freed(va->va_start, (va->va_end - va->va_start)); free_unmap_vmap_area(va); } EXPORT_SYMBOL(vm_unmap_ram); hm, how did this sneak through? My bad. I had tested them but missed bringing these compile fixes to the patch file. Will be careful next time. mm/vmalloc.c:1139:29: warning: passing argument 1 of debug_check_no_locks_freed makes pointer from integer without a cast [-Wint-conversion] debug_check_no_locks_freed(va->va_start, (va->va_end - va->va_start)); --- a/mm/vmalloc.c~mm-vmalloc-pass-proper-vm_start-into-debugobjects-fix +++ a/mm/vmalloc.c @@ -1136,7 +1136,8 @@ void vm_unmap_ram(const void *mem, unsig va = find_vmap_area(addr); BUG_ON(!va); - debug_check_no_locks_freed(va->va_start, (va->va_end - va->va_start)); + debug_check_no_locks_freed((void *)va->va_start, + (va->va_end - va->va_start)); free_unmap_vmap_area(va); } EXPORT_SYMBOL(vm_unmap_ram); Chintan -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v2 2/2] mm: vmalloc: Pass proper vm_start into debugobjects
On 5/4/2018 3:12 AM, Andrew Morton wrote: On Tue, 17 Apr 2018 16:13:48 +0530 Chintan Pandya wrote: Client can call vunmap with some intermediate 'addr' which may not be the start of the VM area. Entire unmap code works with vm->vm_start which is proper but debug object API is called with 'addr'. This could be a problem within debug objects. Pass proper start address into debug object API. --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1124,15 +1124,15 @@ void vm_unmap_ram(const void *mem, unsigned int count) BUG_ON(addr > VMALLOC_END); BUG_ON(!PAGE_ALIGNED(addr)); - debug_check_no_locks_freed(mem, size); - if (likely(count <= VMAP_MAX_ALLOC)) { + debug_check_no_locks_freed(mem, size); vb_free(mem, size); return; } va = find_vmap_area(addr); BUG_ON(!va); + debug_check_no_locks_freed(va->va_start, (va->va_end - va->va_start)); free_unmap_vmap_area(va); } EXPORT_SYMBOL(vm_unmap_ram); hm, how did this sneak through? My bad. I had tested them but missed bringing these compile fixes to the patch file. Will be careful next time. mm/vmalloc.c:1139:29: warning: passing argument 1 of debug_check_no_locks_freed makes pointer from integer without a cast [-Wint-conversion] debug_check_no_locks_freed(va->va_start, (va->va_end - va->va_start)); --- a/mm/vmalloc.c~mm-vmalloc-pass-proper-vm_start-into-debugobjects-fix +++ a/mm/vmalloc.c @@ -1136,7 +1136,8 @@ void vm_unmap_ram(const void *mem, unsig va = find_vmap_area(addr); BUG_ON(!va); - debug_check_no_locks_freed(va->va_start, (va->va_end - va->va_start)); + debug_check_no_locks_freed((void *)va->va_start, + (va->va_end - va->va_start)); free_unmap_vmap_area(va); } EXPORT_SYMBOL(vm_unmap_ram); Chintan -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v5 2/5] efi: Add embedded peripheral firmware support
On 4 May 2018 at 01:29, Luis R. Rodriguezwrote: > On Sun, Apr 29, 2018 at 11:35:55AM +0200, Hans de Goede wrote: [...] >> diff --git a/Documentation/driver-api/firmware/request_firmware.rst >> b/Documentation/driver-api/firmware/request_firmware.rst >> index c8bddbdcfd10..560dfed76e38 100644 >> --- a/Documentation/driver-api/firmware/request_firmware.rst >> +++ b/Documentation/driver-api/firmware/request_firmware.rst >> @@ -73,3 +73,69 @@ If something went wrong firmware_request() returns >> non-zero and fw_entry >> is set to NULL. Once your driver is done with processing the firmware it >> can call call firmware_release(fw_entry) to release the firmware image >> and any related resource. >> + >> +EFI embedded firmware support >> += > > This is a new fallback mechanism, please see: > > Documentation/driver-api/firmware/fallback-mechanisms.rst > > Refer to the section "Types of fallback mechanisms", augument the list there > and then move the section "Firmware sysfs loading facility" to a new file, and > then add a new file for your own. > >> + >> +On some devices the system's EFI code / ROM may contain an embedded copy >> +of firmware for some of the system's integrated peripheral devices and >> +the peripheral's Linux device-driver needs to access this firmware. > > You in no way indicate this is a just an invented scheme, a custom solution > and > nothing standard. I realize Ard criticized that the EFI Firmware Volume > Protocol > is not part of the UEFI spec -- however it is a bit more widely used right? > Why can't Linux support it instead? > Most implementations of UEFI are based on PI, and so it is likely that the protocols are available. However, the PI spec does not cover firmware blobs, and so it is undefined whether such blobs are self contained (i.e., in separate files in the firmware volume), statically linked into the driver or maybe even encrypted or otherwise encapsulated, and the actual loadable image only lives in memory. Hans's case is the second one, i.e., the firmware is at an arbitrary offset in the driver image. Using the FV protocol in this case would result in a mix of both approaches: look up the driver file by GUID [which could change btw between different versions of the system firmware, although this is unlikely] and then still use the prefix/crc based approach to sift through the image itself. But my main objection is simply that from the UEFI forum point of view, there is a clear distinction between the OS visible interfaces in the UEFI spec and the internal interfaces in the PI spec (which for instance are not subject to the same rules when it comes to backward compatibility), and so I think we should not depend on PI at all. This is all the more important considering that we are trying to encourage the creation of other implementations of UEFI that are not based on PI (e.g., uboot for arm64 implements the required UEFI interfaces for booting the kernel via GRUB), and adding dependencies on PI protocols makes that a moving target. So in my view, we either take a ad-hoc approach which works for the few platforms we expect to support, in which case Hans's approach is sufficient, or we architect it properly, in which case we shouldn't depend on PI because it does not belong in a properly architected OS<->firmware exchange. -- Ard.
Re: [PATCH v5 2/5] efi: Add embedded peripheral firmware support
On 4 May 2018 at 01:29, Luis R. Rodriguez wrote: > On Sun, Apr 29, 2018 at 11:35:55AM +0200, Hans de Goede wrote: [...] >> diff --git a/Documentation/driver-api/firmware/request_firmware.rst >> b/Documentation/driver-api/firmware/request_firmware.rst >> index c8bddbdcfd10..560dfed76e38 100644 >> --- a/Documentation/driver-api/firmware/request_firmware.rst >> +++ b/Documentation/driver-api/firmware/request_firmware.rst >> @@ -73,3 +73,69 @@ If something went wrong firmware_request() returns >> non-zero and fw_entry >> is set to NULL. Once your driver is done with processing the firmware it >> can call call firmware_release(fw_entry) to release the firmware image >> and any related resource. >> + >> +EFI embedded firmware support >> += > > This is a new fallback mechanism, please see: > > Documentation/driver-api/firmware/fallback-mechanisms.rst > > Refer to the section "Types of fallback mechanisms", augument the list there > and then move the section "Firmware sysfs loading facility" to a new file, and > then add a new file for your own. > >> + >> +On some devices the system's EFI code / ROM may contain an embedded copy >> +of firmware for some of the system's integrated peripheral devices and >> +the peripheral's Linux device-driver needs to access this firmware. > > You in no way indicate this is a just an invented scheme, a custom solution > and > nothing standard. I realize Ard criticized that the EFI Firmware Volume > Protocol > is not part of the UEFI spec -- however it is a bit more widely used right? > Why can't Linux support it instead? > Most implementations of UEFI are based on PI, and so it is likely that the protocols are available. However, the PI spec does not cover firmware blobs, and so it is undefined whether such blobs are self contained (i.e., in separate files in the firmware volume), statically linked into the driver or maybe even encrypted or otherwise encapsulated, and the actual loadable image only lives in memory. Hans's case is the second one, i.e., the firmware is at an arbitrary offset in the driver image. Using the FV protocol in this case would result in a mix of both approaches: look up the driver file by GUID [which could change btw between different versions of the system firmware, although this is unlikely] and then still use the prefix/crc based approach to sift through the image itself. But my main objection is simply that from the UEFI forum point of view, there is a clear distinction between the OS visible interfaces in the UEFI spec and the internal interfaces in the PI spec (which for instance are not subject to the same rules when it comes to backward compatibility), and so I think we should not depend on PI at all. This is all the more important considering that we are trying to encourage the creation of other implementations of UEFI that are not based on PI (e.g., uboot for arm64 implements the required UEFI interfaces for booting the kernel via GRUB), and adding dependencies on PI protocols makes that a moving target. So in my view, we either take a ad-hoc approach which works for the few platforms we expect to support, in which case Hans's approach is sufficient, or we architect it properly, in which case we shouldn't depend on PI because it does not belong in a properly architected OS<->firmware exchange. -- Ard.
[PATCH v7 2/2] PCI: mediatek: Using chained IRQ to setup IRQ handle
From: Honghui ZhangUsing irq_chip solution to setup IRQs in order to consist with IRQ framework. Signed-off-by: Honghui Zhang Acked-by: Ryder Lee --- drivers/pci/host/pcie-mediatek.c | 206 ++- 1 file changed, 115 insertions(+), 91 deletions(-) diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c index c3dc549..dabf1086 100644 --- a/drivers/pci/host/pcie-mediatek.c +++ b/drivers/pci/host/pcie-mediatek.c @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -130,14 +132,12 @@ struct mtk_pcie_port; /** * struct mtk_pcie_soc - differentiate between host generations * @need_fix_class_id: whether this host's class ID needed to be fixed or not - * @has_msi: whether this host supports MSI interrupts or not * @ops: pointer to configuration access functions * @startup: pointer to controller setting functions * @setup_irq: pointer to initialize IRQ functions */ struct mtk_pcie_soc { bool need_fix_class_id; - bool has_msi; struct pci_ops *ops; int (*startup)(struct mtk_pcie_port *port); int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node); @@ -161,7 +161,9 @@ struct mtk_pcie_soc { * @lane: lane count * @slot: port slot * @irq_domain: legacy INTx IRQ domain + * @inner_domain: inner IRQ domain * @msi_domain: MSI IRQ domain + * @lock: protect the msi_irq_in_use bitmap * @msi_irq_in_use: bit map for assigned MSI IRQ */ struct mtk_pcie_port { @@ -179,7 +181,9 @@ struct mtk_pcie_port { u32 lane; u32 slot; struct irq_domain *irq_domain; + struct irq_domain *inner_domain; struct irq_domain *msi_domain; + struct mutex lock; DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM); }; @@ -446,103 +450,130 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) return 0; } -static int mtk_pcie_msi_alloc(struct mtk_pcie_port *port) +static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) { - int msi; + struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data); + phys_addr_t addr; - msi = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM); - if (msi < MTK_MSI_IRQS_NUM) - set_bit(msi, port->msi_irq_in_use); - else - return -ENOSPC; + /* MT2712/MT7622 only support 32-bit MSI addresses */ + addr = virt_to_phys(port->base + PCIE_MSI_VECTOR); + msg->address_hi = 0; + msg->address_lo = lower_32_bits(addr); + + msg->data = data->hwirq; - return msi; + dev_dbg(port->pcie->dev, "msi#%d address_hi %#x address_lo %#x\n", + (int)data->hwirq, msg->address_hi, msg->address_lo); } -static void mtk_pcie_msi_free(struct mtk_pcie_port *port, unsigned long hwirq) +static int mtk_msi_set_affinity(struct irq_data *irq_data, + const struct cpumask *mask, bool force) { - clear_bit(hwirq, port->msi_irq_in_use); +return -EINVAL; } -static int mtk_pcie_msi_setup_irq(struct msi_controller *chip, - struct pci_dev *pdev, struct msi_desc *desc) +static void mtk_msi_ack_irq(struct irq_data *data) { - struct mtk_pcie_port *port; - struct msi_msg msg; - unsigned int irq; - int hwirq; - phys_addr_t msg_addr; + struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data); + u32 hwirq = data->hwirq; - port = mtk_pcie_find_port(pdev->bus, pdev->devfn); - if (!port) - return -EINVAL; + writel(1 << hwirq, port->base + PCIE_IMSI_STATUS); +} - hwirq = mtk_pcie_msi_alloc(port); - if (hwirq < 0) - return hwirq; +static struct irq_chip mtk_msi_bottom_irq_chip = { + .name = "MTK MSI", + .irq_compose_msi_msg= mtk_compose_msi_msg, + .irq_set_affinity = mtk_msi_set_affinity, + .irq_ack= mtk_msi_ack_irq, +}; - irq = irq_create_mapping(port->msi_domain, hwirq); - if (!irq) { - mtk_pcie_msi_free(port, hwirq); - return -EINVAL; - } +static int mtk_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, +unsigned int nr_irqs, void *args) +{ + struct mtk_pcie_port *port = domain->host_data; + unsigned long bit; - chip->dev = >dev; + WARN_ON(nr_irqs != 1); + mutex_lock(>lock); - irq_set_msi_desc(irq, desc); + bit = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM); + if (bit >= MTK_MSI_IRQS_NUM) { + mutex_unlock(>lock); + return -ENOSPC; + } - /* MT2712/MT7622 only support 32-bit MSI addresses */ -
[PATCH v7 0/2] PCI: mediatek: Fixups for the IRQ handle routine and MT7622's class code
From: Honghui ZhangTwo fixups for mediatek's host bridge: The first patch fixup class type and vendor ID for MT7622. The second patch fixup the IRQ handle routine by using irq_chip solution to avoid IRQ reentry which may exist for both MT2712 and MT7622. Change since v6: - Remove the irq_mask, irq_unmask callback in lower layer irq_chip since we have set the MSI_FLAG_USE_DEF_CHIP_OPS flags. - Add irq_ack callback in irq_chip to handle edge IRQ. - Uing handle_edge_irq to handle the MSI IRQs. Change since v5: - Make the comments consistend with the code modification in the first patch. - Using writew to performing a 16-bit write. - Using irq_chip solution to fix the IRQ issue. The v5 patchset could be found in: https://patchwork.kernel.org/patch/10133303 https://patchwork.kernel.org/patch/10133305 Change since v4: - Only setup vendor ID for MT7622, igorning the device ID since mediatek's host bridge driver does not cares about the device ID. Change since v3: - Setup the class type and vendor ID at the beginning of startup instead of in a quirk. - Add mediatek's vendor ID, it could be found in: https://pcisig.com/membership/member-companies?combine==4 Change since v2: - Move the initialize of the iterate before the loop to fix an INTx IRQ issue in the first patch Change since v1: - Add the second patch. - Make the first patch's commit message more standard. Honghui Zhang (2): PCI: mediatek: Set up vendor ID and class type for MT7622 PCI: mediatek: Using chained IRQ to setup IRQ handle drivers/pci/host/pcie-mediatek.c | 234 +++ include/linux/pci_ids.h | 2 + 2 files changed, 143 insertions(+), 93 deletions(-) -- 2.6.4
[PATCH v7 2/2] PCI: mediatek: Using chained IRQ to setup IRQ handle
From: Honghui Zhang Using irq_chip solution to setup IRQs in order to consist with IRQ framework. Signed-off-by: Honghui Zhang Acked-by: Ryder Lee --- drivers/pci/host/pcie-mediatek.c | 206 ++- 1 file changed, 115 insertions(+), 91 deletions(-) diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c index c3dc549..dabf1086 100644 --- a/drivers/pci/host/pcie-mediatek.c +++ b/drivers/pci/host/pcie-mediatek.c @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -130,14 +132,12 @@ struct mtk_pcie_port; /** * struct mtk_pcie_soc - differentiate between host generations * @need_fix_class_id: whether this host's class ID needed to be fixed or not - * @has_msi: whether this host supports MSI interrupts or not * @ops: pointer to configuration access functions * @startup: pointer to controller setting functions * @setup_irq: pointer to initialize IRQ functions */ struct mtk_pcie_soc { bool need_fix_class_id; - bool has_msi; struct pci_ops *ops; int (*startup)(struct mtk_pcie_port *port); int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node); @@ -161,7 +161,9 @@ struct mtk_pcie_soc { * @lane: lane count * @slot: port slot * @irq_domain: legacy INTx IRQ domain + * @inner_domain: inner IRQ domain * @msi_domain: MSI IRQ domain + * @lock: protect the msi_irq_in_use bitmap * @msi_irq_in_use: bit map for assigned MSI IRQ */ struct mtk_pcie_port { @@ -179,7 +181,9 @@ struct mtk_pcie_port { u32 lane; u32 slot; struct irq_domain *irq_domain; + struct irq_domain *inner_domain; struct irq_domain *msi_domain; + struct mutex lock; DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM); }; @@ -446,103 +450,130 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) return 0; } -static int mtk_pcie_msi_alloc(struct mtk_pcie_port *port) +static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) { - int msi; + struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data); + phys_addr_t addr; - msi = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM); - if (msi < MTK_MSI_IRQS_NUM) - set_bit(msi, port->msi_irq_in_use); - else - return -ENOSPC; + /* MT2712/MT7622 only support 32-bit MSI addresses */ + addr = virt_to_phys(port->base + PCIE_MSI_VECTOR); + msg->address_hi = 0; + msg->address_lo = lower_32_bits(addr); + + msg->data = data->hwirq; - return msi; + dev_dbg(port->pcie->dev, "msi#%d address_hi %#x address_lo %#x\n", + (int)data->hwirq, msg->address_hi, msg->address_lo); } -static void mtk_pcie_msi_free(struct mtk_pcie_port *port, unsigned long hwirq) +static int mtk_msi_set_affinity(struct irq_data *irq_data, + const struct cpumask *mask, bool force) { - clear_bit(hwirq, port->msi_irq_in_use); +return -EINVAL; } -static int mtk_pcie_msi_setup_irq(struct msi_controller *chip, - struct pci_dev *pdev, struct msi_desc *desc) +static void mtk_msi_ack_irq(struct irq_data *data) { - struct mtk_pcie_port *port; - struct msi_msg msg; - unsigned int irq; - int hwirq; - phys_addr_t msg_addr; + struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data); + u32 hwirq = data->hwirq; - port = mtk_pcie_find_port(pdev->bus, pdev->devfn); - if (!port) - return -EINVAL; + writel(1 << hwirq, port->base + PCIE_IMSI_STATUS); +} - hwirq = mtk_pcie_msi_alloc(port); - if (hwirq < 0) - return hwirq; +static struct irq_chip mtk_msi_bottom_irq_chip = { + .name = "MTK MSI", + .irq_compose_msi_msg= mtk_compose_msi_msg, + .irq_set_affinity = mtk_msi_set_affinity, + .irq_ack= mtk_msi_ack_irq, +}; - irq = irq_create_mapping(port->msi_domain, hwirq); - if (!irq) { - mtk_pcie_msi_free(port, hwirq); - return -EINVAL; - } +static int mtk_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, +unsigned int nr_irqs, void *args) +{ + struct mtk_pcie_port *port = domain->host_data; + unsigned long bit; - chip->dev = >dev; + WARN_ON(nr_irqs != 1); + mutex_lock(>lock); - irq_set_msi_desc(irq, desc); + bit = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM); + if (bit >= MTK_MSI_IRQS_NUM) { + mutex_unlock(>lock); + return -ENOSPC; + } - /* MT2712/MT7622 only support 32-bit MSI addresses */ - msg_addr = virt_to_phys(port->base + PCIE_MSI_VECTOR); - msg.address_hi
[PATCH v7 0/2] PCI: mediatek: Fixups for the IRQ handle routine and MT7622's class code
From: Honghui Zhang Two fixups for mediatek's host bridge: The first patch fixup class type and vendor ID for MT7622. The second patch fixup the IRQ handle routine by using irq_chip solution to avoid IRQ reentry which may exist for both MT2712 and MT7622. Change since v6: - Remove the irq_mask, irq_unmask callback in lower layer irq_chip since we have set the MSI_FLAG_USE_DEF_CHIP_OPS flags. - Add irq_ack callback in irq_chip to handle edge IRQ. - Uing handle_edge_irq to handle the MSI IRQs. Change since v5: - Make the comments consistend with the code modification in the first patch. - Using writew to performing a 16-bit write. - Using irq_chip solution to fix the IRQ issue. The v5 patchset could be found in: https://patchwork.kernel.org/patch/10133303 https://patchwork.kernel.org/patch/10133305 Change since v4: - Only setup vendor ID for MT7622, igorning the device ID since mediatek's host bridge driver does not cares about the device ID. Change since v3: - Setup the class type and vendor ID at the beginning of startup instead of in a quirk. - Add mediatek's vendor ID, it could be found in: https://pcisig.com/membership/member-companies?combine==4 Change since v2: - Move the initialize of the iterate before the loop to fix an INTx IRQ issue in the first patch Change since v1: - Add the second patch. - Make the first patch's commit message more standard. Honghui Zhang (2): PCI: mediatek: Set up vendor ID and class type for MT7622 PCI: mediatek: Using chained IRQ to setup IRQ handle drivers/pci/host/pcie-mediatek.c | 234 +++ include/linux/pci_ids.h | 2 + 2 files changed, 143 insertions(+), 93 deletions(-) -- 2.6.4
[PATCH v7 1/2] PCI: mediatek: Set up vendor ID and class type for MT7622
From: Honghui ZhangMT7622's hardware default value of vendor ID and class type is not correct, fix that by setup the correct values before linkup with Endpoint. Signed-off-by: Honghui Zhang Acked-by: Ryder Lee --- drivers/pci/host/pcie-mediatek.c | 30 +++--- include/linux/pci_ids.h | 2 ++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c index a8b20c5..c3dc549 100644 --- a/drivers/pci/host/pcie-mediatek.c +++ b/drivers/pci/host/pcie-mediatek.c @@ -66,6 +66,10 @@ /* PCIe V2 per-port registers */ #define PCIE_MSI_VECTOR0x0c0 + +#define PCIE_CONF_VEND_ID 0x100 +#define PCIE_CONF_CLASS_ID 0x106 + #define PCIE_INT_MASK 0x420 #define INTX_MASK GENMASK(19, 16) #define INTX_SHIFT 16 @@ -125,12 +129,14 @@ struct mtk_pcie_port; /** * struct mtk_pcie_soc - differentiate between host generations + * @need_fix_class_id: whether this host's class ID needed to be fixed or not * @has_msi: whether this host supports MSI interrupts or not * @ops: pointer to configuration access functions * @startup: pointer to controller setting functions * @setup_irq: pointer to initialize IRQ functions */ struct mtk_pcie_soc { + bool need_fix_class_id; bool has_msi; struct pci_ops *ops; int (*startup)(struct mtk_pcie_port *port); @@ -375,6 +381,7 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) { struct mtk_pcie *pcie = port->pcie; struct resource *mem = >mem; + const struct mtk_pcie_soc *soc = port->pcie->soc; u32 val; size_t size; int err; @@ -403,6 +410,15 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) PCIE_MAC_SRSTB | PCIE_CRSTB; writel(val, port->base + PCIE_RST_CTRL); + /* Set up vendor ID and class code */ + if (soc->need_fix_class_id) { + val = PCI_VENDOR_ID_MEDIATEK; + writew(val, port->base + PCIE_CONF_VEND_ID); + + val = PCI_CLASS_BRIDGE_HOST; + writew(val, port->base + PCIE_CONF_CLASS_ID); + } + /* 100ms timeout value should be enough for Gen1/2 training */ err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val, !!(val & PCIE_PORT_LINKUP_V2), 20, @@ -1142,7 +1158,15 @@ static const struct mtk_pcie_soc mtk_pcie_soc_v1 = { .startup = mtk_pcie_startup_port, }; -static const struct mtk_pcie_soc mtk_pcie_soc_v2 = { +static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = { + .has_msi = true, + .ops = _pcie_ops_v2, + .startup = mtk_pcie_startup_port_v2, + .setup_irq = mtk_pcie_setup_irq, +}; + +static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = { + .need_fix_class_id = true, .has_msi = true, .ops = _pcie_ops_v2, .startup = mtk_pcie_startup_port_v2, @@ -1152,8 +1176,8 @@ static const struct mtk_pcie_soc mtk_pcie_soc_v2 = { static const struct of_device_id mtk_pcie_ids[] = { { .compatible = "mediatek,mt2701-pcie", .data = _pcie_soc_v1 }, { .compatible = "mediatek,mt7623-pcie", .data = _pcie_soc_v1 }, - { .compatible = "mediatek,mt2712-pcie", .data = _pcie_soc_v2 }, - { .compatible = "mediatek,mt7622-pcie", .data = _pcie_soc_v2 }, + { .compatible = "mediatek,mt2712-pcie", .data = _pcie_soc_mt2712 }, + { .compatible = "mediatek,mt7622-pcie", .data = _pcie_soc_mt7622 }, {}, }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index a6b3066..9d4fca5 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2115,6 +2115,8 @@ #define PCI_VENDOR_ID_MYRICOM 0x14c1 +#define PCI_VENDOR_ID_MEDIATEK 0x14c3 + #define PCI_VENDOR_ID_TITAN0x14D2 #define PCI_DEVICE_ID_TITAN_010L 0x8001 #define PCI_DEVICE_ID_TITAN_100L 0x8010 -- 2.6.4
[PATCH v7 1/2] PCI: mediatek: Set up vendor ID and class type for MT7622
From: Honghui Zhang MT7622's hardware default value of vendor ID and class type is not correct, fix that by setup the correct values before linkup with Endpoint. Signed-off-by: Honghui Zhang Acked-by: Ryder Lee --- drivers/pci/host/pcie-mediatek.c | 30 +++--- include/linux/pci_ids.h | 2 ++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c index a8b20c5..c3dc549 100644 --- a/drivers/pci/host/pcie-mediatek.c +++ b/drivers/pci/host/pcie-mediatek.c @@ -66,6 +66,10 @@ /* PCIe V2 per-port registers */ #define PCIE_MSI_VECTOR0x0c0 + +#define PCIE_CONF_VEND_ID 0x100 +#define PCIE_CONF_CLASS_ID 0x106 + #define PCIE_INT_MASK 0x420 #define INTX_MASK GENMASK(19, 16) #define INTX_SHIFT 16 @@ -125,12 +129,14 @@ struct mtk_pcie_port; /** * struct mtk_pcie_soc - differentiate between host generations + * @need_fix_class_id: whether this host's class ID needed to be fixed or not * @has_msi: whether this host supports MSI interrupts or not * @ops: pointer to configuration access functions * @startup: pointer to controller setting functions * @setup_irq: pointer to initialize IRQ functions */ struct mtk_pcie_soc { + bool need_fix_class_id; bool has_msi; struct pci_ops *ops; int (*startup)(struct mtk_pcie_port *port); @@ -375,6 +381,7 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) { struct mtk_pcie *pcie = port->pcie; struct resource *mem = >mem; + const struct mtk_pcie_soc *soc = port->pcie->soc; u32 val; size_t size; int err; @@ -403,6 +410,15 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) PCIE_MAC_SRSTB | PCIE_CRSTB; writel(val, port->base + PCIE_RST_CTRL); + /* Set up vendor ID and class code */ + if (soc->need_fix_class_id) { + val = PCI_VENDOR_ID_MEDIATEK; + writew(val, port->base + PCIE_CONF_VEND_ID); + + val = PCI_CLASS_BRIDGE_HOST; + writew(val, port->base + PCIE_CONF_CLASS_ID); + } + /* 100ms timeout value should be enough for Gen1/2 training */ err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val, !!(val & PCIE_PORT_LINKUP_V2), 20, @@ -1142,7 +1158,15 @@ static const struct mtk_pcie_soc mtk_pcie_soc_v1 = { .startup = mtk_pcie_startup_port, }; -static const struct mtk_pcie_soc mtk_pcie_soc_v2 = { +static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = { + .has_msi = true, + .ops = _pcie_ops_v2, + .startup = mtk_pcie_startup_port_v2, + .setup_irq = mtk_pcie_setup_irq, +}; + +static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = { + .need_fix_class_id = true, .has_msi = true, .ops = _pcie_ops_v2, .startup = mtk_pcie_startup_port_v2, @@ -1152,8 +1176,8 @@ static const struct mtk_pcie_soc mtk_pcie_soc_v2 = { static const struct of_device_id mtk_pcie_ids[] = { { .compatible = "mediatek,mt2701-pcie", .data = _pcie_soc_v1 }, { .compatible = "mediatek,mt7623-pcie", .data = _pcie_soc_v1 }, - { .compatible = "mediatek,mt2712-pcie", .data = _pcie_soc_v2 }, - { .compatible = "mediatek,mt7622-pcie", .data = _pcie_soc_v2 }, + { .compatible = "mediatek,mt2712-pcie", .data = _pcie_soc_mt2712 }, + { .compatible = "mediatek,mt7622-pcie", .data = _pcie_soc_mt7622 }, {}, }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index a6b3066..9d4fca5 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2115,6 +2115,8 @@ #define PCI_VENDOR_ID_MYRICOM 0x14c1 +#define PCI_VENDOR_ID_MEDIATEK 0x14c3 + #define PCI_VENDOR_ID_TITAN0x14D2 #define PCI_DEVICE_ID_TITAN_010L 0x8001 #define PCI_DEVICE_ID_TITAN_100L 0x8010 -- 2.6.4
Re: KASAN: use-after-free Read in process_preds
On Fri, Apr 27, 2018 at 5:19 PM, Dmitry Vyukovwrote: > On Fri, Apr 27, 2018 at 7:30 AM, syzbot > wrote: >> Hello, >> >> syzbot hit the following crash on bpf-next commit >> 5d1365940a68dd57b031b6e3c07d7d451cd69daf (Thu Apr 12 18:09:05 2018 +) >> Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net >> syzbot dashboard link: >> https://syzkaller.appspot.com/bug?extid=b6fc33dcecb65cd8ff80 >> >> Unfortunately, I don't have any reproducer for this crash yet. >> Raw console output: >> https://syzkaller.appspot.com/x/log.txt?id=4606019153952768 >> Kernel config: >> https://syzkaller.appspot.com/x/.config?id=-5947642240294114534 >> compiler: gcc (GCC) 8.0.1 20180413 (experimental) >> >> IMPORTANT: if you fix the bug, please add the following tag to the commit: >> Reported-by: syzbot+b6fc33dcecb65cd8f...@syzkaller.appspotmail.com >> It will help syzbot understand when the bug is fixed. See footer for >> details. >> If you forward the report, please keep this part and the footer. >> >> == >> BUG: KASAN: use-after-free in predicate_parse >> kernel/trace/trace_events_filter.c:563 [inline] >> BUG: KASAN: use-after-free in process_preds+0x197f/0x19b0 >> kernel/trace/trace_events_filter.c:1505 >> Read of size 4 at addr 8801b9832ce4 by task syz-executor0/28463 >> >> CPU: 0 PID: 28463 Comm: syz-executor0 Not tainted 4.16.0+ #2 >> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS >> Google 01/01/2011 >> Call Trace: >> __dump_stack lib/dump_stack.c:77 [inline] >> dump_stack+0x1b9/0x294 lib/dump_stack.c:113 >> print_address_description+0x6c/0x20b mm/kasan/report.c:256 >> kasan_report_error mm/kasan/report.c:354 [inline] >> kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 >> __asan_report_load4_noabort+0x14/0x20 mm/kasan/report.c:432 >> predicate_parse kernel/trace/trace_events_filter.c:563 [inline] >> process_preds+0x197f/0x19b0 kernel/trace/trace_events_filter.c:1505 >> create_filter+0x1a8/0x370 kernel/trace/trace_events_filter.c:1714 >> ftrace_profile_set_filter+0x109/0x2b0 >> kernel/trace/trace_events_filter.c:2042 >> perf_event_set_filter+0x248/0x1230 kernel/events/core.c:9064 >> _perf_ioctl+0x84c/0x15e0 kernel/events/core.c:5056 >> perf_ioctl+0x59/0x80 kernel/events/core.c:5107 >> vfs_ioctl fs/ioctl.c:46 [inline] >> file_ioctl fs/ioctl.c:500 [inline] >> do_vfs_ioctl+0x1cf/0x16a0 fs/ioctl.c:684 >> ksys_ioctl+0xa9/0xd0 fs/ioctl.c:701 >> SYSC_ioctl fs/ioctl.c:708 [inline] >> SyS_ioctl+0x24/0x30 fs/ioctl.c:706 >> do_syscall_64+0x29e/0x9d0 arch/x86/entry/common.c:287 >> entry_SYSCALL_64_after_hwframe+0x42/0xb7 >> RIP: 0033:0x455329 >> RSP: 002b:7f14b2c73c68 EFLAGS: 0246 ORIG_RAX: 0010 >> RAX: ffda RBX: 7f14b2c746d4 RCX: 00455329 >> RDX: 2040 RSI: 40082406 RDI: 0013 >> RBP: 0072bea0 R08: R09: >> R10: R11: 0246 R12: >> R13: 0291 R14: 006f6e38 R15: >> >> Allocated by task 2370: >> save_stack+0x43/0xd0 mm/kasan/kasan.c:448 >> set_track mm/kasan/kasan.c:460 [inline] >> kasan_kmalloc+0xc4/0xe0 mm/kasan/kasan.c:553 >> kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:490 >> kmem_cache_alloc+0x12e/0x760 mm/slab.c:3554 >> getname_flags+0xd0/0x5a0 fs/namei.c:140 >> getname+0x19/0x20 fs/namei.c:211 >> do_sys_open+0x39a/0x740 fs/open.c:1087 >> SYSC_open fs/open.c: [inline] >> SyS_open+0x2d/0x40 fs/open.c:1106 >> do_syscall_64+0x29e/0x9d0 arch/x86/entry/common.c:287 >> entry_SYSCALL_64_after_hwframe+0x42/0xb7 >> >> Freed by task 2370: >> save_stack+0x43/0xd0 mm/kasan/kasan.c:448 >> set_track mm/kasan/kasan.c:460 [inline] >> __kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521 >> kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528 >> __cache_free mm/slab.c:3498 [inline] >> kmem_cache_free+0x86/0x2d0 mm/slab.c:3756 >> putname+0xf2/0x130 fs/namei.c:261 >> do_sys_open+0x554/0x740 fs/open.c:1102 >> SYSC_open fs/open.c: [inline] >> SyS_open+0x2d/0x40 fs/open.c:1106 >> do_syscall_64+0x29e/0x9d0 arch/x86/entry/common.c:287 >> entry_SYSCALL_64_after_hwframe+0x42/0xb7 >> >> The buggy address belongs to the object at 8801b9832340 >> which belongs to the cache names_cache of size 4096 >> The buggy address is located 2468 bytes inside of >> 4096-byte region [8801b9832340, 8801b9833340) >> The buggy address belongs to the page: >> page:ea0006e60c80 count:1 mapcount:0 mapping:8801b9832340 index:0x0 >> compound_mapcount: 0 >> flags: 0x2fffc008100(slab|head) >> raw: 02fffc008100 8801b9832340 00010001 >> raw: ea000743eca0 ea0006628f20 8801dad86dc0 >> page dumped because: kasan: bad access detected >> >> Memory state around the buggy address: >>
Re: KASAN: use-after-free Read in process_preds
On Fri, Apr 27, 2018 at 5:19 PM, Dmitry Vyukov wrote: > On Fri, Apr 27, 2018 at 7:30 AM, syzbot > wrote: >> Hello, >> >> syzbot hit the following crash on bpf-next commit >> 5d1365940a68dd57b031b6e3c07d7d451cd69daf (Thu Apr 12 18:09:05 2018 +) >> Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net >> syzbot dashboard link: >> https://syzkaller.appspot.com/bug?extid=b6fc33dcecb65cd8ff80 >> >> Unfortunately, I don't have any reproducer for this crash yet. >> Raw console output: >> https://syzkaller.appspot.com/x/log.txt?id=4606019153952768 >> Kernel config: >> https://syzkaller.appspot.com/x/.config?id=-5947642240294114534 >> compiler: gcc (GCC) 8.0.1 20180413 (experimental) >> >> IMPORTANT: if you fix the bug, please add the following tag to the commit: >> Reported-by: syzbot+b6fc33dcecb65cd8f...@syzkaller.appspotmail.com >> It will help syzbot understand when the bug is fixed. See footer for >> details. >> If you forward the report, please keep this part and the footer. >> >> == >> BUG: KASAN: use-after-free in predicate_parse >> kernel/trace/trace_events_filter.c:563 [inline] >> BUG: KASAN: use-after-free in process_preds+0x197f/0x19b0 >> kernel/trace/trace_events_filter.c:1505 >> Read of size 4 at addr 8801b9832ce4 by task syz-executor0/28463 >> >> CPU: 0 PID: 28463 Comm: syz-executor0 Not tainted 4.16.0+ #2 >> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS >> Google 01/01/2011 >> Call Trace: >> __dump_stack lib/dump_stack.c:77 [inline] >> dump_stack+0x1b9/0x294 lib/dump_stack.c:113 >> print_address_description+0x6c/0x20b mm/kasan/report.c:256 >> kasan_report_error mm/kasan/report.c:354 [inline] >> kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 >> __asan_report_load4_noabort+0x14/0x20 mm/kasan/report.c:432 >> predicate_parse kernel/trace/trace_events_filter.c:563 [inline] >> process_preds+0x197f/0x19b0 kernel/trace/trace_events_filter.c:1505 >> create_filter+0x1a8/0x370 kernel/trace/trace_events_filter.c:1714 >> ftrace_profile_set_filter+0x109/0x2b0 >> kernel/trace/trace_events_filter.c:2042 >> perf_event_set_filter+0x248/0x1230 kernel/events/core.c:9064 >> _perf_ioctl+0x84c/0x15e0 kernel/events/core.c:5056 >> perf_ioctl+0x59/0x80 kernel/events/core.c:5107 >> vfs_ioctl fs/ioctl.c:46 [inline] >> file_ioctl fs/ioctl.c:500 [inline] >> do_vfs_ioctl+0x1cf/0x16a0 fs/ioctl.c:684 >> ksys_ioctl+0xa9/0xd0 fs/ioctl.c:701 >> SYSC_ioctl fs/ioctl.c:708 [inline] >> SyS_ioctl+0x24/0x30 fs/ioctl.c:706 >> do_syscall_64+0x29e/0x9d0 arch/x86/entry/common.c:287 >> entry_SYSCALL_64_after_hwframe+0x42/0xb7 >> RIP: 0033:0x455329 >> RSP: 002b:7f14b2c73c68 EFLAGS: 0246 ORIG_RAX: 0010 >> RAX: ffda RBX: 7f14b2c746d4 RCX: 00455329 >> RDX: 2040 RSI: 40082406 RDI: 0013 >> RBP: 0072bea0 R08: R09: >> R10: R11: 0246 R12: >> R13: 0291 R14: 006f6e38 R15: >> >> Allocated by task 2370: >> save_stack+0x43/0xd0 mm/kasan/kasan.c:448 >> set_track mm/kasan/kasan.c:460 [inline] >> kasan_kmalloc+0xc4/0xe0 mm/kasan/kasan.c:553 >> kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:490 >> kmem_cache_alloc+0x12e/0x760 mm/slab.c:3554 >> getname_flags+0xd0/0x5a0 fs/namei.c:140 >> getname+0x19/0x20 fs/namei.c:211 >> do_sys_open+0x39a/0x740 fs/open.c:1087 >> SYSC_open fs/open.c: [inline] >> SyS_open+0x2d/0x40 fs/open.c:1106 >> do_syscall_64+0x29e/0x9d0 arch/x86/entry/common.c:287 >> entry_SYSCALL_64_after_hwframe+0x42/0xb7 >> >> Freed by task 2370: >> save_stack+0x43/0xd0 mm/kasan/kasan.c:448 >> set_track mm/kasan/kasan.c:460 [inline] >> __kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521 >> kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528 >> __cache_free mm/slab.c:3498 [inline] >> kmem_cache_free+0x86/0x2d0 mm/slab.c:3756 >> putname+0xf2/0x130 fs/namei.c:261 >> do_sys_open+0x554/0x740 fs/open.c:1102 >> SYSC_open fs/open.c: [inline] >> SyS_open+0x2d/0x40 fs/open.c:1106 >> do_syscall_64+0x29e/0x9d0 arch/x86/entry/common.c:287 >> entry_SYSCALL_64_after_hwframe+0x42/0xb7 >> >> The buggy address belongs to the object at 8801b9832340 >> which belongs to the cache names_cache of size 4096 >> The buggy address is located 2468 bytes inside of >> 4096-byte region [8801b9832340, 8801b9833340) >> The buggy address belongs to the page: >> page:ea0006e60c80 count:1 mapcount:0 mapping:8801b9832340 index:0x0 >> compound_mapcount: 0 >> flags: 0x2fffc008100(slab|head) >> raw: 02fffc008100 8801b9832340 00010001 >> raw: ea000743eca0 ea0006628f20 8801dad86dc0 >> page dumped because: kasan: bad access detected >> >> Memory state around the buggy address: >> 8801b9832b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >>
Re: [PATCH 04/15] powerpc/powernv: opal-kmsg use flush fallback from console code
On Fri, 04 May 2018 15:16:37 +1000 Michael Ellermanwrote: > Nicholas Piggin writes: > > > Use the more refined and tested event polling loop from opal_put_chars > > as the fallback console flush in the opal-kmsg path. This loop is used > > by the console driver today, whereas the opal-kmsg fallback is not > > likely to have been used for years. > > > > Use WARN_ONCE rather than a printk when the fallback is invoked to > > prepare for moving the console flush into a common function. > > Do we want to add a WARN in that path? If we're panicking things might > get worse if we WARN (which takes a trap). True, probably a good idea not to... oh there's a printk_once so that'll work nicely. Thanks, Nick
Re: [PATCH 04/15] powerpc/powernv: opal-kmsg use flush fallback from console code
On Fri, 04 May 2018 15:16:37 +1000 Michael Ellerman wrote: > Nicholas Piggin writes: > > > Use the more refined and tested event polling loop from opal_put_chars > > as the fallback console flush in the opal-kmsg path. This loop is used > > by the console driver today, whereas the opal-kmsg fallback is not > > likely to have been used for years. > > > > Use WARN_ONCE rather than a printk when the fallback is invoked to > > prepare for moving the console flush into a common function. > > Do we want to add a WARN in that path? If we're panicking things might > get worse if we WARN (which takes a trap). True, probably a good idea not to... oh there's a printk_once so that'll work nicely. Thanks, Nick
Re: KASAN: use-after-free Write in process_preds
On Fri, May 4, 2018 at 7:30 AM, syzbotwrote: > Hello, > > syzbot found the following crash on: > > HEAD commit:03f5781be2c7 bpf, x86_32: add eBPF JIT compiler for ia32 > git tree: bpf-next > console output: https://syzkaller.appspot.com/x/log.txt?x=1362723780 > kernel config: https://syzkaller.appspot.com/x/.config?x=3d356c2d908b7293 > dashboard link: https://syzkaller.appspot.com/bug?extid=873ae613c636f037d5f8 > compiler: gcc (GCC) 8.0.1 20180413 (experimental) > > Unfortunately, I don't have any reproducer for this crash yet. > > IMPORTANT: if you fix the bug, please add the following tag to the commit: > Reported-by: syzbot+873ae613c636f037d...@syzkaller.appspotmail.com This looks similar to the old crash with reproducer: #syz dup: KASAN: slab-out-of-bounds Write in process_preds https://syzkaller.appspot.com/bug?id=e84ebd53b11608595ca4fd595d48ae9ddce9cf11 > == > BUG: KASAN: use-after-free in predicate_parse > kernel/trace/trace_events_filter.c:557 [inline] > BUG: KASAN: use-after-free in process_preds+0x1958/0x19b0 > kernel/trace/trace_events_filter.c:1505 > Write of size 4 at addr 8801ada34ff0 by task syz-executor3/6458 > > CPU: 0 PID: 6458 Comm: syz-executor3 Not tainted 4.17.0-rc2+ #22 > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS > Google 01/01/2011 > Call Trace: > __dump_stack lib/dump_stack.c:77 [inline] > dump_stack+0x1b9/0x294 lib/dump_stack.c:113 > print_address_description+0x6c/0x20b mm/kasan/report.c:256 > kasan_report_error mm/kasan/report.c:354 [inline] > kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 > __asan_report_store4_noabort+0x17/0x20 mm/kasan/report.c:437 > predicate_parse kernel/trace/trace_events_filter.c:557 [inline] > process_preds+0x1958/0x19b0 kernel/trace/trace_events_filter.c:1505 > create_filter+0x155/0x270 kernel/trace/trace_events_filter.c:1713 > ftrace_profile_set_filter+0x130/0x2e0 > kernel/trace/trace_events_filter.c:2038 > perf_event_set_filter+0x248/0x1230 kernel/events/core.c:9079 > _perf_ioctl+0x84c/0x15e0 kernel/events/core.c:5059 > perf_ioctl+0x59/0x80 kernel/events/core.c:5110 > vfs_ioctl fs/ioctl.c:46 [inline] > file_ioctl fs/ioctl.c:500 [inline] > do_vfs_ioctl+0x1cf/0x16a0 fs/ioctl.c:684 > ksys_ioctl+0xa9/0xd0 fs/ioctl.c:701 > __do_sys_ioctl fs/ioctl.c:708 [inline] > __se_sys_ioctl fs/ioctl.c:706 [inline] > __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:706 > do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 > entry_SYSCALL_64_after_hwframe+0x49/0xbe > RIP: 0033:0x455979 > RSP: 002b:7fd67f515c68 EFLAGS: 0246 ORIG_RAX: 0010 > RAX: ffda RBX: 7fd67f5166d4 RCX: 00455979 > RDX: 2040 RSI: 40082406 RDI: 0013 > RBP: 0072bea0 R08: R09: > R10: R11: 0246 R12: > R13: 02bf R14: 006f8288 R15: > > The buggy address belongs to the page: > page:ea0006b68d00 count:0 mapcount:0 mapping: index:0x0 > flags: 0x2fffc00() > raw: 02fffc00 > raw: 8801daf2fcd8 ea0006a5d9e0 > page dumped because: kasan: bad access detected > > Memory state around the buggy address: > 8801ada34e80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > 8801ada34f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff >> >> 8801ada34f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > > ^ > 8801ada35000: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc > 8801ada35080: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc > == > > > --- > This bug is generated by a bot. It may contain errors. > See https://goo.gl/tpsmEJ for more information about syzbot. > syzbot engineers can be reached at syzkal...@googlegroups.com. > > syzbot will keep track of this bug report. > If you forgot to add the Reported-by tag, once the fix for this bug is > merged > into any tree, please reply to this email with: > #syz fix: exact-commit-title > To mark this as a duplicate of another syzbot report, please reply with: > #syz dup: exact-subject-of-another-report > If it's a one-off invalid bug report, please reply with: > #syz invalid > Note: if the crash happens again, it will cause creation of a new bug > report. > Note: all commands must start from beginning of the line in the email body. > > -- > You received this message because you are subscribed to the Google Groups > "syzkaller-bugs" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to syzkaller-bugs+unsubscr...@googlegroups.com. > To view this discussion on the web visit >
Re: KASAN: use-after-free Write in process_preds
On Fri, May 4, 2018 at 7:30 AM, syzbot wrote: > Hello, > > syzbot found the following crash on: > > HEAD commit:03f5781be2c7 bpf, x86_32: add eBPF JIT compiler for ia32 > git tree: bpf-next > console output: https://syzkaller.appspot.com/x/log.txt?x=1362723780 > kernel config: https://syzkaller.appspot.com/x/.config?x=3d356c2d908b7293 > dashboard link: https://syzkaller.appspot.com/bug?extid=873ae613c636f037d5f8 > compiler: gcc (GCC) 8.0.1 20180413 (experimental) > > Unfortunately, I don't have any reproducer for this crash yet. > > IMPORTANT: if you fix the bug, please add the following tag to the commit: > Reported-by: syzbot+873ae613c636f037d...@syzkaller.appspotmail.com This looks similar to the old crash with reproducer: #syz dup: KASAN: slab-out-of-bounds Write in process_preds https://syzkaller.appspot.com/bug?id=e84ebd53b11608595ca4fd595d48ae9ddce9cf11 > == > BUG: KASAN: use-after-free in predicate_parse > kernel/trace/trace_events_filter.c:557 [inline] > BUG: KASAN: use-after-free in process_preds+0x1958/0x19b0 > kernel/trace/trace_events_filter.c:1505 > Write of size 4 at addr 8801ada34ff0 by task syz-executor3/6458 > > CPU: 0 PID: 6458 Comm: syz-executor3 Not tainted 4.17.0-rc2+ #22 > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS > Google 01/01/2011 > Call Trace: > __dump_stack lib/dump_stack.c:77 [inline] > dump_stack+0x1b9/0x294 lib/dump_stack.c:113 > print_address_description+0x6c/0x20b mm/kasan/report.c:256 > kasan_report_error mm/kasan/report.c:354 [inline] > kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 > __asan_report_store4_noabort+0x17/0x20 mm/kasan/report.c:437 > predicate_parse kernel/trace/trace_events_filter.c:557 [inline] > process_preds+0x1958/0x19b0 kernel/trace/trace_events_filter.c:1505 > create_filter+0x155/0x270 kernel/trace/trace_events_filter.c:1713 > ftrace_profile_set_filter+0x130/0x2e0 > kernel/trace/trace_events_filter.c:2038 > perf_event_set_filter+0x248/0x1230 kernel/events/core.c:9079 > _perf_ioctl+0x84c/0x15e0 kernel/events/core.c:5059 > perf_ioctl+0x59/0x80 kernel/events/core.c:5110 > vfs_ioctl fs/ioctl.c:46 [inline] > file_ioctl fs/ioctl.c:500 [inline] > do_vfs_ioctl+0x1cf/0x16a0 fs/ioctl.c:684 > ksys_ioctl+0xa9/0xd0 fs/ioctl.c:701 > __do_sys_ioctl fs/ioctl.c:708 [inline] > __se_sys_ioctl fs/ioctl.c:706 [inline] > __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:706 > do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 > entry_SYSCALL_64_after_hwframe+0x49/0xbe > RIP: 0033:0x455979 > RSP: 002b:7fd67f515c68 EFLAGS: 0246 ORIG_RAX: 0010 > RAX: ffda RBX: 7fd67f5166d4 RCX: 00455979 > RDX: 2040 RSI: 40082406 RDI: 0013 > RBP: 0072bea0 R08: R09: > R10: R11: 0246 R12: > R13: 02bf R14: 006f8288 R15: > > The buggy address belongs to the page: > page:ea0006b68d00 count:0 mapcount:0 mapping: index:0x0 > flags: 0x2fffc00() > raw: 02fffc00 > raw: 8801daf2fcd8 ea0006a5d9e0 > page dumped because: kasan: bad access detected > > Memory state around the buggy address: > 8801ada34e80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > 8801ada34f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff >> >> 8801ada34f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > > ^ > 8801ada35000: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc > 8801ada35080: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc > == > > > --- > This bug is generated by a bot. It may contain errors. > See https://goo.gl/tpsmEJ for more information about syzbot. > syzbot engineers can be reached at syzkal...@googlegroups.com. > > syzbot will keep track of this bug report. > If you forgot to add the Reported-by tag, once the fix for this bug is > merged > into any tree, please reply to this email with: > #syz fix: exact-commit-title > To mark this as a duplicate of another syzbot report, please reply with: > #syz dup: exact-subject-of-another-report > If it's a one-off invalid bug report, please reply with: > #syz invalid > Note: if the crash happens again, it will cause creation of a new bug > report. > Note: all commands must start from beginning of the line in the email body. > > -- > You received this message because you are subscribed to the Google Groups > "syzkaller-bugs" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to syzkaller-bugs+unsubscr...@googlegroups.com. > To view this discussion on the web visit >
Re: [PATCH v2] staging: lustre: llite: fix potential missing-check bug when copying lumv
On Fri, May 4, 2018 at 12:27 AM, Dan Carpenterwrote: > There is no security problem here. The user is allowed to choose either > v1 or v3. Using a double read race condition to choose v1 is not > going to cause problems. It's slightly more complicated than just > choosing it directly but that doesn't make it a security issue. > > It's a bit like typing with your feet in that just because using your > toes instead of your fingergs is more complicated, it doesn't make it a > security issue. > > regards, > dan carpenter > Thanks again for your comment, Dan! I revised the commit message and removed the security risk: However, given that the user data resides in the user space, a malicious user-space process can race to change the data between the two copies. By doing so, the user can provide a data with an inconsistent version, e.g., v1 version + v3 data. To improve code readability and make static analysis tools happy, which will warn about read-verify-re-read type bugs, this issue should be fixed. Thanks, Wenwen
Re: [PATCH v2] staging: lustre: llite: fix potential missing-check bug when copying lumv
On Fri, May 4, 2018 at 12:27 AM, Dan Carpenter wrote: > There is no security problem here. The user is allowed to choose either > v1 or v3. Using a double read race condition to choose v1 is not > going to cause problems. It's slightly more complicated than just > choosing it directly but that doesn't make it a security issue. > > It's a bit like typing with your feet in that just because using your > toes instead of your fingergs is more complicated, it doesn't make it a > security issue. > > regards, > dan carpenter > Thanks again for your comment, Dan! I revised the commit message and removed the security risk: However, given that the user data resides in the user space, a malicious user-space process can race to change the data between the two copies. By doing so, the user can provide a data with an inconsistent version, e.g., v1 version + v3 data. To improve code readability and make static analysis tools happy, which will warn about read-verify-re-read type bugs, this issue should be fixed. Thanks, Wenwen
KASAN: use-after-free Write in process_preds
Hello, syzbot found the following crash on: HEAD commit:03f5781be2c7 bpf, x86_32: add eBPF JIT compiler for ia32 git tree: bpf-next console output: https://syzkaller.appspot.com/x/log.txt?x=1362723780 kernel config: https://syzkaller.appspot.com/x/.config?x=3d356c2d908b7293 dashboard link: https://syzkaller.appspot.com/bug?extid=873ae613c636f037d5f8 compiler: gcc (GCC) 8.0.1 20180413 (experimental) Unfortunately, I don't have any reproducer for this crash yet. IMPORTANT: if you fix the bug, please add the following tag to the commit: Reported-by: syzbot+873ae613c636f037d...@syzkaller.appspotmail.com == BUG: KASAN: use-after-free in predicate_parse kernel/trace/trace_events_filter.c:557 [inline] BUG: KASAN: use-after-free in process_preds+0x1958/0x19b0 kernel/trace/trace_events_filter.c:1505 Write of size 4 at addr 8801ada34ff0 by task syz-executor3/6458 CPU: 0 PID: 6458 Comm: syz-executor3 Not tainted 4.17.0-rc2+ #22 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1b9/0x294 lib/dump_stack.c:113 print_address_description+0x6c/0x20b mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 __asan_report_store4_noabort+0x17/0x20 mm/kasan/report.c:437 predicate_parse kernel/trace/trace_events_filter.c:557 [inline] process_preds+0x1958/0x19b0 kernel/trace/trace_events_filter.c:1505 create_filter+0x155/0x270 kernel/trace/trace_events_filter.c:1713 ftrace_profile_set_filter+0x130/0x2e0 kernel/trace/trace_events_filter.c:2038 perf_event_set_filter+0x248/0x1230 kernel/events/core.c:9079 _perf_ioctl+0x84c/0x15e0 kernel/events/core.c:5059 perf_ioctl+0x59/0x80 kernel/events/core.c:5110 vfs_ioctl fs/ioctl.c:46 [inline] file_ioctl fs/ioctl.c:500 [inline] do_vfs_ioctl+0x1cf/0x16a0 fs/ioctl.c:684 ksys_ioctl+0xa9/0xd0 fs/ioctl.c:701 __do_sys_ioctl fs/ioctl.c:708 [inline] __se_sys_ioctl fs/ioctl.c:706 [inline] __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:706 do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x455979 RSP: 002b:7fd67f515c68 EFLAGS: 0246 ORIG_RAX: 0010 RAX: ffda RBX: 7fd67f5166d4 RCX: 00455979 RDX: 2040 RSI: 40082406 RDI: 0013 RBP: 0072bea0 R08: R09: R10: R11: 0246 R12: R13: 02bf R14: 006f8288 R15: The buggy address belongs to the page: page:ea0006b68d00 count:0 mapcount:0 mapping: index:0x0 flags: 0x2fffc00() raw: 02fffc00 raw: 8801daf2fcd8 ea0006a5d9e0 page dumped because: kasan: bad access detected Memory state around the buggy address: 8801ada34e80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 8801ada34f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 8801ada34f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ^ 8801ada35000: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc 8801ada35080: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc == --- This bug is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkal...@googlegroups.com. syzbot will keep track of this bug report. If you forgot to add the Reported-by tag, once the fix for this bug is merged into any tree, please reply to this email with: #syz fix: exact-commit-title To mark this as a duplicate of another syzbot report, please reply with: #syz dup: exact-subject-of-another-report If it's a one-off invalid bug report, please reply with: #syz invalid Note: if the crash happens again, it will cause creation of a new bug report. Note: all commands must start from beginning of the line in the email body.
KASAN: use-after-free Write in process_preds
Hello, syzbot found the following crash on: HEAD commit:03f5781be2c7 bpf, x86_32: add eBPF JIT compiler for ia32 git tree: bpf-next console output: https://syzkaller.appspot.com/x/log.txt?x=1362723780 kernel config: https://syzkaller.appspot.com/x/.config?x=3d356c2d908b7293 dashboard link: https://syzkaller.appspot.com/bug?extid=873ae613c636f037d5f8 compiler: gcc (GCC) 8.0.1 20180413 (experimental) Unfortunately, I don't have any reproducer for this crash yet. IMPORTANT: if you fix the bug, please add the following tag to the commit: Reported-by: syzbot+873ae613c636f037d...@syzkaller.appspotmail.com == BUG: KASAN: use-after-free in predicate_parse kernel/trace/trace_events_filter.c:557 [inline] BUG: KASAN: use-after-free in process_preds+0x1958/0x19b0 kernel/trace/trace_events_filter.c:1505 Write of size 4 at addr 8801ada34ff0 by task syz-executor3/6458 CPU: 0 PID: 6458 Comm: syz-executor3 Not tainted 4.17.0-rc2+ #22 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1b9/0x294 lib/dump_stack.c:113 print_address_description+0x6c/0x20b mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 __asan_report_store4_noabort+0x17/0x20 mm/kasan/report.c:437 predicate_parse kernel/trace/trace_events_filter.c:557 [inline] process_preds+0x1958/0x19b0 kernel/trace/trace_events_filter.c:1505 create_filter+0x155/0x270 kernel/trace/trace_events_filter.c:1713 ftrace_profile_set_filter+0x130/0x2e0 kernel/trace/trace_events_filter.c:2038 perf_event_set_filter+0x248/0x1230 kernel/events/core.c:9079 _perf_ioctl+0x84c/0x15e0 kernel/events/core.c:5059 perf_ioctl+0x59/0x80 kernel/events/core.c:5110 vfs_ioctl fs/ioctl.c:46 [inline] file_ioctl fs/ioctl.c:500 [inline] do_vfs_ioctl+0x1cf/0x16a0 fs/ioctl.c:684 ksys_ioctl+0xa9/0xd0 fs/ioctl.c:701 __do_sys_ioctl fs/ioctl.c:708 [inline] __se_sys_ioctl fs/ioctl.c:706 [inline] __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:706 do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x455979 RSP: 002b:7fd67f515c68 EFLAGS: 0246 ORIG_RAX: 0010 RAX: ffda RBX: 7fd67f5166d4 RCX: 00455979 RDX: 2040 RSI: 40082406 RDI: 0013 RBP: 0072bea0 R08: R09: R10: R11: 0246 R12: R13: 02bf R14: 006f8288 R15: The buggy address belongs to the page: page:ea0006b68d00 count:0 mapcount:0 mapping: index:0x0 flags: 0x2fffc00() raw: 02fffc00 raw: 8801daf2fcd8 ea0006a5d9e0 page dumped because: kasan: bad access detected Memory state around the buggy address: 8801ada34e80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 8801ada34f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 8801ada34f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ^ 8801ada35000: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc 8801ada35080: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc == --- This bug is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkal...@googlegroups.com. syzbot will keep track of this bug report. If you forgot to add the Reported-by tag, once the fix for this bug is merged into any tree, please reply to this email with: #syz fix: exact-commit-title To mark this as a duplicate of another syzbot report, please reply with: #syz dup: exact-subject-of-another-report If it's a one-off invalid bug report, please reply with: #syz invalid Note: if the crash happens again, it will cause creation of a new bug report. Note: all commands must start from beginning of the line in the email body.
Re: [PATCH] i2c: core-smbus: fix a potential uninitialization bug
On Fri, May 4, 2018 at 12:04 AM, Peter Rosinwrote: > On 2018-05-04 06:08, Wenwen Wang wrote: >> On Thu, May 3, 2018 at 3:34 PM, Peter Rosin wrote: >>> On 2018-05-03 00:36, Wenwen Wang wrote: In i2c_smbus_xfer_emulated(), there are two buffers: msgbuf0 and msgbuf1, which are used to save a series of messages, as mentioned in the comment. According to the value of the variable "size", msgbuf0 is initialized to various values. In contrast, msgbuf1 is left uninitialized until the function i2c_transfer() is invoked. However, mgsbuf1 is not always initialized on all possible execution paths (implementation) of i2c_transfer(). Thus, it is possible that mgsbuf1 may still not be >>> >>> double negation here >>> uninitialized even after the invocation of the function i2c_transfer(). In the following execution, the uninitialized msgbuf1 will be used, such as for security checks. Since uninitialized values can be random and arbitrary, this will cause undefined behaviors or even check bypass. For example, it is expected that if the value of "size" is I2C_SMBUS_BLOCK_PROC_CALL, the value of data->block[0] should not be larger than I2C_SMBUS_BLOCK_MAX. But, at the end of i2c_smbus_xfer_emulated(), the value read from msgbuf1 is assigned to data->block[0], which can potentially lead to invalid block write size, as demonstrated in the error message. This patch simply initializes the buffer msgbuf1 with 0 to avoid undefined behaviors or security issues. Signed-off-by: Wenwen Wang --- drivers/i2c/i2c-core-smbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index b5aec33..0fcca75 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -324,7 +324,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, * somewhat simpler. */ unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; - unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; + unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2] = {0}; >>> >>> I think this will result in the whole of msgbuf1 being filled with zeroes. >>> It might be cheaper to do this with code proper rather than with an >>> initializer? >> >> Thanks for your comment, Peter! How about using a memset() only when >> i2c_smbus_xfer_emulated() emulates reading commands, since msgbuf1 is >> used only in that case? > > I was thinking that an assignment of > > msgbuf1[0] = 0; > > would be enough in the I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_BLOCK_PROC_CALL > cases before the i2c_transfer call. However, this will only kick in if > the call to kzalloc fails (and it most likely will not) in the call to the > i2c_smbus_try_get_dmabuf helper. So, this thing that you are trying to fix > seems like a non-issue to me. > > However, while looking I think the bigger problem with that function is that > it considers all non-negative return values from i2c_transfer as good. > IMHO, it should barf on any return values <> num. Or at the very least > describe why a partial result is considered OK... > > Cheers, > Peter > >>> >>> Cheers, >>> Peter >>> int num = read_write == I2C_SMBUS_READ ? 2 : 1; int i; u8 partial_pec = 0; >>> > Yes, it is a big issue if the return value from i2c_transfer() is not equal to num. I can add a check like this: if (status != num) return -EINVAL; Also, I wonder why msgbuf1 is necessary if it is replaced by kzalloc in i2c_smbus_try_get_dmabuf()? Thanks, Wenwen
Re: [PATCH] i2c: core-smbus: fix a potential uninitialization bug
On Fri, May 4, 2018 at 12:04 AM, Peter Rosin wrote: > On 2018-05-04 06:08, Wenwen Wang wrote: >> On Thu, May 3, 2018 at 3:34 PM, Peter Rosin wrote: >>> On 2018-05-03 00:36, Wenwen Wang wrote: In i2c_smbus_xfer_emulated(), there are two buffers: msgbuf0 and msgbuf1, which are used to save a series of messages, as mentioned in the comment. According to the value of the variable "size", msgbuf0 is initialized to various values. In contrast, msgbuf1 is left uninitialized until the function i2c_transfer() is invoked. However, mgsbuf1 is not always initialized on all possible execution paths (implementation) of i2c_transfer(). Thus, it is possible that mgsbuf1 may still not be >>> >>> double negation here >>> uninitialized even after the invocation of the function i2c_transfer(). In the following execution, the uninitialized msgbuf1 will be used, such as for security checks. Since uninitialized values can be random and arbitrary, this will cause undefined behaviors or even check bypass. For example, it is expected that if the value of "size" is I2C_SMBUS_BLOCK_PROC_CALL, the value of data->block[0] should not be larger than I2C_SMBUS_BLOCK_MAX. But, at the end of i2c_smbus_xfer_emulated(), the value read from msgbuf1 is assigned to data->block[0], which can potentially lead to invalid block write size, as demonstrated in the error message. This patch simply initializes the buffer msgbuf1 with 0 to avoid undefined behaviors or security issues. Signed-off-by: Wenwen Wang --- drivers/i2c/i2c-core-smbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index b5aec33..0fcca75 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -324,7 +324,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, * somewhat simpler. */ unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; - unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; + unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2] = {0}; >>> >>> I think this will result in the whole of msgbuf1 being filled with zeroes. >>> It might be cheaper to do this with code proper rather than with an >>> initializer? >> >> Thanks for your comment, Peter! How about using a memset() only when >> i2c_smbus_xfer_emulated() emulates reading commands, since msgbuf1 is >> used only in that case? > > I was thinking that an assignment of > > msgbuf1[0] = 0; > > would be enough in the I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_BLOCK_PROC_CALL > cases before the i2c_transfer call. However, this will only kick in if > the call to kzalloc fails (and it most likely will not) in the call to the > i2c_smbus_try_get_dmabuf helper. So, this thing that you are trying to fix > seems like a non-issue to me. > > However, while looking I think the bigger problem with that function is that > it considers all non-negative return values from i2c_transfer as good. > IMHO, it should barf on any return values <> num. Or at the very least > describe why a partial result is considered OK... > > Cheers, > Peter > >>> >>> Cheers, >>> Peter >>> int num = read_write == I2C_SMBUS_READ ? 2 : 1; int i; u8 partial_pec = 0; >>> > Yes, it is a big issue if the return value from i2c_transfer() is not equal to num. I can add a check like this: if (status != num) return -EINVAL; Also, I wonder why msgbuf1 is necessary if it is replaced by kzalloc in i2c_smbus_try_get_dmabuf()? Thanks, Wenwen
Re: [PATCH v2] staging: lustre: llite: fix potential missing-check bug when copying lumv
There is no security problem here. The user is allowed to choose either v1 or v3. Using a double read race condition to choose v1 is not going to cause problems. It's slightly more complicated than just choosing it directly but that doesn't make it a security issue. It's a bit like typing with your feet in that just because using your toes instead of your fingergs is more complicated, it doesn't make it a security issue. regards, dan carpenter
Re: [PATCH v2] staging: lustre: llite: fix potential missing-check bug when copying lumv
There is no security problem here. The user is allowed to choose either v1 or v3. Using a double read race condition to choose v1 is not going to cause problems. It's slightly more complicated than just choosing it directly but that doesn't make it a security issue. It's a bit like typing with your feet in that just because using your toes instead of your fingergs is more complicated, it doesn't make it a security issue. regards, dan carpenter
[PATCH 0/4] iommu/vt-d: Several cleanup patches
Hi, This includes several cleanup patches which aim to make the code more concise and easier for reading. There aren't any functionality changes. Best regards, Lu Baolu Lu Baolu (4): iommu: Clean up the comments for iommu_group_alloc iommu/vt-d: Clean up unused variable in find_or_alloc_domain iommu/vt-d: Clean up pasid quirk for pre-production devices iommu/vt-d: Remove unnecessary parentheses drivers/iommu/intel-iommu.c | 36 +++- drivers/iommu/intel-svm.c | 2 +- drivers/iommu/iommu.c | 1 - include/linux/intel-iommu.h | 1 - 4 files changed, 4 insertions(+), 36 deletions(-) -- 2.7.4
[PATCH 0/4] iommu/vt-d: Several cleanup patches
Hi, This includes several cleanup patches which aim to make the code more concise and easier for reading. There aren't any functionality changes. Best regards, Lu Baolu Lu Baolu (4): iommu: Clean up the comments for iommu_group_alloc iommu/vt-d: Clean up unused variable in find_or_alloc_domain iommu/vt-d: Clean up pasid quirk for pre-production devices iommu/vt-d: Remove unnecessary parentheses drivers/iommu/intel-iommu.c | 36 +++- drivers/iommu/intel-svm.c | 2 +- drivers/iommu/iommu.c | 1 - include/linux/intel-iommu.h | 1 - 4 files changed, 4 insertions(+), 36 deletions(-) -- 2.7.4
[PATCH 2/4] iommu/vt-d: Clean up unused variable in find_or_alloc_domain
Remove it to make the code more concise. Signed-off-by: Lu Baolu--- drivers/iommu/intel-iommu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 749d8f2..9064607 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2533,7 +2533,7 @@ static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw) struct device_domain_info *info = NULL; struct dmar_domain *domain = NULL; struct intel_iommu *iommu; - u16 req_id, dma_alias; + u16 dma_alias; unsigned long flags; u8 bus, devfn; @@ -2541,8 +2541,6 @@ static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw) if (!iommu) return NULL; - req_id = ((u16)bus << 8) | devfn; - if (dev_is_pci(dev)) { struct pci_dev *pdev = to_pci_dev(dev); -- 2.7.4
[PATCH 2/4] iommu/vt-d: Clean up unused variable in find_or_alloc_domain
Remove it to make the code more concise. Signed-off-by: Lu Baolu --- drivers/iommu/intel-iommu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 749d8f2..9064607 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2533,7 +2533,7 @@ static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw) struct device_domain_info *info = NULL; struct dmar_domain *domain = NULL; struct intel_iommu *iommu; - u16 req_id, dma_alias; + u16 dma_alias; unsigned long flags; u8 bus, devfn; @@ -2541,8 +2541,6 @@ static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw) if (!iommu) return NULL; - req_id = ((u16)bus << 8) | devfn; - if (dev_is_pci(dev)) { struct pci_dev *pdev = to_pci_dev(dev); -- 2.7.4
[PATCH 4/4] iommu/vt-d: Remove unnecessary parentheses
Remove unnecessary parentheses to comply with preferred coding style. Signed-off-by: Lu Baolu--- drivers/iommu/intel-svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index e8cd984..45f6e58 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -319,7 +319,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ } else pasid_max = 1 << 20; - if ((flags & SVM_FLAG_SUPERVISOR_MODE)) { + if (flags & SVM_FLAG_SUPERVISOR_MODE) { if (!ecap_srs(iommu->ecap)) return -EINVAL; } else if (pasid) { -- 2.7.4
[PATCH 4/4] iommu/vt-d: Remove unnecessary parentheses
Remove unnecessary parentheses to comply with preferred coding style. Signed-off-by: Lu Baolu --- drivers/iommu/intel-svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index e8cd984..45f6e58 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -319,7 +319,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ } else pasid_max = 1 << 20; - if ((flags & SVM_FLAG_SUPERVISOR_MODE)) { + if (flags & SVM_FLAG_SUPERVISOR_MODE) { if (!ecap_srs(iommu->ecap)) return -EINVAL; } else if (pasid) { -- 2.7.4
[PATCH 3/4] iommu/vt-d: Clean up pasid quirk for pre-production devices
The pasid28 quirk is needed only for some pre-production devices. Remove it to make the code concise. Signed-off-by: Ashok RajSigned-off-by: Lu Baolu --- drivers/iommu/intel-iommu.c | 32 ++-- include/linux/intel-iommu.h | 1 - 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 9064607..10bce33 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -485,37 +485,14 @@ static int dmar_forcedac; static int intel_iommu_strict; static int intel_iommu_superpage = 1; static int intel_iommu_ecs = 1; -static int intel_iommu_pasid28; static int iommu_identity_mapping; #define IDENTMAP_ALL 1 #define IDENTMAP_GFX 2 #define IDENTMAP_AZALIA4 -/* Broadwell and Skylake have broken ECS support — normal so-called "second - * level" translation of DMA requests-without-PASID doesn't actually happen - * unless you also set the NESTE bit in an extended context-entry. Which of - * course means that SVM doesn't work because it's trying to do nested - * translation of the physical addresses it finds in the process page tables, - * through the IOVA->phys mapping found in the "second level" page tables. - * - * The VT-d specification was retroactively changed to change the definition - * of the capability bits and pretend that Broadwell/Skylake never happened... - * but unfortunately the wrong bit was changed. It's ECS which is broken, but - * for some reason it was the PASID capability bit which was redefined (from - * bit 28 on BDW/SKL to bit 40 in future). - * - * So our test for ECS needs to eschew those implementations which set the old - * PASID capabiity bit 28, since those are the ones on which ECS is broken. - * Unless we are working around the 'pasid28' limitations, that is, by putting - * the device into passthrough mode for normal DMA and thus masking the bug. - */ -#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \ - (intel_iommu_pasid28 || !ecap_broken_pasid(iommu->ecap))) -/* PASID support is thus enabled if ECS is enabled and *either* of the old - * or new capability bits are set. */ -#define pasid_enabled(iommu) (ecs_enabled(iommu) &&\ - (ecap_pasid(iommu->ecap) || ecap_broken_pasid(iommu->ecap))) +#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap)) +#define pasid_enabled(iommu) (ecs_enabled(iommu) && ecap_pasid(iommu->ecap)) int intel_iommu_gfx_mapped; EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); @@ -578,11 +555,6 @@ static int __init intel_iommu_setup(char *str) printk(KERN_INFO "Intel-IOMMU: disable extended context table support\n"); intel_iommu_ecs = 0; - } else if (!strncmp(str, "pasid28", 7)) { - printk(KERN_INFO - "Intel-IOMMU: enable pre-production PASID support\n"); - intel_iommu_pasid28 = 1; - iommu_identity_mapping |= IDENTMAP_GFX; } else if (!strncmp(str, "tboot_noforce", 13)) { printk(KERN_INFO "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n"); diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index ef169d6..1df9401 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -121,7 +121,6 @@ #define ecap_srs(e)((e >> 31) & 0x1) #define ecap_ers(e)((e >> 30) & 0x1) #define ecap_prs(e)((e >> 29) & 0x1) -#define ecap_broken_pasid(e) ((e >> 28) & 0x1) #define ecap_dis(e)((e >> 27) & 0x1) #define ecap_nest(e) ((e >> 26) & 0x1) #define ecap_mts(e)((e >> 25) & 0x1) -- 2.7.4
[PATCH 3/4] iommu/vt-d: Clean up pasid quirk for pre-production devices
The pasid28 quirk is needed only for some pre-production devices. Remove it to make the code concise. Signed-off-by: Ashok Raj Signed-off-by: Lu Baolu --- drivers/iommu/intel-iommu.c | 32 ++-- include/linux/intel-iommu.h | 1 - 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 9064607..10bce33 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -485,37 +485,14 @@ static int dmar_forcedac; static int intel_iommu_strict; static int intel_iommu_superpage = 1; static int intel_iommu_ecs = 1; -static int intel_iommu_pasid28; static int iommu_identity_mapping; #define IDENTMAP_ALL 1 #define IDENTMAP_GFX 2 #define IDENTMAP_AZALIA4 -/* Broadwell and Skylake have broken ECS support — normal so-called "second - * level" translation of DMA requests-without-PASID doesn't actually happen - * unless you also set the NESTE bit in an extended context-entry. Which of - * course means that SVM doesn't work because it's trying to do nested - * translation of the physical addresses it finds in the process page tables, - * through the IOVA->phys mapping found in the "second level" page tables. - * - * The VT-d specification was retroactively changed to change the definition - * of the capability bits and pretend that Broadwell/Skylake never happened... - * but unfortunately the wrong bit was changed. It's ECS which is broken, but - * for some reason it was the PASID capability bit which was redefined (from - * bit 28 on BDW/SKL to bit 40 in future). - * - * So our test for ECS needs to eschew those implementations which set the old - * PASID capabiity bit 28, since those are the ones on which ECS is broken. - * Unless we are working around the 'pasid28' limitations, that is, by putting - * the device into passthrough mode for normal DMA and thus masking the bug. - */ -#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \ - (intel_iommu_pasid28 || !ecap_broken_pasid(iommu->ecap))) -/* PASID support is thus enabled if ECS is enabled and *either* of the old - * or new capability bits are set. */ -#define pasid_enabled(iommu) (ecs_enabled(iommu) &&\ - (ecap_pasid(iommu->ecap) || ecap_broken_pasid(iommu->ecap))) +#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap)) +#define pasid_enabled(iommu) (ecs_enabled(iommu) && ecap_pasid(iommu->ecap)) int intel_iommu_gfx_mapped; EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); @@ -578,11 +555,6 @@ static int __init intel_iommu_setup(char *str) printk(KERN_INFO "Intel-IOMMU: disable extended context table support\n"); intel_iommu_ecs = 0; - } else if (!strncmp(str, "pasid28", 7)) { - printk(KERN_INFO - "Intel-IOMMU: enable pre-production PASID support\n"); - intel_iommu_pasid28 = 1; - iommu_identity_mapping |= IDENTMAP_GFX; } else if (!strncmp(str, "tboot_noforce", 13)) { printk(KERN_INFO "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n"); diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index ef169d6..1df9401 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -121,7 +121,6 @@ #define ecap_srs(e)((e >> 31) & 0x1) #define ecap_ers(e)((e >> 30) & 0x1) #define ecap_prs(e)((e >> 29) & 0x1) -#define ecap_broken_pasid(e) ((e >> 28) & 0x1) #define ecap_dis(e)((e >> 27) & 0x1) #define ecap_nest(e) ((e >> 26) & 0x1) #define ecap_mts(e)((e >> 25) & 0x1) -- 2.7.4
[PATCH 1/4] iommu: Clean up the comments for iommu_group_alloc
@name parameter has been removed. Signed-off-by: Lu Baolu--- drivers/iommu/iommu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d2aa2320..d87e7c2 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -322,7 +322,6 @@ static struct kobj_type iommu_group_ktype = { /** * iommu_group_alloc - Allocate a new group - * @name: Optional name to associate with group, visible in sysfs * * This function is called by an iommu driver to allocate a new iommu * group. The iommu group represents the minimum granularity of the iommu. -- 2.7.4
[PATCH 1/4] iommu: Clean up the comments for iommu_group_alloc
@name parameter has been removed. Signed-off-by: Lu Baolu --- drivers/iommu/iommu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d2aa2320..d87e7c2 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -322,7 +322,6 @@ static struct kobj_type iommu_group_ktype = { /** * iommu_group_alloc - Allocate a new group - * @name: Optional name to associate with group, visible in sysfs * * This function is called by an iommu driver to allocate a new iommu * group. The iommu group represents the minimum granularity of the iommu. -- 2.7.4
Re: [PATCH 4/7] dt-bindings: gnss: add u-blox binding
Hi Andreas, > Am 03.05.2018 um 20:50 schrieb Andreas Kemnade: > > On Thu, 3 May 2018 11:35:21 +0200 > H. Nikolaus Schaller wrote: > > >> I have realized that the w2sg0004 is an exception (although a Sirf chip) >> that it does not provide a WAKEUP signal. And another significant >> difference is that we have to keep the serdev UART enabled even if there >> is no user-space client. Otherwise we are not able to detect unexpected >> activity. So we unfortunately can't move serdev open/close into the .open >> and .close ops but need to open it in probe. >> > how much power does it use to keep the uart enabled? Or should it > better be reprogrammed as gpio? I think it does not need much more (if at all) than a gpio controller on the OMAP3 chip (I think the clocks are active anyways for use by the other UARTs). We had proposed years ago to reprogram the UART RX pin by pinmux-states into an interrupt gpio but that was rejected because it was not general enough and ugly in the device tree (an rx-gpios record where the rx-line is already connected to the UART-rx). Then we did experiment with tapping the UART driver and finally the serdev API was developed to solve this problem. Hence we use it now this way. BR and thanks, Nikolaus signature.asc Description: Message signed with OpenPGP using GPGMail
Re: [PATCH 4/7] dt-bindings: gnss: add u-blox binding
Hi Andreas, > Am 03.05.2018 um 20:50 schrieb Andreas Kemnade : > > On Thu, 3 May 2018 11:35:21 +0200 > H. Nikolaus Schaller wrote: > > >> I have realized that the w2sg0004 is an exception (although a Sirf chip) >> that it does not provide a WAKEUP signal. And another significant >> difference is that we have to keep the serdev UART enabled even if there >> is no user-space client. Otherwise we are not able to detect unexpected >> activity. So we unfortunately can't move serdev open/close into the .open >> and .close ops but need to open it in probe. >> > how much power does it use to keep the uart enabled? Or should it > better be reprogrammed as gpio? I think it does not need much more (if at all) than a gpio controller on the OMAP3 chip (I think the clocks are active anyways for use by the other UARTs). We had proposed years ago to reprogram the UART RX pin by pinmux-states into an interrupt gpio but that was rejected because it was not general enough and ugly in the device tree (an rx-gpios record where the rx-line is already connected to the UART-rx). Then we did experiment with tapping the UART driver and finally the serdev API was developed to solve this problem. Hence we use it now this way. BR and thanks, Nikolaus signature.asc Description: Message signed with OpenPGP using GPGMail
Re: [PATCH 04/15] powerpc/powernv: opal-kmsg use flush fallback from console code
Nicholas Pigginwrites: > Use the more refined and tested event polling loop from opal_put_chars > as the fallback console flush in the opal-kmsg path. This loop is used > by the console driver today, whereas the opal-kmsg fallback is not > likely to have been used for years. > > Use WARN_ONCE rather than a printk when the fallback is invoked to > prepare for moving the console flush into a common function. Do we want to add a WARN in that path? If we're panicking things might get worse if we WARN (which takes a trap). cheers
Re: [PATCH 04/15] powerpc/powernv: opal-kmsg use flush fallback from console code
Nicholas Piggin writes: > Use the more refined and tested event polling loop from opal_put_chars > as the fallback console flush in the opal-kmsg path. This loop is used > by the console driver today, whereas the opal-kmsg fallback is not > likely to have been used for years. > > Use WARN_ONCE rather than a printk when the fallback is invoked to > prepare for moving the console flush into a common function. Do we want to add a WARN in that path? If we're panicking things might get worse if we WARN (which takes a trap). cheers
general protection fault in perf_tp_event
Hello, syzbot found the following crash on: HEAD commit:c15f6d8d4715 Merge tag 'dma-mapping-4.17-4' of git://git.i.. git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=128d955b80 kernel config: https://syzkaller.appspot.com/x/.config?x=5a1dc06635c10d27 dashboard link: https://syzkaller.appspot.com/bug?extid=2f86b8550eb66cbd5808 compiler: gcc (GCC) 8.0.1 20180413 (experimental) Unfortunately, I don't have any reproducer for this crash yet. IMPORTANT: if you fix the bug, please add the following tag to the commit: Reported-by: syzbot+2f86b8550eb66cbd5...@syzkaller.appspotmail.com R13: 04a7 R14: 006fb048 R15: 0002 kasan: CONFIG_KASAN_INLINE enabled kasan: CONFIG_KASAN_INLINE enabled kasan: GPF could be caused by NULL-ptr deref or user memory access kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: [#1] SMP KASAN Dumping ftrace buffer: (ftrace buffer empty) Modules linked in: CPU: 0 PID: 13905 Comm: udevd Not tainted 4.17.0-rc3+ #31 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:perf_tp_event_match kernel/events/core.c:8235 [inline] RIP: 0010:perf_tp_event+0x427/0xc30 kernel/events/core.c:8286 RSP: 0018:8801acea7380 EFLAGS: 00010002 RAX: 06ca2060204a RBX: 365103010080 RCX: 81921715 RDX: RSI: 819217a9 RDI: 365103010250 RBP: 8801acea77b0 R08: 8801d7e4c200 R09: 8801dae0 R10: 8801acea77e0 R11: R12: ed00359d4e90 R13: dc00 R14: 8801acea75c0 R15: dc00 FS: 7fb9286417a0() GS:8801dae0() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 7fb928648000 CR3: 0001aec72000 CR4: 001406f0 DR0: 2000 DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0600 Call Trace: perf_trace_run_bpf_submit+0x23f/0x370 kernel/events/core.c:8261 perf_trace_sched_wakeup_template+0x4fc/0x910 include/trace/events/sched.h:57 trace_sched_wakeup_new include/trace/events/sched.h:103 [inline] wake_up_new_task+0x7ad/0xc10 kernel/sched/core.c:2447 _do_fork+0x379/0x12a0 kernel/fork.c:2113 __do_sys_clone kernel/fork.c:2195 [inline] __se_sys_clone kernel/fork.c:2189 [inline] __x64_sys_clone+0xbf/0x150 kernel/fork.c:2189 do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x7fb927d24f46 RSP: 002b:7ffe709c6b80 EFLAGS: 0246 ORIG_RAX: 0038 RAX: ffda RBX: 7ffe709c6b80 RCX: 7fb927d24f46 RDX: RSI: RDI: 01200011 RBP: 7ffe709c6be0 R08: 3651 R09: 3651 R10: 7fb928641a70 R11: 0246 R12: R13: 7ffe709c6ba0 R14: 0005 R15: 0005 Code: 48 85 db 0f 84 da 00 00 00 e8 a6 27 e7 ff 48 83 eb 60 0f 84 cb 00 00 00 e8 97 27 e7 ff 48 8d bb d0 01 00 00 48 89 f8 48 c1 e8 03 <42> 0f b6 04 28 84 c0 74 08 3c 03 0f 8e dc 06 00 00 44 8b bb d0 RIP: perf_tp_event_match kernel/events/core.c:8235 [inline] RSP: 8801acea7380 RIP: perf_tp_event+0x427/0xc30 kernel/events/core.c:8286 RSP: 8801acea7380 == WARNING: possible circular locking dependency detected 4.17.0-rc3+ #31 Not tainted -- udevd/13905 is trying to acquire lock: 3dcbb218 ((console_sem).lock){-.-.}, at: down_trylock+0x13/0x70 kernel/locking/semaphore.c:136 but task is already holding lock: 8f208626 (>lock){-.-.}, at: __task_rq_lock+0xe0/0x300 kernel/sched/core.c:77 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (>lock){-.-.}: __raw_spin_lock include/linux/spinlock_api_smp.h:142 [inline] _raw_spin_lock+0x2a/0x40 kernel/locking/spinlock.c:144 rq_lock kernel/sched/sched.h:1799 [inline] task_fork_fair+0x8a/0x660 kernel/sched/fair.c:9967 sched_fork+0x43e/0xb30 kernel/sched/core.c:2379 copy_process.part.38+0x1c18/0x6e90 kernel/fork.c:1764 copy_process kernel/fork.c:1607 [inline] _do_fork+0x291/0x12a0 kernel/fork.c:2088 kernel_thread+0x34/0x40 kernel/fork.c:2147 rest_init+0x22/0xe4 init/main.c:407 start_kernel+0x906/0x92d init/main.c:737 x86_64_start_reservations+0x29/0x2b arch/x86/kernel/head64.c:445 x86_64_start_kernel+0x76/0x79 arch/x86/kernel/head64.c:426 secondary_startup_64+0xa5/0xb0 arch/x86/kernel/head_64.S:242 -> #1 (>pi_lock){-.-.}: __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x96/0xc0 kernel/locking/spinlock.c:152 try_to_wake_up+0xca/0x1190 kernel/sched/core.c:1963 wake_up_process+0x10/0x20
general protection fault in perf_tp_event
Hello, syzbot found the following crash on: HEAD commit:c15f6d8d4715 Merge tag 'dma-mapping-4.17-4' of git://git.i.. git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=128d955b80 kernel config: https://syzkaller.appspot.com/x/.config?x=5a1dc06635c10d27 dashboard link: https://syzkaller.appspot.com/bug?extid=2f86b8550eb66cbd5808 compiler: gcc (GCC) 8.0.1 20180413 (experimental) Unfortunately, I don't have any reproducer for this crash yet. IMPORTANT: if you fix the bug, please add the following tag to the commit: Reported-by: syzbot+2f86b8550eb66cbd5...@syzkaller.appspotmail.com R13: 04a7 R14: 006fb048 R15: 0002 kasan: CONFIG_KASAN_INLINE enabled kasan: CONFIG_KASAN_INLINE enabled kasan: GPF could be caused by NULL-ptr deref or user memory access kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: [#1] SMP KASAN Dumping ftrace buffer: (ftrace buffer empty) Modules linked in: CPU: 0 PID: 13905 Comm: udevd Not tainted 4.17.0-rc3+ #31 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:perf_tp_event_match kernel/events/core.c:8235 [inline] RIP: 0010:perf_tp_event+0x427/0xc30 kernel/events/core.c:8286 RSP: 0018:8801acea7380 EFLAGS: 00010002 RAX: 06ca2060204a RBX: 365103010080 RCX: 81921715 RDX: RSI: 819217a9 RDI: 365103010250 RBP: 8801acea77b0 R08: 8801d7e4c200 R09: 8801dae0 R10: 8801acea77e0 R11: R12: ed00359d4e90 R13: dc00 R14: 8801acea75c0 R15: dc00 FS: 7fb9286417a0() GS:8801dae0() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 7fb928648000 CR3: 0001aec72000 CR4: 001406f0 DR0: 2000 DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0600 Call Trace: perf_trace_run_bpf_submit+0x23f/0x370 kernel/events/core.c:8261 perf_trace_sched_wakeup_template+0x4fc/0x910 include/trace/events/sched.h:57 trace_sched_wakeup_new include/trace/events/sched.h:103 [inline] wake_up_new_task+0x7ad/0xc10 kernel/sched/core.c:2447 _do_fork+0x379/0x12a0 kernel/fork.c:2113 __do_sys_clone kernel/fork.c:2195 [inline] __se_sys_clone kernel/fork.c:2189 [inline] __x64_sys_clone+0xbf/0x150 kernel/fork.c:2189 do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x7fb927d24f46 RSP: 002b:7ffe709c6b80 EFLAGS: 0246 ORIG_RAX: 0038 RAX: ffda RBX: 7ffe709c6b80 RCX: 7fb927d24f46 RDX: RSI: RDI: 01200011 RBP: 7ffe709c6be0 R08: 3651 R09: 3651 R10: 7fb928641a70 R11: 0246 R12: R13: 7ffe709c6ba0 R14: 0005 R15: 0005 Code: 48 85 db 0f 84 da 00 00 00 e8 a6 27 e7 ff 48 83 eb 60 0f 84 cb 00 00 00 e8 97 27 e7 ff 48 8d bb d0 01 00 00 48 89 f8 48 c1 e8 03 <42> 0f b6 04 28 84 c0 74 08 3c 03 0f 8e dc 06 00 00 44 8b bb d0 RIP: perf_tp_event_match kernel/events/core.c:8235 [inline] RSP: 8801acea7380 RIP: perf_tp_event+0x427/0xc30 kernel/events/core.c:8286 RSP: 8801acea7380 == WARNING: possible circular locking dependency detected 4.17.0-rc3+ #31 Not tainted -- udevd/13905 is trying to acquire lock: 3dcbb218 ((console_sem).lock){-.-.}, at: down_trylock+0x13/0x70 kernel/locking/semaphore.c:136 but task is already holding lock: 8f208626 (>lock){-.-.}, at: __task_rq_lock+0xe0/0x300 kernel/sched/core.c:77 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (>lock){-.-.}: __raw_spin_lock include/linux/spinlock_api_smp.h:142 [inline] _raw_spin_lock+0x2a/0x40 kernel/locking/spinlock.c:144 rq_lock kernel/sched/sched.h:1799 [inline] task_fork_fair+0x8a/0x660 kernel/sched/fair.c:9967 sched_fork+0x43e/0xb30 kernel/sched/core.c:2379 copy_process.part.38+0x1c18/0x6e90 kernel/fork.c:1764 copy_process kernel/fork.c:1607 [inline] _do_fork+0x291/0x12a0 kernel/fork.c:2088 kernel_thread+0x34/0x40 kernel/fork.c:2147 rest_init+0x22/0xe4 init/main.c:407 start_kernel+0x906/0x92d init/main.c:737 x86_64_start_reservations+0x29/0x2b arch/x86/kernel/head64.c:445 x86_64_start_kernel+0x76/0x79 arch/x86/kernel/head64.c:426 secondary_startup_64+0xa5/0xb0 arch/x86/kernel/head_64.S:242 -> #1 (>pi_lock){-.-.}: __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x96/0xc0 kernel/locking/spinlock.c:152 try_to_wake_up+0xca/0x1190 kernel/sched/core.c:1963 wake_up_process+0x10/0x20
Re: [PATCH] i2c: core-smbus: fix a potential uninitialization bug
On 2018-05-04 06:08, Wenwen Wang wrote: > On Thu, May 3, 2018 at 3:34 PM, Peter Rosinwrote: >> On 2018-05-03 00:36, Wenwen Wang wrote: >>> In i2c_smbus_xfer_emulated(), there are two buffers: msgbuf0 and msgbuf1, >>> which are used to save a series of messages, as mentioned in the comment. >>> According to the value of the variable "size", msgbuf0 is initialized to >>> various values. In contrast, msgbuf1 is left uninitialized until the >>> function i2c_transfer() is invoked. However, mgsbuf1 is not always >>> initialized on all possible execution paths (implementation) of >>> i2c_transfer(). Thus, it is possible that mgsbuf1 may still not be >> >> double negation here >> >>> uninitialized even after the invocation of the function i2c_transfer(). In >>> the following execution, the uninitialized msgbuf1 will be used, such as >>> for security checks. Since uninitialized values can be random and >>> arbitrary, this will cause undefined behaviors or even check bypass. For >>> example, it is expected that if the value of "size" is >>> I2C_SMBUS_BLOCK_PROC_CALL, the value of data->block[0] should not be larger >>> than I2C_SMBUS_BLOCK_MAX. But, at the end of i2c_smbus_xfer_emulated(), the >>> value read from msgbuf1 is assigned to data->block[0], which can >>> potentially lead to invalid block write size, as demonstrated in the error >>> message. >>> >>> This patch simply initializes the buffer msgbuf1 with 0 to avoid undefined >>> behaviors or security issues. >>> >>> Signed-off-by: Wenwen Wang >>> --- >>> drivers/i2c/i2c-core-smbus.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c >>> index b5aec33..0fcca75 100644 >>> --- a/drivers/i2c/i2c-core-smbus.c >>> +++ b/drivers/i2c/i2c-core-smbus.c >>> @@ -324,7 +324,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter >>> *adapter, u16 addr, >>>* somewhat simpler. >>>*/ >>> unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; >>> - unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; >>> + unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2] = {0}; >> >> I think this will result in the whole of msgbuf1 being filled with zeroes. >> It might be cheaper to do this with code proper rather than with an >> initializer? > > Thanks for your comment, Peter! How about using a memset() only when > i2c_smbus_xfer_emulated() emulates reading commands, since msgbuf1 is > used only in that case? I was thinking that an assignment of msgbuf1[0] = 0; would be enough in the I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_BLOCK_PROC_CALL cases before the i2c_transfer call. However, this will only kick in if the call to kzalloc fails (and it most likely will not) in the call to the i2c_smbus_try_get_dmabuf helper. So, this thing that you are trying to fix seems like a non-issue to me. However, while looking I think the bigger problem with that function is that it considers all non-negative return values from i2c_transfer as good. IMHO, it should barf on any return values <> num. Or at the very least describe why a partial result is considered OK... Cheers, Peter >> >> Cheers, >> Peter >> >>> int num = read_write == I2C_SMBUS_READ ? 2 : 1; >>> int i; >>> u8 partial_pec = 0; >>> >>
Re: [PATCH] i2c: core-smbus: fix a potential uninitialization bug
On 2018-05-04 06:08, Wenwen Wang wrote: > On Thu, May 3, 2018 at 3:34 PM, Peter Rosin wrote: >> On 2018-05-03 00:36, Wenwen Wang wrote: >>> In i2c_smbus_xfer_emulated(), there are two buffers: msgbuf0 and msgbuf1, >>> which are used to save a series of messages, as mentioned in the comment. >>> According to the value of the variable "size", msgbuf0 is initialized to >>> various values. In contrast, msgbuf1 is left uninitialized until the >>> function i2c_transfer() is invoked. However, mgsbuf1 is not always >>> initialized on all possible execution paths (implementation) of >>> i2c_transfer(). Thus, it is possible that mgsbuf1 may still not be >> >> double negation here >> >>> uninitialized even after the invocation of the function i2c_transfer(). In >>> the following execution, the uninitialized msgbuf1 will be used, such as >>> for security checks. Since uninitialized values can be random and >>> arbitrary, this will cause undefined behaviors or even check bypass. For >>> example, it is expected that if the value of "size" is >>> I2C_SMBUS_BLOCK_PROC_CALL, the value of data->block[0] should not be larger >>> than I2C_SMBUS_BLOCK_MAX. But, at the end of i2c_smbus_xfer_emulated(), the >>> value read from msgbuf1 is assigned to data->block[0], which can >>> potentially lead to invalid block write size, as demonstrated in the error >>> message. >>> >>> This patch simply initializes the buffer msgbuf1 with 0 to avoid undefined >>> behaviors or security issues. >>> >>> Signed-off-by: Wenwen Wang >>> --- >>> drivers/i2c/i2c-core-smbus.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c >>> index b5aec33..0fcca75 100644 >>> --- a/drivers/i2c/i2c-core-smbus.c >>> +++ b/drivers/i2c/i2c-core-smbus.c >>> @@ -324,7 +324,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter >>> *adapter, u16 addr, >>>* somewhat simpler. >>>*/ >>> unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; >>> - unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; >>> + unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2] = {0}; >> >> I think this will result in the whole of msgbuf1 being filled with zeroes. >> It might be cheaper to do this with code proper rather than with an >> initializer? > > Thanks for your comment, Peter! How about using a memset() only when > i2c_smbus_xfer_emulated() emulates reading commands, since msgbuf1 is > used only in that case? I was thinking that an assignment of msgbuf1[0] = 0; would be enough in the I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_BLOCK_PROC_CALL cases before the i2c_transfer call. However, this will only kick in if the call to kzalloc fails (and it most likely will not) in the call to the i2c_smbus_try_get_dmabuf helper. So, this thing that you are trying to fix seems like a non-issue to me. However, while looking I think the bigger problem with that function is that it considers all non-negative return values from i2c_transfer as good. IMHO, it should barf on any return values <> num. Or at the very least describe why a partial result is considered OK... Cheers, Peter >> >> Cheers, >> Peter >> >>> int num = read_write == I2C_SMBUS_READ ? 2 : 1; >>> int i; >>> u8 partial_pec = 0; >>> >>
[PATCH 7/8] staging: mt7621-pci: remove some dead code.
Some code is dead because it is commented out. Some is dead because it is uninteresting printks. Some is dead because it declares unused functions. Remove it all. Signed-off-by: NeilBrown--- drivers/staging/mt7621-pci/pci-mt7621.c | 14 -- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index 5094e90eaf69..edd95013faf3 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -56,9 +56,6 @@ #include -extern void pcie_phy_init(void); -extern void chk_phy_pll(void); - /* * These functions and structures provide the BIOS scan and mapping of the PCI * devices. @@ -364,11 +361,8 @@ pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) void set_pcie_phy(u32 *addr, int start_b, int bits, int val) { -// printk("0x%p:", addr); -// printk(" %x", *addr); *(unsigned int *)(addr) &= ~(((1< %x\n", *addr); } void @@ -497,7 +491,6 @@ static int mt7621_pci_probe(struct platform_device *pdev) val |= RALINK_PCIE2_RST; ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST); - printk("pull PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); *(unsigned int *)(0xbe60) &= ~(0x3<<10 | 0x3<<3); *(unsigned int *)(0xbe60) |= 0x1<<10 | 0x1<<3; @@ -513,12 +506,10 @@ static int mt7621_pci_probe(struct platform_device *pdev) val |= RALINK_PCIE2_RST; DEASSERT_SYSRST_PCIE(val); - printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); if ((*(unsigned int *)(0xbe0c)&0x) == 0x0101) // MT7621 E2 bypass_pipe_rst(); set_phy_for_ssc(); - printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); read_config(0, 0, 0, 0x70c, ); printk("Port 0 N_FTS = %x\n", (unsigned int)val); @@ -614,8 +605,6 @@ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num RALINK_PCI_PCICFG_ADDR |= 0x1 << 24;//port2 break; } - printk(" -> %x\n", RALINK_PCI_PCICFG_ADDR); - //printk(" RALINK_PCI_ARBCTL = %x\n", RALINK_PCI_ARBCTL); /* ioport_resource.start = mt7621_res_pci_io1.start; @@ -653,7 +642,6 @@ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num case 7: read_config(0, 2, 0, 0x4, ); write_config(0, 2, 0, 0x4, val|0x4); - // write_config(0, 1, 0, 0x4, val|0x7); read_config(0, 2, 0, 0x70c, ); val &= ~(0xff)<<8; val |= 0x50<<8; @@ -663,7 +651,6 @@ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num case 6: read_config(0, 1, 0, 0x4, ); write_config(0, 1, 0, 0x4, val|0x4); - // write_config(0, 1, 0, 0x4, val|0x7); read_config(0, 1, 0, 0x70c, ); val &= ~(0xff)<<8; val |= 0x50<<8; @@ -671,7 +658,6 @@ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num default: read_config(0, 0, 0, 0x4, ); write_config(0, 0, 0, 0x4, val|0x4); //bus master enable - // write_config(0, 0, 0, 0x4, val|0x7); //bus master enable read_config(0, 0, 0, 0x70c, ); val &= ~(0xff)<<8; val |= 0x50<<8;
[PATCH 6/8] staging: mt7621-pci: remove unnecessary resource details.
These resources are extracted from devicetree, so they aren't needed here. Signed-off-by: NeilBrown--- drivers/staging/mt7621-pci/pci-mt7621.c | 19 ++- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index 616960e01052..5094e90eaf69 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -302,27 +302,12 @@ struct pci_ops mt7621_pci_ops= { .write = pci_config_write, }; -static struct resource mt7621_res_pci_mem1 = { - .name = "PCI MEM1", - .start = RALINK_PCI_MM_MAP_BASE, - .end= (u32)((RALINK_PCI_MM_MAP_BASE + (unsigned char *)0x0fff)), - .flags = IORESOURCE_MEM, -}; - -static struct resource mt7621_res_pci_io1 = { - .name = "PCI I/O1", - .start = RALINK_PCI_IO_MAP_BASE, - .end= (u32)((RALINK_PCI_IO_MAP_BASE + (unsigned char *)0x0)), - .flags = IORESOURCE_IO, -}; - +static struct resource mt7621_res_pci_mem1; +static struct resource mt7621_res_pci_io1; static struct pci_controller mt7621_controller = { .pci_ops= _pci_ops, .mem_resource = _res_pci_mem1, .io_resource= _res_pci_io1, - .mem_offset = 0xUL, - .io_offset = 0xUL, - .io_map_base= 0xa000, }; static void
[PATCH 6/8] staging: mt7621-pci: remove unnecessary resource details.
These resources are extracted from devicetree, so they aren't needed here. Signed-off-by: NeilBrown --- drivers/staging/mt7621-pci/pci-mt7621.c | 19 ++- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index 616960e01052..5094e90eaf69 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -302,27 +302,12 @@ struct pci_ops mt7621_pci_ops= { .write = pci_config_write, }; -static struct resource mt7621_res_pci_mem1 = { - .name = "PCI MEM1", - .start = RALINK_PCI_MM_MAP_BASE, - .end= (u32)((RALINK_PCI_MM_MAP_BASE + (unsigned char *)0x0fff)), - .flags = IORESOURCE_MEM, -}; - -static struct resource mt7621_res_pci_io1 = { - .name = "PCI I/O1", - .start = RALINK_PCI_IO_MAP_BASE, - .end= (u32)((RALINK_PCI_IO_MAP_BASE + (unsigned char *)0x0)), - .flags = IORESOURCE_IO, -}; - +static struct resource mt7621_res_pci_mem1; +static struct resource mt7621_res_pci_io1; static struct pci_controller mt7621_controller = { .pci_ops= _pci_ops, .mem_resource = _res_pci_mem1, .io_resource= _res_pci_io1, - .mem_offset = 0xUL, - .io_offset = 0xUL, - .io_map_base= 0xa000, }; static void
[PATCH 7/8] staging: mt7621-pci: remove some dead code.
Some code is dead because it is commented out. Some is dead because it is uninteresting printks. Some is dead because it declares unused functions. Remove it all. Signed-off-by: NeilBrown --- drivers/staging/mt7621-pci/pci-mt7621.c | 14 -- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index 5094e90eaf69..edd95013faf3 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -56,9 +56,6 @@ #include -extern void pcie_phy_init(void); -extern void chk_phy_pll(void); - /* * These functions and structures provide the BIOS scan and mapping of the PCI * devices. @@ -364,11 +361,8 @@ pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) void set_pcie_phy(u32 *addr, int start_b, int bits, int val) { -// printk("0x%p:", addr); -// printk(" %x", *addr); *(unsigned int *)(addr) &= ~(((1< %x\n", *addr); } void @@ -497,7 +491,6 @@ static int mt7621_pci_probe(struct platform_device *pdev) val |= RALINK_PCIE2_RST; ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST); - printk("pull PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); *(unsigned int *)(0xbe60) &= ~(0x3<<10 | 0x3<<3); *(unsigned int *)(0xbe60) |= 0x1<<10 | 0x1<<3; @@ -513,12 +506,10 @@ static int mt7621_pci_probe(struct platform_device *pdev) val |= RALINK_PCIE2_RST; DEASSERT_SYSRST_PCIE(val); - printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); if ((*(unsigned int *)(0xbe0c)&0x) == 0x0101) // MT7621 E2 bypass_pipe_rst(); set_phy_for_ssc(); - printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); read_config(0, 0, 0, 0x70c, ); printk("Port 0 N_FTS = %x\n", (unsigned int)val); @@ -614,8 +605,6 @@ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num RALINK_PCI_PCICFG_ADDR |= 0x1 << 24;//port2 break; } - printk(" -> %x\n", RALINK_PCI_PCICFG_ADDR); - //printk(" RALINK_PCI_ARBCTL = %x\n", RALINK_PCI_ARBCTL); /* ioport_resource.start = mt7621_res_pci_io1.start; @@ -653,7 +642,6 @@ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num case 7: read_config(0, 2, 0, 0x4, ); write_config(0, 2, 0, 0x4, val|0x4); - // write_config(0, 1, 0, 0x4, val|0x7); read_config(0, 2, 0, 0x70c, ); val &= ~(0xff)<<8; val |= 0x50<<8; @@ -663,7 +651,6 @@ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num case 6: read_config(0, 1, 0, 0x4, ); write_config(0, 1, 0, 0x4, val|0x4); - // write_config(0, 1, 0, 0x4, val|0x7); read_config(0, 1, 0, 0x70c, ); val &= ~(0xff)<<8; val |= 0x50<<8; @@ -671,7 +658,6 @@ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num default: read_config(0, 0, 0, 0x4, ); write_config(0, 0, 0, 0x4, val|0x4); //bus master enable - // write_config(0, 0, 0, 0x4, val|0x7); //bus master enable read_config(0, 0, 0, 0x70c, ); val &= ~(0xff)<<8; val |= 0x50<<8;
[PATCH 2/8] staging: mt7621-spi: remove unused lock.
This lock is never initialized, locked once, and never unlocked. Clearly it is pointless - so remove it. Signed-off-by: NeilBrown--- drivers/staging/mt7621-spi/spi-mt7621.c |3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/mt7621-spi/spi-mt7621.c b/drivers/staging/mt7621-spi/spi-mt7621.c index d9b55d2059b0..37f299080410 100644 --- a/drivers/staging/mt7621-spi/spi-mt7621.c +++ b/drivers/staging/mt7621-spi/spi-mt7621.c @@ -65,7 +65,6 @@ struct mt7621_spi { unsigned intsys_freq; unsigned intspeed; struct clk *clk; - spinlock_t lock; struct mt7621_spi_ops *ops; }; @@ -395,7 +394,6 @@ static int mt7621_spi_probe(struct platform_device *pdev) const struct of_device_id *match; struct spi_master *master; struct mt7621_spi *rs; - unsigned long flags; void __iomem *base; struct resource *r; int status = 0; @@ -447,7 +445,6 @@ static int mt7621_spi_probe(struct platform_device *pdev) rs->sys_freq = clk_get_rate(rs->clk); rs->ops = ops; dev_info(>dev, "sys_freq: %u\n", rs->sys_freq); - spin_lock_irqsave(>lock, flags); device_reset(>dev);
[PATCH 2/8] staging: mt7621-spi: remove unused lock.
This lock is never initialized, locked once, and never unlocked. Clearly it is pointless - so remove it. Signed-off-by: NeilBrown --- drivers/staging/mt7621-spi/spi-mt7621.c |3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/mt7621-spi/spi-mt7621.c b/drivers/staging/mt7621-spi/spi-mt7621.c index d9b55d2059b0..37f299080410 100644 --- a/drivers/staging/mt7621-spi/spi-mt7621.c +++ b/drivers/staging/mt7621-spi/spi-mt7621.c @@ -65,7 +65,6 @@ struct mt7621_spi { unsigned intsys_freq; unsigned intspeed; struct clk *clk; - spinlock_t lock; struct mt7621_spi_ops *ops; }; @@ -395,7 +394,6 @@ static int mt7621_spi_probe(struct platform_device *pdev) const struct of_device_id *match; struct spi_master *master; struct mt7621_spi *rs; - unsigned long flags; void __iomem *base; struct resource *r; int status = 0; @@ -447,7 +445,6 @@ static int mt7621_spi_probe(struct platform_device *pdev) rs->sys_freq = clk_get_rate(rs->clk); rs->ops = ops; dev_info(>dev, "sys_freq: %u\n", rs->sys_freq); - spin_lock_irqsave(>lock, flags); device_reset(>dev);
[PATCH 1/8] staging: mt7621-eth: Lock is never unlocked.
mtk_phy_link_adjust takes a spinlock and disables interrupts, but never unlocks. This can leave interrupts disabled on one CPU and various things stop working. Signed-off-by: NeilBrown--- drivers/staging/mt7621-eth/mdio.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/mt7621-eth/mdio.c b/drivers/staging/mt7621-eth/mdio.c index 9d713078ef90..c6db11aad9e4 100644 --- a/drivers/staging/mt7621-eth/mdio.c +++ b/drivers/staging/mt7621-eth/mdio.c @@ -57,6 +57,7 @@ static void mtk_phy_link_adjust(struct net_device *dev) } } } + spin_unlock_irqrestore(>phy->lock, flags); } int mtk_connect_phy_node(struct mtk_eth *eth, struct mtk_mac *mac,
Re: [PATCH 3/3] xen: share start flags between PV and PVH
Hi Roger, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.17-rc3 next-20180503] [cannot apply to xen-tip/linux-next] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Roger-Pau-Monne/xen-pvh-Dom0-support/20180504-102629 config: arm64-defconfig (attached as .config) compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm64 All errors (new ones prefixed by >>): In file included from arch/arm64/xen/../../arm/xen/enlighten.c:1:0: >> include/xen/xen.h:28:8: error: unknown type name 'uint32_t' extern uint32_t xen_start_flags; ^~~~ vim +/uint32_t +28 include/xen/xen.h 27 > 28 extern uint32_t xen_start_flags; 29 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH 3/8] staging: mt7621-pci: improve interrupt mapping
As the Interrupts for the PCI adapters are listed in devicetree we shouldn't need to have them explicit in the code. The simplest way to do this is to use of_irq_parse_and_map_pci() and specify an interrupt-map which identifies the different PCI hosts by bus/slot numbers. This has the advantage that the hwirq number are mapped to virq numbers for us, so the ugly hack can go. Signed-off-by: NeilBrown--- drivers/staging/mt7621-dts/mt7621.dtsi |9 ++- drivers/staging/mt7621-pci/pci-mt7621.c | 90 +++ 2 files changed, 14 insertions(+), 85 deletions(-) diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi index ebcaa8b1fc81..9d941b531712 100644 --- a/drivers/staging/mt7621-dts/mt7621.dtsi +++ b/drivers/staging/mt7621-dts/mt7621.dtsi @@ -429,10 +429,11 @@ 0x0100 0 0x 0x1e16 0 0x0001 /* io space */ >; - interrupt-parent = <>; - interrupts = ; + #interrupt-cells = <1>; + interrupt-map-mask = <0xF 0 0 1>; + interrupt-map = <0x1 0 0 1 GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>, + <0x2 0 0 1 GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>, + <0x3 0 0 1 GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index c49442c9b187..cc89d464ef7f 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -73,12 +73,6 @@ extern void chk_phy_pll(void); #define RALINK_PCI_CONFIG_ADDR 0x20 #define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG 0x24 -#define SURFBOARDINT_PCIE0 11 /* PCIE0 */ -#define RALINK_INT_PCIE0 SURFBOARDINT_PCIE0 -#define RALINK_INT_PCIE1 SURFBOARDINT_PCIE1 -#define RALINK_INT_PCIE2 SURFBOARDINT_PCIE2 -#define SURFBOARDINT_PCIE1 31 /* PCIE1 */ -#define SURFBOARDINT_PCIE2 32 /* PCIE2 */ #define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028) #define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C) #define RALINK_PCIE0_RST(1<<24) @@ -367,68 +361,12 @@ pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u16 cmd; u32 val; - int irq = 0; - - if ((dev->bus->number == 0) && (slot == 0)) { - write_config(0, 0, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); - read_config(0, 0, 0, PCI_BASE_ADDRESS_0, (unsigned long *)); - printk("BAR0 at slot 0 = %x\n", val); - printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); - } else if((dev->bus->number == 0) && (slot == 0x1)) { - write_config(0, 1, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); - read_config(0, 1, 0, PCI_BASE_ADDRESS_0, (unsigned long *)); - printk("BAR0 at slot 1 = %x\n", val); - printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); - } else if((dev->bus->number == 0) && (slot == 0x2)) { - write_config(0, 2, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); - read_config(0, 2, 0, PCI_BASE_ADDRESS_0, (unsigned long *)); - printk("BAR0 at slot 2 = %x\n", val); - printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); - } else if ((dev->bus->number == 1) && (slot == 0x0)) { - switch (pcie_link_status) { - case 2: - case 6: - irq = RALINK_INT_PCIE1; - break; - case 4: - irq = RALINK_INT_PCIE2; - break; - default: - irq = RALINK_INT_PCIE0; - } - printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); - } else if ((dev->bus->number == 2) && (slot == 0x0)) { - switch (pcie_link_status) { - case 5: - case 6: - irq = RALINK_INT_PCIE2; - break; - default: - irq = RALINK_INT_PCIE1; - } - printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); - } else if ((dev->bus->number == 2) && (slot == 0x1)) { - switch (pcie_link_status) { - case 5: - case 6: - irq = RALINK_INT_PCIE2; - break; - default: - irq = RALINK_INT_PCIE1; - } - printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); - } else if ((dev->bus->number ==3) && (slot == 0x0)) { - irq = RALINK_INT_PCIE2; -
[PATCH 1/8] staging: mt7621-eth: Lock is never unlocked.
mtk_phy_link_adjust takes a spinlock and disables interrupts, but never unlocks. This can leave interrupts disabled on one CPU and various things stop working. Signed-off-by: NeilBrown --- drivers/staging/mt7621-eth/mdio.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/mt7621-eth/mdio.c b/drivers/staging/mt7621-eth/mdio.c index 9d713078ef90..c6db11aad9e4 100644 --- a/drivers/staging/mt7621-eth/mdio.c +++ b/drivers/staging/mt7621-eth/mdio.c @@ -57,6 +57,7 @@ static void mtk_phy_link_adjust(struct net_device *dev) } } } + spin_unlock_irqrestore(>phy->lock, flags); } int mtk_connect_phy_node(struct mtk_eth *eth, struct mtk_mac *mac,
Re: [PATCH 3/3] xen: share start flags between PV and PVH
Hi Roger, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.17-rc3 next-20180503] [cannot apply to xen-tip/linux-next] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Roger-Pau-Monne/xen-pvh-Dom0-support/20180504-102629 config: arm64-defconfig (attached as .config) compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm64 All errors (new ones prefixed by >>): In file included from arch/arm64/xen/../../arm/xen/enlighten.c:1:0: >> include/xen/xen.h:28:8: error: unknown type name 'uint32_t' extern uint32_t xen_start_flags; ^~~~ vim +/uint32_t +28 include/xen/xen.h 27 > 28 extern uint32_t xen_start_flags; 29 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH 3/8] staging: mt7621-pci: improve interrupt mapping
As the Interrupts for the PCI adapters are listed in devicetree we shouldn't need to have them explicit in the code. The simplest way to do this is to use of_irq_parse_and_map_pci() and specify an interrupt-map which identifies the different PCI hosts by bus/slot numbers. This has the advantage that the hwirq number are mapped to virq numbers for us, so the ugly hack can go. Signed-off-by: NeilBrown --- drivers/staging/mt7621-dts/mt7621.dtsi |9 ++- drivers/staging/mt7621-pci/pci-mt7621.c | 90 +++ 2 files changed, 14 insertions(+), 85 deletions(-) diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi index ebcaa8b1fc81..9d941b531712 100644 --- a/drivers/staging/mt7621-dts/mt7621.dtsi +++ b/drivers/staging/mt7621-dts/mt7621.dtsi @@ -429,10 +429,11 @@ 0x0100 0 0x 0x1e16 0 0x0001 /* io space */ >; - interrupt-parent = <>; - interrupts = ; + #interrupt-cells = <1>; + interrupt-map-mask = <0xF 0 0 1>; + interrupt-map = <0x1 0 0 1 GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>, + <0x2 0 0 1 GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>, + <0x3 0 0 1 GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index c49442c9b187..cc89d464ef7f 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -73,12 +73,6 @@ extern void chk_phy_pll(void); #define RALINK_PCI_CONFIG_ADDR 0x20 #define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG 0x24 -#define SURFBOARDINT_PCIE0 11 /* PCIE0 */ -#define RALINK_INT_PCIE0 SURFBOARDINT_PCIE0 -#define RALINK_INT_PCIE1 SURFBOARDINT_PCIE1 -#define RALINK_INT_PCIE2 SURFBOARDINT_PCIE2 -#define SURFBOARDINT_PCIE1 31 /* PCIE1 */ -#define SURFBOARDINT_PCIE2 32 /* PCIE2 */ #define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028) #define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C) #define RALINK_PCIE0_RST(1<<24) @@ -367,68 +361,12 @@ pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u16 cmd; u32 val; - int irq = 0; - - if ((dev->bus->number == 0) && (slot == 0)) { - write_config(0, 0, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); - read_config(0, 0, 0, PCI_BASE_ADDRESS_0, (unsigned long *)); - printk("BAR0 at slot 0 = %x\n", val); - printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); - } else if((dev->bus->number == 0) && (slot == 0x1)) { - write_config(0, 1, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); - read_config(0, 1, 0, PCI_BASE_ADDRESS_0, (unsigned long *)); - printk("BAR0 at slot 1 = %x\n", val); - printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); - } else if((dev->bus->number == 0) && (slot == 0x2)) { - write_config(0, 2, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); - read_config(0, 2, 0, PCI_BASE_ADDRESS_0, (unsigned long *)); - printk("BAR0 at slot 2 = %x\n", val); - printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); - } else if ((dev->bus->number == 1) && (slot == 0x0)) { - switch (pcie_link_status) { - case 2: - case 6: - irq = RALINK_INT_PCIE1; - break; - case 4: - irq = RALINK_INT_PCIE2; - break; - default: - irq = RALINK_INT_PCIE0; - } - printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); - } else if ((dev->bus->number == 2) && (slot == 0x0)) { - switch (pcie_link_status) { - case 5: - case 6: - irq = RALINK_INT_PCIE2; - break; - default: - irq = RALINK_INT_PCIE1; - } - printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); - } else if ((dev->bus->number == 2) && (slot == 0x1)) { - switch (pcie_link_status) { - case 5: - case 6: - irq = RALINK_INT_PCIE2; - break; - default: - irq = RALINK_INT_PCIE1; - } - printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); - } else if ((dev->bus->number ==3) && (slot == 0x0)) { - irq = RALINK_INT_PCIE2; - printk("bus=0x%x, slot
[PATCH 8/8] staging: mt7621-dts: update nor-flash info for gnubee1
The GNUBEE has 32MB flash, so set partitions accordingly. Also remove "m25p,chunked-io" which isn't documented or used anywhere (outside of freewrt). Signed-off-by: NeilBrown--- drivers/staging/mt7621-dts/gbpc1.dts |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/mt7621-dts/gbpc1.dts b/drivers/staging/mt7621-dts/gbpc1.dts index 515c7cbdd15e..6b13d85d9d34 100644 --- a/drivers/staging/mt7621-dts/gbpc1.dts +++ b/drivers/staging/mt7621-dts/gbpc1.dts @@ -75,7 +75,6 @@ compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <1000>; - m25p,chunked-io = <32>; partition@0 { label = "u-boot"; @@ -97,7 +96,7 @@ partition@5 { label = "firmware"; - reg = <0x5 0xFB>; + reg = <0x5 0x1FB>; }; };
[PATCH 4/8] staging: mt7621-pci: white-space cleanups.
- remove white space at end of line. - no more than 2 blank line at a time - remove spaces before tabs - use tabs to line things up - re-indent some #define do{}while(0) Signed-off-by: NeilBrown--- drivers/staging/mt7621-pci/pci-mt7621.c | 291 +++ 1 file changed, 143 insertions(+), 148 deletions(-) diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index cc89d464ef7f..c8d7b47c8952 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -67,95 +67,94 @@ extern void chk_phy_pll(void); #define CONFIG_PCIE_PORT0 #define CONFIG_PCIE_PORT1 #define CONFIG_PCIE_PORT2 -#define RALINK_PCIE0_CLK_EN (1<<24) -#define RALINK_PCIE1_CLK_EN (1<<25) -#define RALINK_PCIE2_CLK_EN (1<<26) - -#define RALINK_PCI_CONFIG_ADDR 0x20 -#define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG 0x24 -#define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028) -#define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C) -#define RALINK_PCIE0_RST(1<<24) -#define RALINK_PCIE1_RST(1<<25) -#define RALINK_PCIE2_RST(1<<26) -#define RALINK_SYSCTL_BASE 0xBE00 - -#define RALINK_PCI_PCICFG_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x) -#define RALINK_PCI_PCIMSK_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x000C) -#define RALINK_PCI_BASE 0xBE14 - -#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) -#define RT6855_PCIE0_OFFSET 0x2000 -#define RT6855_PCIE1_OFFSET 0x3000 -#define RT6855_PCIE2_OFFSET 0x4000 - -#define RALINK_PCI0_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010) -#define RALINK_PCI0_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018) -#define RALINK_PCI0_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030) -#define RALINK_PCI0_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034) -#define RALINK_PCI0_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038) -#define RALINK_PCI0_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050) -#define RALINK_PCI0_DERR*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060) -#define RALINK_PCI0_ECRC*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064) - -#define RALINK_PCI1_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010) -#define RALINK_PCI1_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018) -#define RALINK_PCI1_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030) -#define RALINK_PCI1_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034) -#define RALINK_PCI1_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038) -#define RALINK_PCI1_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050) -#define RALINK_PCI1_DERR*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060) -#define RALINK_PCI1_ECRC*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064) - -#define RALINK_PCI2_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0010) -#define RALINK_PCI2_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0018) -#define RALINK_PCI2_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0030) -#define RALINK_PCI2_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0034) -#define RALINK_PCI2_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0038) -#define RALINK_PCI2_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0050) -#define RALINK_PCI2_DERR*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0060) -#define RALINK_PCI2_ECRC*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0064) - -#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) -#define RALINK_PCIEPHY_P2_CTL_OFFSET(RALINK_PCI_BASE + 0xA000) - - -#define MV_WRITE(ofs, data) \ -*(volatile u32 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le32(data) -#define MV_READ(ofs, data) \ - *(data) = le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs))) -#define MV_READ_DATA(ofs)\ - le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs))) - -#define MV_WRITE_16(ofs, data) \ -*(volatile u16 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le16(data) -#define MV_READ_16(ofs, data) \ - *(data) =
linux-next: Tree for May 4
Hi all, Changes since 20180503: Non-merge commits (relative to Linus' tree): 3965 3776 files changed, 154371 insertions(+), 67944 deletions(-) I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" and checkout or reset to the new master. You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc, an allmodconfig for x86_64, a multi_v7_defconfig for arm and a native build of tools/perf. After the final fixups (if any), I do an x86_64 modules_install followed by builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig and pseries_le_defconfig and i386, sparc and sparc64 defconfig. And finally, a simple boot test of the powerpc pseries_le_defconfig kernel in qemu (with and without kvm enabled). Below is a summary of the state of the merge. I am currently merging 257 trees (counting Linus' and 44 trees of bug fix patches pending for the current merge release). Stats about the size of the tree over time can be seen at http://neuling.org/linux-next-size.html . Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. -- Cheers, Stephen Rothwell $ git checkout master $ git reset --hard stable Merging origin/master (c15f6d8d4715 Merge tag 'dma-mapping-4.17-4' of git://git.infradead.org/users/hch/dma-mapping) Merging fixes/master (147a89bc71e7 Merge tag 'kconfig-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild) Merging kbuild-current/fixes (6d08b06e67cd Linux 4.17-rc2) Merging arc-current/for-curr (661e50bc8532 Linux 4.16-rc4) Merging arm-current/fixes (30cfae461581 ARM: replace unnecessary perl with sed and the shell $(( )) operator) Merging arm64-fixes/for-next/fixes (3789c122d0a0 arm64: avoid instrumenting atomic_ll_sc.o) Merging m68k-current/for-linus (ecd685580c8f m68k/mac: Remove bogus "FIXME" comment) Merging powerpc-fixes/fixes (b2d7ecbe3556 powerpc/kvm/booke: Fix altivec related build break) Merging sparc/master (fff75eb2a08c Merge tag 'errseq-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux) Merging fscrypt-current/for-stable (ae64f9bd1d36 Linux 4.15-rc2) Merging net/master (a8d7aa17bbc9 dccp: fix tasklet usage) Merging bpf/master (94720e3aee68 ipv4: fix fnhe usage by non-cached routes) Merging ipsec/master (b4331a681822 vti6: Change minimum MTU to IPV4_MIN_MTU, vti6 can carry IPv4 too) Merging netfilter/master (2f99aa31cd7a netfilter: nf_tables: skip synchronize_rcu if transaction log is empty) Merging ipvs/master (765cca91b895 netfilter: conntrack: include kmemleak.h for kmemleak_not_leak()) Merging wireless-drivers/master (af8a41cccf8f rtlwifi: cleanup 8723be ant_sel definition) Merging mac80211/master (2f0605a697f4 nl80211: Free connkeys on external authentication failure) Merging rdma-fixes/for-rc (db82476f3741 IB/core: Make ib_mad_client_id atomic) Merging sound-current/for-linus (f13876e2c33a ALSA: pcm: Check PCM state at xfern compat ioctl) Merging pci-current/for-linus (0cf22d6b317c PCI: Add "PCIe" to pcie_print_link_status() messages) Merging driver-core.current/driver-core-linus (6da6c0db5316 Linux v4.17-rc3) Merging tty.current/tty-linus (6da6c0db5316 Linux v4.17-rc3) Merging usb.current/usb-linus (1a2f474d328f usb: typec: tps6598x: handle block reads separately with plain-I2C adapters) Merging usb-gadget-fixes/fixes (ed769520727e usb: gadget: composite Allow for larger configuration descriptors) Merging usb-serial-fixes/usb-linus (4842ed5bfcb9 USB: serial: visor: handle potential invalid device configuration) Merging usb-chipidea-fixes/ci-for-usb-stable (964728f9f407 USB: chipidea: msm: fix ulpi-node lookup) Merging phy/fixes (60cc43fc8884 Linux 4.17-rc1) Merging staging.current/staging-linus (6da6c0db5316 Linux v4.17-rc3) Merging char-misc.current/char-misc-linus (6da6c0db5316 Linux v4.17-rc3) Merging input-current/for-linus (f6eeb9e54857 Input: atmel_mxt_ts - add missing compatible strings to OF device table) Merging crypto-current/master (eea0d3ea7546 crypto: drbg - set freed buffers to NULL) Merging ide/master (8e44e6600caa Merge branch 'KASAN-read_word_at_a_time') Merging vfio-fixes/for-linus (834814e80268 Revert: "vfio
[PATCH 8/8] staging: mt7621-dts: update nor-flash info for gnubee1
The GNUBEE has 32MB flash, so set partitions accordingly. Also remove "m25p,chunked-io" which isn't documented or used anywhere (outside of freewrt). Signed-off-by: NeilBrown --- drivers/staging/mt7621-dts/gbpc1.dts |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/mt7621-dts/gbpc1.dts b/drivers/staging/mt7621-dts/gbpc1.dts index 515c7cbdd15e..6b13d85d9d34 100644 --- a/drivers/staging/mt7621-dts/gbpc1.dts +++ b/drivers/staging/mt7621-dts/gbpc1.dts @@ -75,7 +75,6 @@ compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <1000>; - m25p,chunked-io = <32>; partition@0 { label = "u-boot"; @@ -97,7 +96,7 @@ partition@5 { label = "firmware"; - reg = <0x5 0xFB>; + reg = <0x5 0x1FB>; }; };
[PATCH 4/8] staging: mt7621-pci: white-space cleanups.
- remove white space at end of line. - no more than 2 blank line at a time - remove spaces before tabs - use tabs to line things up - re-indent some #define do{}while(0) Signed-off-by: NeilBrown --- drivers/staging/mt7621-pci/pci-mt7621.c | 291 +++ 1 file changed, 143 insertions(+), 148 deletions(-) diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index cc89d464ef7f..c8d7b47c8952 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -67,95 +67,94 @@ extern void chk_phy_pll(void); #define CONFIG_PCIE_PORT0 #define CONFIG_PCIE_PORT1 #define CONFIG_PCIE_PORT2 -#define RALINK_PCIE0_CLK_EN (1<<24) -#define RALINK_PCIE1_CLK_EN (1<<25) -#define RALINK_PCIE2_CLK_EN (1<<26) - -#define RALINK_PCI_CONFIG_ADDR 0x20 -#define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG 0x24 -#define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028) -#define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C) -#define RALINK_PCIE0_RST(1<<24) -#define RALINK_PCIE1_RST(1<<25) -#define RALINK_PCIE2_RST(1<<26) -#define RALINK_SYSCTL_BASE 0xBE00 - -#define RALINK_PCI_PCICFG_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x) -#define RALINK_PCI_PCIMSK_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x000C) -#define RALINK_PCI_BASE 0xBE14 - -#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) -#define RT6855_PCIE0_OFFSET 0x2000 -#define RT6855_PCIE1_OFFSET 0x3000 -#define RT6855_PCIE2_OFFSET 0x4000 - -#define RALINK_PCI0_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010) -#define RALINK_PCI0_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018) -#define RALINK_PCI0_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030) -#define RALINK_PCI0_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034) -#define RALINK_PCI0_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038) -#define RALINK_PCI0_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050) -#define RALINK_PCI0_DERR*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060) -#define RALINK_PCI0_ECRC*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064) - -#define RALINK_PCI1_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010) -#define RALINK_PCI1_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018) -#define RALINK_PCI1_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030) -#define RALINK_PCI1_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034) -#define RALINK_PCI1_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038) -#define RALINK_PCI1_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050) -#define RALINK_PCI1_DERR*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060) -#define RALINK_PCI1_ECRC*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064) - -#define RALINK_PCI2_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0010) -#define RALINK_PCI2_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0018) -#define RALINK_PCI2_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0030) -#define RALINK_PCI2_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0034) -#define RALINK_PCI2_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0038) -#define RALINK_PCI2_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0050) -#define RALINK_PCI2_DERR*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0060) -#define RALINK_PCI2_ECRC*(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0064) - -#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) -#define RALINK_PCIEPHY_P2_CTL_OFFSET(RALINK_PCI_BASE + 0xA000) - - -#define MV_WRITE(ofs, data) \ -*(volatile u32 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le32(data) -#define MV_READ(ofs, data) \ - *(data) = le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs))) -#define MV_READ_DATA(ofs)\ - le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs))) - -#define MV_WRITE_16(ofs, data) \ -*(volatile u16 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le16(data) -#define MV_READ_16(ofs, data) \ - *(data) = le16_to_cpu(*(volatile
linux-next: Tree for May 4
Hi all, Changes since 20180503: Non-merge commits (relative to Linus' tree): 3965 3776 files changed, 154371 insertions(+), 67944 deletions(-) I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" and checkout or reset to the new master. You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc, an allmodconfig for x86_64, a multi_v7_defconfig for arm and a native build of tools/perf. After the final fixups (if any), I do an x86_64 modules_install followed by builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig and pseries_le_defconfig and i386, sparc and sparc64 defconfig. And finally, a simple boot test of the powerpc pseries_le_defconfig kernel in qemu (with and without kvm enabled). Below is a summary of the state of the merge. I am currently merging 257 trees (counting Linus' and 44 trees of bug fix patches pending for the current merge release). Stats about the size of the tree over time can be seen at http://neuling.org/linux-next-size.html . Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. -- Cheers, Stephen Rothwell $ git checkout master $ git reset --hard stable Merging origin/master (c15f6d8d4715 Merge tag 'dma-mapping-4.17-4' of git://git.infradead.org/users/hch/dma-mapping) Merging fixes/master (147a89bc71e7 Merge tag 'kconfig-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild) Merging kbuild-current/fixes (6d08b06e67cd Linux 4.17-rc2) Merging arc-current/for-curr (661e50bc8532 Linux 4.16-rc4) Merging arm-current/fixes (30cfae461581 ARM: replace unnecessary perl with sed and the shell $(( )) operator) Merging arm64-fixes/for-next/fixes (3789c122d0a0 arm64: avoid instrumenting atomic_ll_sc.o) Merging m68k-current/for-linus (ecd685580c8f m68k/mac: Remove bogus "FIXME" comment) Merging powerpc-fixes/fixes (b2d7ecbe3556 powerpc/kvm/booke: Fix altivec related build break) Merging sparc/master (fff75eb2a08c Merge tag 'errseq-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux) Merging fscrypt-current/for-stable (ae64f9bd1d36 Linux 4.15-rc2) Merging net/master (a8d7aa17bbc9 dccp: fix tasklet usage) Merging bpf/master (94720e3aee68 ipv4: fix fnhe usage by non-cached routes) Merging ipsec/master (b4331a681822 vti6: Change minimum MTU to IPV4_MIN_MTU, vti6 can carry IPv4 too) Merging netfilter/master (2f99aa31cd7a netfilter: nf_tables: skip synchronize_rcu if transaction log is empty) Merging ipvs/master (765cca91b895 netfilter: conntrack: include kmemleak.h for kmemleak_not_leak()) Merging wireless-drivers/master (af8a41cccf8f rtlwifi: cleanup 8723be ant_sel definition) Merging mac80211/master (2f0605a697f4 nl80211: Free connkeys on external authentication failure) Merging rdma-fixes/for-rc (db82476f3741 IB/core: Make ib_mad_client_id atomic) Merging sound-current/for-linus (f13876e2c33a ALSA: pcm: Check PCM state at xfern compat ioctl) Merging pci-current/for-linus (0cf22d6b317c PCI: Add "PCIe" to pcie_print_link_status() messages) Merging driver-core.current/driver-core-linus (6da6c0db5316 Linux v4.17-rc3) Merging tty.current/tty-linus (6da6c0db5316 Linux v4.17-rc3) Merging usb.current/usb-linus (1a2f474d328f usb: typec: tps6598x: handle block reads separately with plain-I2C adapters) Merging usb-gadget-fixes/fixes (ed769520727e usb: gadget: composite Allow for larger configuration descriptors) Merging usb-serial-fixes/usb-linus (4842ed5bfcb9 USB: serial: visor: handle potential invalid device configuration) Merging usb-chipidea-fixes/ci-for-usb-stable (964728f9f407 USB: chipidea: msm: fix ulpi-node lookup) Merging phy/fixes (60cc43fc8884 Linux 4.17-rc1) Merging staging.current/staging-linus (6da6c0db5316 Linux v4.17-rc3) Merging char-misc.current/char-misc-linus (6da6c0db5316 Linux v4.17-rc3) Merging input-current/for-linus (f6eeb9e54857 Input: atmel_mxt_ts - add missing compatible strings to OF device table) Merging crypto-current/master (eea0d3ea7546 crypto: drbg - set freed buffers to NULL) Merging ide/master (8e44e6600caa Merge branch 'KASAN-read_word_at_a_time') Merging vfio-fixes/for-linus (834814e80268 Revert: "vfio
[PATCH 5/8] staging: mt7621-pci: remove conditional compilation.
Code currently defines: #define CONFIG_PCIE_PORT0 #define CONFIG_PCIE_PORT1 #define CONFIG_PCIE_PORT2 #define GPIO_PERST and then compiles code only if they are defined. We might want to disable some of these via devicetree one day, but for now just remove the #defines and the conditions - all the code for different ports is easy to identify. Signed-off-by: NeilBrown--- drivers/staging/mt7621-pci/pci-mt7621.c | 70 +++ 1 file changed, 15 insertions(+), 55 deletions(-) diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index c8d7b47c8952..616960e01052 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -64,9 +64,6 @@ extern void chk_phy_pll(void); * devices. */ -#define CONFIG_PCIE_PORT0 -#define CONFIG_PCIE_PORT1 -#define CONFIG_PCIE_PORT2 #define RALINK_PCIE0_CLK_EN(1<<24) #define RALINK_PCIE1_CLK_EN(1<<25) #define RALINK_PCIE2_CLK_EN(1<<26) @@ -140,7 +137,7 @@ extern void chk_phy_pll(void); #define RALINK_PCI_IO_MAP_BASE 0x1e16 #define RALINK_SYSTEM_CONTROL_BASE 0xbe00 -#define GPIO_PERST + #define ASSERT_SYSRST_PCIE(val)\ do {\ if (*(unsigned int *)(0xbe0c) == 0x00030101)\ @@ -392,21 +389,15 @@ set_pcie_phy(u32 *addr, int start_b, int bits, int val) void bypass_pipe_rst(void) { -#if defined (CONFIG_PCIE_PORT0) /* PCIe Port 0 */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -#endif -#if defined (CONFIG_PCIE_PORT1) /* PCIe Port 1 */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 12, 1, 0x01); // rg_pe1_pipe_rst_b set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -#endif -#if defined (CONFIG_PCIE_PORT2) /* PCIe Port 2 */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -#endif } void @@ -415,7 +406,6 @@ set_phy_for_ssc(void) unsigned long reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10)); reg = (reg >> 6) & 0x7; -#if defined (CONFIG_PCIE_PORT0) || defined (CONFIG_PCIE_PORT1) /* Set PCIe Port0 & Port1 PHY to disable SSC */ /* Debug Xtal Type */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type @@ -456,8 +446,7 @@ set_phy_for_ssc(void) set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x01); // rg_pe1_phy_en//Port 1 enable set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en//Force Port 0 disable control set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x00); // rg_pe1_frc_phy_en//Force Port 1 disable control -#endif -#if defined (CONFIG_PCIE_PORT2) + /* Set PCIe Port2 PHY to disable SSC */ /* Debug Xtal Type */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type @@ -490,7 +479,6 @@ set_phy_for_ssc(void) /* Enable PHY and disable force mode */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en//Port 0 enable set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en//Force Port 0 disable control -#endif } void setup_cm_memory_region(struct resource *mem_resource) @@ -519,18 +507,13 @@ static int mt7621_pci_probe(struct platform_device *pdev) ioport_resource.start= 0; ioport_resource.end = ~0; -#if defined (CONFIG_PCIE_PORT0) val = RALINK_PCIE0_RST; -#endif -#if defined (CONFIG_PCIE_PORT1) val |= RALINK_PCIE1_RST; -#endif -#if defined (CONFIG_PCIE_PORT2) val |= RALINK_PCIE2_RST; -#endif + ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST); printk("pull PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); -#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/ + *(unsigned int *)(0xbe60) &= ~(0x3<<10 | 0x3<<3); *(unsigned int *)(0xbe60) |= 0x1<<10 | 0x1<<3; mdelay(100); @@ -539,18 +522,11 @@ static int mt7621_pci_probe(struct platform_device *pdev) *(unsigned int *)(0xbe000620) &= ~(0x1<<19 | 0x1<<8 | 0x1<<7); // clear DATA mdelay(100); -#else - *(unsigned int *)(0xbe60) &= ~0x0c00; -#endif -#if
[PATCH 5/8] staging: mt7621-pci: remove conditional compilation.
Code currently defines: #define CONFIG_PCIE_PORT0 #define CONFIG_PCIE_PORT1 #define CONFIG_PCIE_PORT2 #define GPIO_PERST and then compiles code only if they are defined. We might want to disable some of these via devicetree one day, but for now just remove the #defines and the conditions - all the code for different ports is easy to identify. Signed-off-by: NeilBrown --- drivers/staging/mt7621-pci/pci-mt7621.c | 70 +++ 1 file changed, 15 insertions(+), 55 deletions(-) diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index c8d7b47c8952..616960e01052 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -64,9 +64,6 @@ extern void chk_phy_pll(void); * devices. */ -#define CONFIG_PCIE_PORT0 -#define CONFIG_PCIE_PORT1 -#define CONFIG_PCIE_PORT2 #define RALINK_PCIE0_CLK_EN(1<<24) #define RALINK_PCIE1_CLK_EN(1<<25) #define RALINK_PCIE2_CLK_EN(1<<26) @@ -140,7 +137,7 @@ extern void chk_phy_pll(void); #define RALINK_PCI_IO_MAP_BASE 0x1e16 #define RALINK_SYSTEM_CONTROL_BASE 0xbe00 -#define GPIO_PERST + #define ASSERT_SYSRST_PCIE(val)\ do {\ if (*(unsigned int *)(0xbe0c) == 0x00030101)\ @@ -392,21 +389,15 @@ set_pcie_phy(u32 *addr, int start_b, int bits, int val) void bypass_pipe_rst(void) { -#if defined (CONFIG_PCIE_PORT0) /* PCIe Port 0 */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -#endif -#if defined (CONFIG_PCIE_PORT1) /* PCIe Port 1 */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 12, 1, 0x01); // rg_pe1_pipe_rst_b set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -#endif -#if defined (CONFIG_PCIE_PORT2) /* PCIe Port 2 */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -#endif } void @@ -415,7 +406,6 @@ set_phy_for_ssc(void) unsigned long reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10)); reg = (reg >> 6) & 0x7; -#if defined (CONFIG_PCIE_PORT0) || defined (CONFIG_PCIE_PORT1) /* Set PCIe Port0 & Port1 PHY to disable SSC */ /* Debug Xtal Type */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type @@ -456,8 +446,7 @@ set_phy_for_ssc(void) set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x01); // rg_pe1_phy_en//Port 1 enable set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en//Force Port 0 disable control set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x00); // rg_pe1_frc_phy_en//Force Port 1 disable control -#endif -#if defined (CONFIG_PCIE_PORT2) + /* Set PCIe Port2 PHY to disable SSC */ /* Debug Xtal Type */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type @@ -490,7 +479,6 @@ set_phy_for_ssc(void) /* Enable PHY and disable force mode */ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en//Port 0 enable set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en//Force Port 0 disable control -#endif } void setup_cm_memory_region(struct resource *mem_resource) @@ -519,18 +507,13 @@ static int mt7621_pci_probe(struct platform_device *pdev) ioport_resource.start= 0; ioport_resource.end = ~0; -#if defined (CONFIG_PCIE_PORT0) val = RALINK_PCIE0_RST; -#endif -#if defined (CONFIG_PCIE_PORT1) val |= RALINK_PCIE1_RST; -#endif -#if defined (CONFIG_PCIE_PORT2) val |= RALINK_PCIE2_RST; -#endif + ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST); printk("pull PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); -#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/ + *(unsigned int *)(0xbe60) &= ~(0x3<<10 | 0x3<<3); *(unsigned int *)(0xbe60) |= 0x1<<10 | 0x1<<3; mdelay(100); @@ -539,18 +522,11 @@ static int mt7621_pci_probe(struct platform_device *pdev) *(unsigned int *)(0xbe000620) &= ~(0x1<<19 | 0x1<<8 | 0x1<<7); // clear DATA mdelay(100); -#else - *(unsigned int *)(0xbe60) &= ~0x0c00; -#endif -#if defined
[PATCH 0/8] staging: various mt7621 fixes
Highlights here are a bugfix for the ethernet driver, and proper handling of irq assignments in the PCI driver. We also make the full 32M of the gnubee flash available and start cleaning up the mt7621-pci code. --- NeilBrown (8): staging: mt7621-eth: Lock is never unlocked. staging: mt7621-spi: remove unused lock. staging: mt7621-pci: improve interrupt mapping staging: mt7621-pci: white-space cleanups. staging: mt7621-pci: remove conditional compilation. staging: mt7621-pci: remove unnecessary resource details. staging: mt7621-pci: remove some dead code. staging: mt7621-dts: update nor-flash info for gnubee1 drivers/staging/mt7621-dts/gbpc1.dts|3 drivers/staging/mt7621-dts/mt7621.dtsi |9 - drivers/staging/mt7621-eth/mdio.c |1 drivers/staging/mt7621-pci/pci-mt7621.c | 482 +++ drivers/staging/mt7621-spi/spi-mt7621.c |3 5 files changed, 175 insertions(+), 323 deletions(-) -- Signature
[PATCH 0/8] staging: various mt7621 fixes
Highlights here are a bugfix for the ethernet driver, and proper handling of irq assignments in the PCI driver. We also make the full 32M of the gnubee flash available and start cleaning up the mt7621-pci code. --- NeilBrown (8): staging: mt7621-eth: Lock is never unlocked. staging: mt7621-spi: remove unused lock. staging: mt7621-pci: improve interrupt mapping staging: mt7621-pci: white-space cleanups. staging: mt7621-pci: remove conditional compilation. staging: mt7621-pci: remove unnecessary resource details. staging: mt7621-pci: remove some dead code. staging: mt7621-dts: update nor-flash info for gnubee1 drivers/staging/mt7621-dts/gbpc1.dts|3 drivers/staging/mt7621-dts/mt7621.dtsi |9 - drivers/staging/mt7621-eth/mdio.c |1 drivers/staging/mt7621-pci/pci-mt7621.c | 482 +++ drivers/staging/mt7621-spi/spi-mt7621.c |3 5 files changed, 175 insertions(+), 323 deletions(-) -- Signature
Re: [RFC][PATCH] memcg: Replace mm->owner with mm->memcg
On Fri, May 4, 2018 at 1:11 AM, Eric W. Biedermanwrote: > Balbir Singh writes: > >> On Tue, 01 May 2018 12:35:16 -0500 >> ebied...@xmission.com (Eric W. Biederman) wrote: >> >>> Recently it was reported that mm_update_next_owner could get into >>> cases where it was executing it's fallback for_each_process part of >>> the loop and thus taking up a lot of time. >>> >>> To deal with this replace mm->owner with mm->memcg. This just reduces >>> the complexity of everything. As much as possible I have maintained >>> the current semantics. There are two siginificant exceptions. During >>> fork the memcg of the process calling fork is charged rather than >>> init_css_set. During memory cgroup migration the charges are migrated >>> not if the process is the owner of the mm, but if the process being >>> migrated has the same memory cgroup as the mm. >>> >>> I believe it was a bug if init_css_set is charged for memory activity >>> during fork, and the old behavior was simply a consequence of the new >>> task not having tsk->cgroup not initialized to it's proper cgroup. >> >> That does sound like a bug, I guess we've not seen it because we did >> not track any slab allocations initially. > > >>> Durhing cgroup migration only thread group leaders are allowed to >>> migrate. Which means in practice there should only be one. Linux >>> tasks created with CLONE_VM are the only exception, but the common >>> cases are already ruled out. Processes created with vfork have a >>> suspended parent and can do nothing but call exec so they should never >>> show up. Threads of the same cgroup are not the thread group leader >>> so also should not show up. That leaves the old LinuxThreads library >>> which is probably out of use by now, and someone doing something very >>> creative with cgroups, and rolling their own threads with CLONE_VM. >>> So in practice I don't think the difference charge migration will >>> affect anyone. >>> >>> To ensure that mm->memcg is updated appropriately I have implemented >>> cgroup "attach" and "fork" methods. This ensures that at those >>> points the mm pointed to the task has the appropriate memory cgroup. >>> >>> For simplicity instead of introducing a new mm lock I simply use >>> exchange on the pointer where the mm->memcg is updated to get >>> atomic updates. >>> >>> Looking at the history effectively this change is a revert. The >>> reason given for adding mm->owner is so that multiple cgroups can be >>> attached to the same mm. In the last 8 years a second user of >>> mm->owner has not appeared. A feature that has never used, makes the >>> code more complicated and has horrible worst case performance should >>> go. >> >> The idea was to track the mm to the right cgroup, we did find that >> the mm could be confused as belonging to two cgroups. tsk->cgroup is >> not sufficient and if when the tgid left, we needed an owner to track >> where the current allocations were. But this is from 8 year old history, >> I don't have my notes anymore :) > > I was referring to the change 8ish years ago where mm->memcg was > replaced with mm->owner. Semantically the two concepts should both > be perfectly capable of resolving which cgroup the mm belongs to. > Yep, agreed. >>> +static void mem_cgroup_attach(struct cgroup_taskset *tset) >>> +{ >>> +struct cgroup_subsys_state *css; >>> +struct task_struct *tsk; >>> + >>> +cgroup_taskset_for_each(tsk, css, tset) { >>> +struct mem_cgroup *new = mem_cgroup_from_css(css); >>> +css_get(css); >>> +task_update_memcg(tsk, new); >> >> I'd have to go back and check and I think your comment refers to this, >> but we don't expect non tgid tasks to show up here? My concern is I can't >> find the guaratee that task_update_memcg(tsk, new) is not >> >> 1. Duplicated for each thread in the process or attached to the mm >> 2. Do not update mm->memcg to point to different places, so the one >> that sticks is the one that updated things last. > > For cgroupv2 which only operates on processes we have such a guarantee. > > There is no such guarantee for cgroupv1. But it would take someone > being crazy to try this. > > We can add a guarantee to can_attach that we move all of the threads in > a process, and we probably should. However having mm->memcg is more > important structurally than what crazy we let in. So let's make this > change first as safely as we can, and then we don't loose important > data structure simplications if it turns out we have to revert a change > to make the memcgroup per process in cgroupv1. > > > There are some serious issues with the intereactions between the memory > control group and the concept of thread group leader, that show up when > you consider a zombie thread group leader that has called cgroup_exit. > So I am not anxious to stir in concepts like thread_group_leader into > new code unless there is a very good reason. > > We don't
Re: [RFC][PATCH] memcg: Replace mm->owner with mm->memcg
On Fri, May 4, 2018 at 1:11 AM, Eric W. Biederman wrote: > Balbir Singh writes: > >> On Tue, 01 May 2018 12:35:16 -0500 >> ebied...@xmission.com (Eric W. Biederman) wrote: >> >>> Recently it was reported that mm_update_next_owner could get into >>> cases where it was executing it's fallback for_each_process part of >>> the loop and thus taking up a lot of time. >>> >>> To deal with this replace mm->owner with mm->memcg. This just reduces >>> the complexity of everything. As much as possible I have maintained >>> the current semantics. There are two siginificant exceptions. During >>> fork the memcg of the process calling fork is charged rather than >>> init_css_set. During memory cgroup migration the charges are migrated >>> not if the process is the owner of the mm, but if the process being >>> migrated has the same memory cgroup as the mm. >>> >>> I believe it was a bug if init_css_set is charged for memory activity >>> during fork, and the old behavior was simply a consequence of the new >>> task not having tsk->cgroup not initialized to it's proper cgroup. >> >> That does sound like a bug, I guess we've not seen it because we did >> not track any slab allocations initially. > > >>> Durhing cgroup migration only thread group leaders are allowed to >>> migrate. Which means in practice there should only be one. Linux >>> tasks created with CLONE_VM are the only exception, but the common >>> cases are already ruled out. Processes created with vfork have a >>> suspended parent and can do nothing but call exec so they should never >>> show up. Threads of the same cgroup are not the thread group leader >>> so also should not show up. That leaves the old LinuxThreads library >>> which is probably out of use by now, and someone doing something very >>> creative with cgroups, and rolling their own threads with CLONE_VM. >>> So in practice I don't think the difference charge migration will >>> affect anyone. >>> >>> To ensure that mm->memcg is updated appropriately I have implemented >>> cgroup "attach" and "fork" methods. This ensures that at those >>> points the mm pointed to the task has the appropriate memory cgroup. >>> >>> For simplicity instead of introducing a new mm lock I simply use >>> exchange on the pointer where the mm->memcg is updated to get >>> atomic updates. >>> >>> Looking at the history effectively this change is a revert. The >>> reason given for adding mm->owner is so that multiple cgroups can be >>> attached to the same mm. In the last 8 years a second user of >>> mm->owner has not appeared. A feature that has never used, makes the >>> code more complicated and has horrible worst case performance should >>> go. >> >> The idea was to track the mm to the right cgroup, we did find that >> the mm could be confused as belonging to two cgroups. tsk->cgroup is >> not sufficient and if when the tgid left, we needed an owner to track >> where the current allocations were. But this is from 8 year old history, >> I don't have my notes anymore :) > > I was referring to the change 8ish years ago where mm->memcg was > replaced with mm->owner. Semantically the two concepts should both > be perfectly capable of resolving which cgroup the mm belongs to. > Yep, agreed. >>> +static void mem_cgroup_attach(struct cgroup_taskset *tset) >>> +{ >>> +struct cgroup_subsys_state *css; >>> +struct task_struct *tsk; >>> + >>> +cgroup_taskset_for_each(tsk, css, tset) { >>> +struct mem_cgroup *new = mem_cgroup_from_css(css); >>> +css_get(css); >>> +task_update_memcg(tsk, new); >> >> I'd have to go back and check and I think your comment refers to this, >> but we don't expect non tgid tasks to show up here? My concern is I can't >> find the guaratee that task_update_memcg(tsk, new) is not >> >> 1. Duplicated for each thread in the process or attached to the mm >> 2. Do not update mm->memcg to point to different places, so the one >> that sticks is the one that updated things last. > > For cgroupv2 which only operates on processes we have such a guarantee. > > There is no such guarantee for cgroupv1. But it would take someone > being crazy to try this. > > We can add a guarantee to can_attach that we move all of the threads in > a process, and we probably should. However having mm->memcg is more > important structurally than what crazy we let in. So let's make this > change first as safely as we can, and then we don't loose important > data structure simplications if it turns out we have to revert a change > to make the memcgroup per process in cgroupv1. > > > There are some serious issues with the intereactions between the memory > control group and the concept of thread group leader, that show up when > you consider a zombie thread group leader that has called cgroup_exit. > So I am not anxious to stir in concepts like thread_group_leader into > new code unless there is a very good reason. > > We don't exepect crazy but the code allows it, and I have
[PATCH v1] virtio: support VIRTIO_F_IO_BARRIER
This patch introduces the support for VIRTIO_F_IO_BARRIER. When this feature is negotiated, driver will use the barriers suitable for hardware devices. Signed-off-by: Tiwei Bie--- This patch depends on below proposal for virtio-spec: https://lists.oasis-open.org/archives/virtio-dev/201805/msg00019.html This patch also depends on below patch: https://lkml.org/lkml/2018/4/19/789 RFC -> v1: - Address the changes in the proposal; drivers/virtio/virtio_ring.c | 5 + include/uapi/linux/virtio_config.h | 8 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 21d464a29cf8..edb565643bf4 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -996,6 +996,9 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index, !context; vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX); + if (virtio_has_feature(vdev, VIRTIO_F_IO_BARRIER)) + vq->weak_barriers = false; + /* No callback? Tell other side not to bother us. */ if (!callback) { vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT; @@ -1164,6 +1167,8 @@ void vring_transport_features(struct virtio_device *vdev) break; case VIRTIO_F_IOMMU_PLATFORM: break; + case VIRTIO_F_IO_BARRIER: + break; default: /* We don't understand this bit. */ __virtio_clear_bit(vdev, i); diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h index 308e2096291f..9fb519a9df28 100644 --- a/include/uapi/linux/virtio_config.h +++ b/include/uapi/linux/virtio_config.h @@ -49,7 +49,7 @@ * transport being used (eg. virtio_ring), the rest are per-device feature * bits. */ #define VIRTIO_TRANSPORT_F_START 28 -#define VIRTIO_TRANSPORT_F_END 34 +#define VIRTIO_TRANSPORT_F_END 37 #ifndef VIRTIO_CONFIG_NO_LEGACY /* Do we get callbacks when the ring is completely used, even if we've @@ -71,4 +71,10 @@ * this is for compatibility with legacy systems. */ #define VIRTIO_F_IOMMU_PLATFORM33 + +/* + * If clear - driver may use barriers suitable for CPU cores. + * If set - driver must use barriers suitable for hardware devices. + */ +#define VIRTIO_F_IO_BARRIER36 #endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */ -- 2.11.0
[PATCH v1] virtio: support VIRTIO_F_IO_BARRIER
This patch introduces the support for VIRTIO_F_IO_BARRIER. When this feature is negotiated, driver will use the barriers suitable for hardware devices. Signed-off-by: Tiwei Bie --- This patch depends on below proposal for virtio-spec: https://lists.oasis-open.org/archives/virtio-dev/201805/msg00019.html This patch also depends on below patch: https://lkml.org/lkml/2018/4/19/789 RFC -> v1: - Address the changes in the proposal; drivers/virtio/virtio_ring.c | 5 + include/uapi/linux/virtio_config.h | 8 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 21d464a29cf8..edb565643bf4 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -996,6 +996,9 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index, !context; vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX); + if (virtio_has_feature(vdev, VIRTIO_F_IO_BARRIER)) + vq->weak_barriers = false; + /* No callback? Tell other side not to bother us. */ if (!callback) { vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT; @@ -1164,6 +1167,8 @@ void vring_transport_features(struct virtio_device *vdev) break; case VIRTIO_F_IOMMU_PLATFORM: break; + case VIRTIO_F_IO_BARRIER: + break; default: /* We don't understand this bit. */ __virtio_clear_bit(vdev, i); diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h index 308e2096291f..9fb519a9df28 100644 --- a/include/uapi/linux/virtio_config.h +++ b/include/uapi/linux/virtio_config.h @@ -49,7 +49,7 @@ * transport being used (eg. virtio_ring), the rest are per-device feature * bits. */ #define VIRTIO_TRANSPORT_F_START 28 -#define VIRTIO_TRANSPORT_F_END 34 +#define VIRTIO_TRANSPORT_F_END 37 #ifndef VIRTIO_CONFIG_NO_LEGACY /* Do we get callbacks when the ring is completely used, even if we've @@ -71,4 +71,10 @@ * this is for compatibility with legacy systems. */ #define VIRTIO_F_IOMMU_PLATFORM33 + +/* + * If clear - driver may use barriers suitable for CPU cores. + * If set - driver must use barriers suitable for hardware devices. + */ +#define VIRTIO_F_IO_BARRIER36 #endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */ -- 2.11.0
Re: [PATCH v3 6/9] trace_uprobe: Support SDT markers having reference count (semaphore)
Hi Ravi, I have some comments, please see below. On Tue, 17 Apr 2018 10:02:41 +0530 Ravi Bangoriawrote:\ > diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h > index 7bd2760..2db3ed1 100644 > --- a/include/linux/uprobes.h > +++ b/include/linux/uprobes.h > @@ -122,6 +122,8 @@ struct uprobe_map_info { > unsigned long vaddr; > }; > > +extern void (*uprobe_mmap_callback)(struct vm_area_struct *vma); > + > extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned > long vaddr); > extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, > unsigned long vaddr); > extern bool is_swbp_insn(uprobe_opcode_t *insn); > @@ -136,6 +138,8 @@ struct uprobe_map_info { > extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, > unsigned long end); > extern void uprobe_start_dup_mmap(void); > extern void uprobe_end_dup_mmap(void); > +extern void uprobe_down_write_dup_mmap(void); > +extern void uprobe_up_write_dup_mmap(void); > extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct > *newmm); > extern void uprobe_free_utask(struct task_struct *t); > extern void uprobe_copy_process(struct task_struct *t, unsigned long flags); > @@ -192,6 +196,12 @@ static inline void uprobe_start_dup_mmap(void) > static inline void uprobe_end_dup_mmap(void) > { > } > +static inline void uprobe_down_write_dup_mmap(void) > +{ > +} > +static inline void uprobe_up_write_dup_mmap(void) > +{ > +} > static inline void > uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) > { > diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c > index 096d1e6..e26ad83 100644 > --- a/kernel/events/uprobes.c > +++ b/kernel/events/uprobes.c > @@ -1044,6 +1044,9 @@ static void build_probe_list(struct inode *inode, > spin_unlock(_treelock); > } > > +/* Rightnow the only user of this is trace_uprobe. */ > +void (*uprobe_mmap_callback)(struct vm_area_struct *vma); > + > /* > * Called from mmap_region/vma_adjust with mm->mmap_sem acquired. > * > @@ -1056,7 +1059,13 @@ int uprobe_mmap(struct vm_area_struct *vma) > struct uprobe *uprobe, *u; > struct inode *inode; > > - if (no_uprobe_events() || !valid_vma(vma, true)) > + if (no_uprobe_events()) > + return 0; > + > + if (uprobe_mmap_callback) > + uprobe_mmap_callback(vma); > + > + if (!valid_vma(vma, true)) > return 0; > > inode = file_inode(vma->vm_file); > @@ -1247,6 +1256,16 @@ void uprobe_end_dup_mmap(void) > percpu_up_read(_mmap_sem); > } > > +void uprobe_down_write_dup_mmap(void) > +{ > + percpu_down_write(_mmap_sem); > +} > + > +void uprobe_up_write_dup_mmap(void) > +{ > + percpu_up_write(_mmap_sem); > +} > + I'm not sure why these hunks are not done in previous patch. If you separate "uprobe_map_info" export patch, this also should be separated. (Or both merged into this patch) > void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) > { > if (test_bit(MMF_HAS_UPROBES, >flags)) { > diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c > index 0d450b4..1a48b04 100644 > --- a/kernel/trace/trace_uprobe.c > +++ b/kernel/trace/trace_uprobe.c > @@ -25,6 +25,8 @@ > #include > #include > #include > +#include > +#include > > #include "trace_probe.h" > > @@ -58,6 +60,7 @@ struct trace_uprobe { > struct inode*inode; > char*filename; > unsigned long offset; > + unsigned long ref_ctr_offset; > unsigned long nhit; > struct trace_probe tp; > }; > @@ -364,10 +367,10 @@ static int create_trace_uprobe(int argc, char **argv) > { > struct trace_uprobe *tu; > struct inode *inode; > - char *arg, *event, *group, *filename; > + char *arg, *event, *group, *filename, *rctr, *rctr_end; > char buf[MAX_EVENT_NAME_LEN]; > struct path path; > - unsigned long offset; > + unsigned long offset, ref_ctr_offset; > bool is_delete, is_return; > int i, ret; > > @@ -377,6 +380,7 @@ static int create_trace_uprobe(int argc, char **argv) > is_return = false; > event = NULL; > group = NULL; > + ref_ctr_offset = 0; > > /* argc must be >= 1 */ > if (argv[0][0] == '-') > @@ -456,6 +460,26 @@ static int create_trace_uprobe(int argc, char **argv) > goto fail_address_parse; > } > > + /* Parse reference counter offset if specified. */ > + rctr = strchr(arg, '('); > + if (rctr) { > + rctr_end = strchr(rctr, ')'); > + if (rctr > rctr_end || *(rctr_end + 1) != 0) { > + ret = -EINVAL; > + pr_info("Invalid reference counter offset.\n"); > + goto fail_address_parse; > + } > + > +
Re: [PATCH v3 6/9] trace_uprobe: Support SDT markers having reference count (semaphore)
Hi Ravi, I have some comments, please see below. On Tue, 17 Apr 2018 10:02:41 +0530 Ravi Bangoria wrote:\ > diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h > index 7bd2760..2db3ed1 100644 > --- a/include/linux/uprobes.h > +++ b/include/linux/uprobes.h > @@ -122,6 +122,8 @@ struct uprobe_map_info { > unsigned long vaddr; > }; > > +extern void (*uprobe_mmap_callback)(struct vm_area_struct *vma); > + > extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned > long vaddr); > extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, > unsigned long vaddr); > extern bool is_swbp_insn(uprobe_opcode_t *insn); > @@ -136,6 +138,8 @@ struct uprobe_map_info { > extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, > unsigned long end); > extern void uprobe_start_dup_mmap(void); > extern void uprobe_end_dup_mmap(void); > +extern void uprobe_down_write_dup_mmap(void); > +extern void uprobe_up_write_dup_mmap(void); > extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct > *newmm); > extern void uprobe_free_utask(struct task_struct *t); > extern void uprobe_copy_process(struct task_struct *t, unsigned long flags); > @@ -192,6 +196,12 @@ static inline void uprobe_start_dup_mmap(void) > static inline void uprobe_end_dup_mmap(void) > { > } > +static inline void uprobe_down_write_dup_mmap(void) > +{ > +} > +static inline void uprobe_up_write_dup_mmap(void) > +{ > +} > static inline void > uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) > { > diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c > index 096d1e6..e26ad83 100644 > --- a/kernel/events/uprobes.c > +++ b/kernel/events/uprobes.c > @@ -1044,6 +1044,9 @@ static void build_probe_list(struct inode *inode, > spin_unlock(_treelock); > } > > +/* Rightnow the only user of this is trace_uprobe. */ > +void (*uprobe_mmap_callback)(struct vm_area_struct *vma); > + > /* > * Called from mmap_region/vma_adjust with mm->mmap_sem acquired. > * > @@ -1056,7 +1059,13 @@ int uprobe_mmap(struct vm_area_struct *vma) > struct uprobe *uprobe, *u; > struct inode *inode; > > - if (no_uprobe_events() || !valid_vma(vma, true)) > + if (no_uprobe_events()) > + return 0; > + > + if (uprobe_mmap_callback) > + uprobe_mmap_callback(vma); > + > + if (!valid_vma(vma, true)) > return 0; > > inode = file_inode(vma->vm_file); > @@ -1247,6 +1256,16 @@ void uprobe_end_dup_mmap(void) > percpu_up_read(_mmap_sem); > } > > +void uprobe_down_write_dup_mmap(void) > +{ > + percpu_down_write(_mmap_sem); > +} > + > +void uprobe_up_write_dup_mmap(void) > +{ > + percpu_up_write(_mmap_sem); > +} > + I'm not sure why these hunks are not done in previous patch. If you separate "uprobe_map_info" export patch, this also should be separated. (Or both merged into this patch) > void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) > { > if (test_bit(MMF_HAS_UPROBES, >flags)) { > diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c > index 0d450b4..1a48b04 100644 > --- a/kernel/trace/trace_uprobe.c > +++ b/kernel/trace/trace_uprobe.c > @@ -25,6 +25,8 @@ > #include > #include > #include > +#include > +#include > > #include "trace_probe.h" > > @@ -58,6 +60,7 @@ struct trace_uprobe { > struct inode*inode; > char*filename; > unsigned long offset; > + unsigned long ref_ctr_offset; > unsigned long nhit; > struct trace_probe tp; > }; > @@ -364,10 +367,10 @@ static int create_trace_uprobe(int argc, char **argv) > { > struct trace_uprobe *tu; > struct inode *inode; > - char *arg, *event, *group, *filename; > + char *arg, *event, *group, *filename, *rctr, *rctr_end; > char buf[MAX_EVENT_NAME_LEN]; > struct path path; > - unsigned long offset; > + unsigned long offset, ref_ctr_offset; > bool is_delete, is_return; > int i, ret; > > @@ -377,6 +380,7 @@ static int create_trace_uprobe(int argc, char **argv) > is_return = false; > event = NULL; > group = NULL; > + ref_ctr_offset = 0; > > /* argc must be >= 1 */ > if (argv[0][0] == '-') > @@ -456,6 +460,26 @@ static int create_trace_uprobe(int argc, char **argv) > goto fail_address_parse; > } > > + /* Parse reference counter offset if specified. */ > + rctr = strchr(arg, '('); > + if (rctr) { > + rctr_end = strchr(rctr, ')'); > + if (rctr > rctr_end || *(rctr_end + 1) != 0) { > + ret = -EINVAL; > + pr_info("Invalid reference counter offset.\n"); > + goto fail_address_parse; > + } > + > + *rctr++ = '\0'; > +
Re: [PATCH v4 05/22] iommu: introduce iommu invalidate API function
On Wed, 2 May 2018 10:31:50 +0100 Jean-Philippe Bruckerwrote: > On 01/05/18 23:58, Jacob Pan wrote: > Maybe this should be called "NG_PAGE_PASID", > >>> Sure. I was thinking page range already implies non-global > >>> pages. > and "DOMAIN_PAGE" should > instead be "PAGE_PASID". If I understood their meaning correctly, > it would be more consistent with the rest. > > >>> I am trying not to mix granu between request w/ PASID and w/o. > >>> DOMAIN_PAGE meant to be for request w/o PASID. > >> > >> Is the distinction necessary? I understand the IOMMU side might > >> offer many possibilities for invalidation, but the user probably > >> doesn't need all of them. It might be easier to document, upstream > >> and maintain if we only specify what's currently needed by users > >> (what does QEMU VT-d use?) Others can always extend it by > >> increasing the version. > >> > >> Do you think that this invalidation message will be used outside of > >> BIND_PASID_TABLE context? I can't see an other use but who knows. > >> At the moment requests w/o PASID are managed with > >> VFIO_IOMMU_MAP/UNMAP_DMA, which doesn't require invalidation. And > >> in a BIND_PASID_TABLE context, IOMMUs requests w/o PASID are just a > >> special case using PASID 0 (for Arm and AMD) so I suppose they'll > >> use the same invalidation commands as requests w/ PASID. > >> > > My understanding is that for GIOVA use case, VT-d vIOMMU creates > > GIOVA-GPA mapping and the host shadows the 2nd level page tables to > > create GIOVA-HPA mapping. So when assigned device in the guest can > > do both DMA map/unmap and VFIO map/unmap, VFIO unmap is one time > > deal (I guess invalidation can be captured in other code path), but > > guest kernel use of DMA unmap could will trigger invalidation. QEMU > > needs to trap those invalidation and passdown to physical IOMMU. So > > we do need invalidation w/o PASID. > > Hm, isn't this all done by host userspace? Whether guest does DMA > map/unmap or VFIO map/unmap, it creates/removes IOVA-GPA mappings in > the vIOMMU. QEMU captures invalidation requests for these mappings > from the guest, finds GPA-HVA in the shadow map and sends a VFIO > map/unmap request for IOVA-HVA. > Sorry for the delay but you are right, I have also confirmed with Yi that we don't need second level invalidation. I will remove IOTLB invalidation w/o PASID case from the API. Thanks, > Thanks, > Jean > [Jacob Pan]
Re: [PATCH v4 05/22] iommu: introduce iommu invalidate API function
On Wed, 2 May 2018 10:31:50 +0100 Jean-Philippe Brucker wrote: > On 01/05/18 23:58, Jacob Pan wrote: > Maybe this should be called "NG_PAGE_PASID", > >>> Sure. I was thinking page range already implies non-global > >>> pages. > and "DOMAIN_PAGE" should > instead be "PAGE_PASID". If I understood their meaning correctly, > it would be more consistent with the rest. > > >>> I am trying not to mix granu between request w/ PASID and w/o. > >>> DOMAIN_PAGE meant to be for request w/o PASID. > >> > >> Is the distinction necessary? I understand the IOMMU side might > >> offer many possibilities for invalidation, but the user probably > >> doesn't need all of them. It might be easier to document, upstream > >> and maintain if we only specify what's currently needed by users > >> (what does QEMU VT-d use?) Others can always extend it by > >> increasing the version. > >> > >> Do you think that this invalidation message will be used outside of > >> BIND_PASID_TABLE context? I can't see an other use but who knows. > >> At the moment requests w/o PASID are managed with > >> VFIO_IOMMU_MAP/UNMAP_DMA, which doesn't require invalidation. And > >> in a BIND_PASID_TABLE context, IOMMUs requests w/o PASID are just a > >> special case using PASID 0 (for Arm and AMD) so I suppose they'll > >> use the same invalidation commands as requests w/ PASID. > >> > > My understanding is that for GIOVA use case, VT-d vIOMMU creates > > GIOVA-GPA mapping and the host shadows the 2nd level page tables to > > create GIOVA-HPA mapping. So when assigned device in the guest can > > do both DMA map/unmap and VFIO map/unmap, VFIO unmap is one time > > deal (I guess invalidation can be captured in other code path), but > > guest kernel use of DMA unmap could will trigger invalidation. QEMU > > needs to trap those invalidation and passdown to physical IOMMU. So > > we do need invalidation w/o PASID. > > Hm, isn't this all done by host userspace? Whether guest does DMA > map/unmap or VFIO map/unmap, it creates/removes IOVA-GPA mappings in > the vIOMMU. QEMU captures invalidation requests for these mappings > from the guest, finds GPA-HVA in the shadow map and sends a VFIO > map/unmap request for IOVA-HVA. > Sorry for the delay but you are right, I have also confirmed with Yi that we don't need second level invalidation. I will remove IOTLB invalidation w/o PASID case from the API. Thanks, > Thanks, > Jean > [Jacob Pan]
Re: [PATCH v1] lib/string_helpers: Add missed declaration of struct task_struct
On Thu, May 3, 2018 at 6:13 PM, Andy Shevchenkowrote: > Starting from the commit 0d0443288f22 the new function has been > introduced which takes struct task_struct as a parameter. Though, > compiler doesn't know where to get information about it at this stage. > > Add missed declaration of struct task_struct to satisfy compiler. > > Fixes: 0d0443288f22 ("string_helpers: add kstrdup_quotable_cmdline") > Cc: Kees Cook > Cc: James Morris > Signed-off-by: Andy Shevchenko Acked-by: Kees Cook I'm not sure who should carry this. You're welcome to put it in your tree? -Kees > --- > include/linux/string_helpers.h | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h > index 4397c52ec4a4..d23c5030901a 100644 > --- a/include/linux/string_helpers.h > +++ b/include/linux/string_helpers.h > @@ -5,6 +5,7 @@ > #include > > struct file; > +struct task_struct; > > /* Descriptions of the types of units to > * print in */ > -- > 2.17.0 > -- Kees Cook Pixel Security
Re: [PATCH v1] lib/string_helpers: Add missed declaration of struct task_struct
On Thu, May 3, 2018 at 6:13 PM, Andy Shevchenko wrote: > Starting from the commit 0d0443288f22 the new function has been > introduced which takes struct task_struct as a parameter. Though, > compiler doesn't know where to get information about it at this stage. > > Add missed declaration of struct task_struct to satisfy compiler. > > Fixes: 0d0443288f22 ("string_helpers: add kstrdup_quotable_cmdline") > Cc: Kees Cook > Cc: James Morris > Signed-off-by: Andy Shevchenko Acked-by: Kees Cook I'm not sure who should carry this. You're welcome to put it in your tree? -Kees > --- > include/linux/string_helpers.h | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h > index 4397c52ec4a4..d23c5030901a 100644 > --- a/include/linux/string_helpers.h > +++ b/include/linux/string_helpers.h > @@ -5,6 +5,7 @@ > #include > > struct file; > +struct task_struct; > > /* Descriptions of the types of units to > * print in */ > -- > 2.17.0 > -- Kees Cook Pixel Security
Re: [PATCH V3 10/10] ASoC: amd: dma driver changes for bt i2s instance
On 5/3/2018 10:10 PM, Daniel Kurtz wrote: On Thu, May 3, 2018 at 1:33 AM Mukunda,Vijendarwrote: On Thursday 03 May 2018 11:13 AM, Daniel Kurtz wrote: Some checkpatch nits below... On Tue, May 1, 2018 at 2:53 PM Vijendar Mukunda < vijendar.muku...@amd.com> wrote: With in ACP, There are three I2S controllers can be configured/enabled ( I2S SP, I2S MICSP, I2S BT). Default enabled I2S controller instance is I2S SP. This patch provides required changes to support I2S BT controller Instance. Signed-off-by: Vijendar Mukunda --- v1->v2: defined i2s instance macros in acp header file v2->v3: sqaushed previous patch series and spilt changes into multiple patches (acp dma driver code cleanup patches and bt i2s instance specific changes) sound/soc/amd/acp-da7219-max98357a.c | 23 sound/soc/amd/acp-pcm-dma.c | 256 +++ sound/soc/amd/acp.h | 40 ++ 3 files changed, 262 insertions(+), 57 deletions(-) diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c index 133139d..b3184ab 100644 --- a/sound/soc/amd/acp-da7219-max98357a.c +++ b/sound/soc/amd/acp-da7219-max98357a.c @@ -36,6 +36,7 @@ #include #include +#include "acp.h" #include "../codecs/da7219.h" #include "../codecs/da7219-aad.h" @@ -44,6 +45,7 @@ static struct snd_soc_jack cz_jack; static struct clk *da7219_dai_clk; +extern int bt_pad_enable; WARNING: externs should be avoided in .c files We don't have .h file for machine driver and It can be ignored for one variable. static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd) { @@ -132,6 +134,9 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = { static int cz_da7219_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct acp_platform_info *machine = snd_soc_card_get_drvdata(card); /* * On this platform for PCM device we support stereo @@ -143,6 +148,7 @@ static int cz_da7219_startup(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, _rates); + machine->i2s_instance = I2S_BT_INSTANCE; I'm not a big fan of this approach, but I don't know any other way to tell a single "platform" driver (acp-pcm-dma) which of two channels (ST/BT) to use via the pcm_open() callback. Mark, can you recommend any other way of doing this? Hi Dan, There have been couple of approaches worked upon this earlier. 1) To compare cpu dai name to get the I2S instance value in acp_dma_open() call. But, Mark suggested not to implement this approach as we are comparing dynamically generated cpu dai names. 2) We added i2s_instance parameter as platform data to dwc driver. By querying dwc driver platform data in acp dma driver, current i2s instance was programmed in acp_dma_open (). But Mark's latest comment was to implement platform specific changes in machine driver. Machine driver and Dma driver should exchange the data regarding this. We accepted this and current approach is based on the same comment. Below is the reference. https://lkml.org/lkml/2018/4/18/597 Yes, I saw Mark's previous comment, but what we are trying to implement here is the SoC specific binding between i2s channel and acp-dma channel. This is a feature of the SoC, not of the i2s controller, but also not a feature of the audio configuration on the board. The binding of channel and dma is soc specific but codec to channel is board specific. These linkages can change from one board to another. Machine driver is specific to a board (grunt here) and dma driver being common for various boards (but specific to a platform like ST/CZ here). Tomorrow there can be some other board with x codec linked to BT and y to SP. Hence, machine driver should send this board specific link information to dma driver for it to dma on the correct channel as per the board. For these SoCs, the link between DMA registers & I2S-channel is hard-coded. The machine driver is already specifying which i2s channel to use when it configures, for example, '.cpu_dai_name = "designware-i2s.2.auto"'. The i2s channel selection already implies a particular DMA configuration. It seems redundant to create this separate out-of-band infrastructure to make the machine driver also tell its platform driver '.platform_name = "acp_audio_dma.0.auto"' which i2s channel it is using. We could have decided on the basis of "cpu_dai_name" but the decision would have been based on dynamically generated name. Though maybe redundant in nature, but machine driver is
Re: [PATCH V3 10/10] ASoC: amd: dma driver changes for bt i2s instance
On 5/3/2018 10:10 PM, Daniel Kurtz wrote: On Thu, May 3, 2018 at 1:33 AM Mukunda,Vijendar wrote: On Thursday 03 May 2018 11:13 AM, Daniel Kurtz wrote: Some checkpatch nits below... On Tue, May 1, 2018 at 2:53 PM Vijendar Mukunda < vijendar.muku...@amd.com> wrote: With in ACP, There are three I2S controllers can be configured/enabled ( I2S SP, I2S MICSP, I2S BT). Default enabled I2S controller instance is I2S SP. This patch provides required changes to support I2S BT controller Instance. Signed-off-by: Vijendar Mukunda --- v1->v2: defined i2s instance macros in acp header file v2->v3: sqaushed previous patch series and spilt changes into multiple patches (acp dma driver code cleanup patches and bt i2s instance specific changes) sound/soc/amd/acp-da7219-max98357a.c | 23 sound/soc/amd/acp-pcm-dma.c | 256 +++ sound/soc/amd/acp.h | 40 ++ 3 files changed, 262 insertions(+), 57 deletions(-) diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c index 133139d..b3184ab 100644 --- a/sound/soc/amd/acp-da7219-max98357a.c +++ b/sound/soc/amd/acp-da7219-max98357a.c @@ -36,6 +36,7 @@ #include #include +#include "acp.h" #include "../codecs/da7219.h" #include "../codecs/da7219-aad.h" @@ -44,6 +45,7 @@ static struct snd_soc_jack cz_jack; static struct clk *da7219_dai_clk; +extern int bt_pad_enable; WARNING: externs should be avoided in .c files We don't have .h file for machine driver and It can be ignored for one variable. static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd) { @@ -132,6 +134,9 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = { static int cz_da7219_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct acp_platform_info *machine = snd_soc_card_get_drvdata(card); /* * On this platform for PCM device we support stereo @@ -143,6 +148,7 @@ static int cz_da7219_startup(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, _rates); + machine->i2s_instance = I2S_BT_INSTANCE; I'm not a big fan of this approach, but I don't know any other way to tell a single "platform" driver (acp-pcm-dma) which of two channels (ST/BT) to use via the pcm_open() callback. Mark, can you recommend any other way of doing this? Hi Dan, There have been couple of approaches worked upon this earlier. 1) To compare cpu dai name to get the I2S instance value in acp_dma_open() call. But, Mark suggested not to implement this approach as we are comparing dynamically generated cpu dai names. 2) We added i2s_instance parameter as platform data to dwc driver. By querying dwc driver platform data in acp dma driver, current i2s instance was programmed in acp_dma_open (). But Mark's latest comment was to implement platform specific changes in machine driver. Machine driver and Dma driver should exchange the data regarding this. We accepted this and current approach is based on the same comment. Below is the reference. https://lkml.org/lkml/2018/4/18/597 Yes, I saw Mark's previous comment, but what we are trying to implement here is the SoC specific binding between i2s channel and acp-dma channel. This is a feature of the SoC, not of the i2s controller, but also not a feature of the audio configuration on the board. The binding of channel and dma is soc specific but codec to channel is board specific. These linkages can change from one board to another. Machine driver is specific to a board (grunt here) and dma driver being common for various boards (but specific to a platform like ST/CZ here). Tomorrow there can be some other board with x codec linked to BT and y to SP. Hence, machine driver should send this board specific link information to dma driver for it to dma on the correct channel as per the board. For these SoCs, the link between DMA registers & I2S-channel is hard-coded. The machine driver is already specifying which i2s channel to use when it configures, for example, '.cpu_dai_name = "designware-i2s.2.auto"'. The i2s channel selection already implies a particular DMA configuration. It seems redundant to create this separate out-of-band infrastructure to make the machine driver also tell its platform driver '.platform_name = "acp_audio_dma.0.auto"' which i2s channel it is using. We could have decided on the basis of "cpu_dai_name" but the decision would have been based on dynamically generated name. Though maybe redundant in nature, but machine driver is just sending info to dma driver that this codec is
[PATCH] mm/page_alloc: use ac->high_zoneidx for classzone_idx
From: Joonsoo KimCurrently, we use the zone index of preferred_zone which represents the best matching zone for allocation, as classzone_idx. It has a problem on NUMA system with ZONE_MOVABLE. In NUMA system, it can be possible that each node has different populated zones. For example, node 0 could have DMA/DMA32/NORMAL/MOVABLE zone and node 1 could have only NORMAL zone. In this setup, allocation request initiated on node 0 and the one on node 1 would have different classzone_idx, 3 and 2, respectively, since their preferred_zones are different. If they are handled by only their own node, there is no problem. However, if they are somtimes handled by the remote node, the problem would happen. In the following setup, allocation initiated on node 1 will have some precedence than allocation initiated on node 0 when former allocation is processed on node 0 due to not enough memory on node 1. They will have different lowmem reserve due to their different classzone_idx thus an watermark bars are also different. root@ubuntu:/sys/devices/system/memory# cat /proc/zoneinfo Node 0, zone DMA per-node stats ... pages free 3965 min 5 low 8 high 11 spanned 4095 present 3998 managed 3977 protection: (0, 2961, 4928, 5440) ... Node 0, zoneDMA32 pages free 757955 min 1129 low 1887 high 2645 spanned 1044480 present 782303 managed 758116 protection: (0, 0, 1967, 2479) ... Node 0, zone Normal pages free 459806 min 750 low 1253 high 1756 spanned 524288 present 524288 managed 503620 protection: (0, 0, 0, 4096) ... Node 0, zone Movable pages free 130759 min 195 low 326 high 457 spanned 1966079 present 131072 managed 131072 protection: (0, 0, 0, 0) ... Node 1, zone DMA pages free 0 min 0 low 0 high 0 spanned 0 present 0 managed 0 protection: (0, 0, 1006, 1006) Node 1, zoneDMA32 pages free 0 min 0 low 0 high 0 spanned 0 present 0 managed 0 protection: (0, 0, 1006, 1006) Node 1, zone Normal per-node stats ... pages free 233277 min 383 low 640 high 897 spanned 262144 present 262144 managed 257744 protection: (0, 0, 0, 0) ... Node 1, zone Movable pages free 0 min 0 low 0 high 0 spanned 262144 present 0 managed 0 protection: (0, 0, 0, 0) min watermark for NORMAL zone on node 0 allocation initiated on node 0: 750 + 4096 = 4846 allocation initiated on node 1: 750 + 0 = 750 This watermark difference could cause too many numa_miss allocation in some situation and then performance could be downgraded. Recently, there was a regression report about this problem on CMA patches since CMA memory are placed in ZONE_MOVABLE by those patches. I checked that problem is disappeared with this fix that uses high_zoneidx for classzone_idx. http://lkml.kernel.org/r/20180102063528.GG30397@yexl-desktop Using high_zoneidx for classzone_idx is more consistent way than previous approach because system's memory layout doesn't affect anything to it. With this patch, both classzone_idx on above example will be 3 so will have the same min watermark. allocation initiated on node 0: 750 + 4096 = 4846 allocation initiated on node 1: 750 + 4096 = 4846 Reported-by: Ye Xiaolong Tested-by: Ye Xiaolong Signed-off-by: Joonsoo Kim --- mm/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/internal.h b/mm/internal.h index 228dd66..e1d7376 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -123,7 +123,7 @@ struct alloc_context { bool spread_dirty_pages; }; -#define ac_classzone_idx(ac) zonelist_zone_idx(ac->preferred_zoneref) +#define ac_classzone_idx(ac) (ac->high_zoneidx) /* * Locate the struct page for both the matching buddy in our -- 2.7.4
Re: serial: start_tx & buffer handling
On Fri, May 4, 2018 at 12:04 AM, Greg KHwrote: > On Thu, May 03, 2018 at 08:08:48PM +0530, Muni Sekhar wrote: >> Hi All, >> >> I’m trying to understand how user mode buffer is written to low level >> serial hardware registers. >> >> For this I read the kernel code and I came to know that from user mode >> write() API lands into kernel’s tty_write() ("drivers/tty/tty_io.c") >> and then it calls a uart_write() ("drivers/tty/serial/serial_core.c"). >> >> In uart_write(), the buffer is copied to circ_buf and then it calls >> low level serial hardware driver’s start_tx() (struct uart_ops >> .start_tx). But here I could not find how the buffer kept in circ_buf >> is copied to serial port’s TX_FIFO registers? >> >> Can someone take a moment to explain me on this? > > It all depends on which specific UART driver you are looking at, they > all do it a bit different depending on the hardware. > > Which one are you looking at? Look at what the start_tx callback does > for that specific driver, that should give you a hint as to how data > starts flowing. Usually an interrupt is enabled that is used to flush > the buffer out to the hardware. > I’m looking for any existing sample code which does DMA transfers of UART transmitted data. I looked at the bcm63xx_uart.c, it looks it does not handle DMA transfers. Even copying the Tx buffer (from circ_buf) to UART_FIFO_REG happening in ISR. > thanks, > > greg k-h -- Thanks, Sekhar
[PATCH] mm/page_alloc: use ac->high_zoneidx for classzone_idx
From: Joonsoo Kim Currently, we use the zone index of preferred_zone which represents the best matching zone for allocation, as classzone_idx. It has a problem on NUMA system with ZONE_MOVABLE. In NUMA system, it can be possible that each node has different populated zones. For example, node 0 could have DMA/DMA32/NORMAL/MOVABLE zone and node 1 could have only NORMAL zone. In this setup, allocation request initiated on node 0 and the one on node 1 would have different classzone_idx, 3 and 2, respectively, since their preferred_zones are different. If they are handled by only their own node, there is no problem. However, if they are somtimes handled by the remote node, the problem would happen. In the following setup, allocation initiated on node 1 will have some precedence than allocation initiated on node 0 when former allocation is processed on node 0 due to not enough memory on node 1. They will have different lowmem reserve due to their different classzone_idx thus an watermark bars are also different. root@ubuntu:/sys/devices/system/memory# cat /proc/zoneinfo Node 0, zone DMA per-node stats ... pages free 3965 min 5 low 8 high 11 spanned 4095 present 3998 managed 3977 protection: (0, 2961, 4928, 5440) ... Node 0, zoneDMA32 pages free 757955 min 1129 low 1887 high 2645 spanned 1044480 present 782303 managed 758116 protection: (0, 0, 1967, 2479) ... Node 0, zone Normal pages free 459806 min 750 low 1253 high 1756 spanned 524288 present 524288 managed 503620 protection: (0, 0, 0, 4096) ... Node 0, zone Movable pages free 130759 min 195 low 326 high 457 spanned 1966079 present 131072 managed 131072 protection: (0, 0, 0, 0) ... Node 1, zone DMA pages free 0 min 0 low 0 high 0 spanned 0 present 0 managed 0 protection: (0, 0, 1006, 1006) Node 1, zoneDMA32 pages free 0 min 0 low 0 high 0 spanned 0 present 0 managed 0 protection: (0, 0, 1006, 1006) Node 1, zone Normal per-node stats ... pages free 233277 min 383 low 640 high 897 spanned 262144 present 262144 managed 257744 protection: (0, 0, 0, 0) ... Node 1, zone Movable pages free 0 min 0 low 0 high 0 spanned 262144 present 0 managed 0 protection: (0, 0, 0, 0) min watermark for NORMAL zone on node 0 allocation initiated on node 0: 750 + 4096 = 4846 allocation initiated on node 1: 750 + 0 = 750 This watermark difference could cause too many numa_miss allocation in some situation and then performance could be downgraded. Recently, there was a regression report about this problem on CMA patches since CMA memory are placed in ZONE_MOVABLE by those patches. I checked that problem is disappeared with this fix that uses high_zoneidx for classzone_idx. http://lkml.kernel.org/r/20180102063528.GG30397@yexl-desktop Using high_zoneidx for classzone_idx is more consistent way than previous approach because system's memory layout doesn't affect anything to it. With this patch, both classzone_idx on above example will be 3 so will have the same min watermark. allocation initiated on node 0: 750 + 4096 = 4846 allocation initiated on node 1: 750 + 4096 = 4846 Reported-by: Ye Xiaolong Tested-by: Ye Xiaolong Signed-off-by: Joonsoo Kim --- mm/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/internal.h b/mm/internal.h index 228dd66..e1d7376 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -123,7 +123,7 @@ struct alloc_context { bool spread_dirty_pages; }; -#define ac_classzone_idx(ac) zonelist_zone_idx(ac->preferred_zoneref) +#define ac_classzone_idx(ac) (ac->high_zoneidx) /* * Locate the struct page for both the matching buddy in our -- 2.7.4
Re: serial: start_tx & buffer handling
On Fri, May 4, 2018 at 12:04 AM, Greg KH wrote: > On Thu, May 03, 2018 at 08:08:48PM +0530, Muni Sekhar wrote: >> Hi All, >> >> I’m trying to understand how user mode buffer is written to low level >> serial hardware registers. >> >> For this I read the kernel code and I came to know that from user mode >> write() API lands into kernel’s tty_write() ("drivers/tty/tty_io.c") >> and then it calls a uart_write() ("drivers/tty/serial/serial_core.c"). >> >> In uart_write(), the buffer is copied to circ_buf and then it calls >> low level serial hardware driver’s start_tx() (struct uart_ops >> .start_tx). But here I could not find how the buffer kept in circ_buf >> is copied to serial port’s TX_FIFO registers? >> >> Can someone take a moment to explain me on this? > > It all depends on which specific UART driver you are looking at, they > all do it a bit different depending on the hardware. > > Which one are you looking at? Look at what the start_tx callback does > for that specific driver, that should give you a hint as to how data > starts flowing. Usually an interrupt is enabled that is used to flush > the buffer out to the hardware. > I’m looking for any existing sample code which does DMA transfers of UART transmitted data. I looked at the bcm63xx_uart.c, it looks it does not handle DMA transfers. Even copying the Tx buffer (from circ_buf) to UART_FIFO_REG happening in ISR. > thanks, > > greg k-h -- Thanks, Sekhar
Re: [PATCH 1/9] R3Di and SBZ quirk entires + alt firmware loading
Sorry for sending these twice, I made a formatting mistake in the first series, and they would not apply properly. Hopefully these do not show up as spam because of this. I went through and fixed them all individually and re-committed them, but kept the same commit messages. I still have a lot to learn. Thanks, Connor On Fri, May 4, 2018 at 12:19 AM, Connor McAdamswrote: > This patch adds PCI quirk ID's for the Sound Blaster Z and Recon3Di. > Only the currently tested ID's have been added. > > This patch also adds the ability to load alternative firmwares for each > card, the firmwares can be obtained from within the Windows driver. > The Recon3Di uses "ctefx-r3di.bin" and the Sound Blaster Z uses > "ctefx-sbz.bin". If the alternative firmware for the given quirk is not > found, the original ctefx.bin will be used. This has been confirmed to > work for both the R3Di and the SBZ. > > This patch also makes the character array *dirstr a const. > > Signed-off-by: Connor McAdams > --- > sound/pci/hda/patch_ca0132.c | 61 > +++- > 1 file changed, 55 insertions(+), 6 deletions(-) > > diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c > index 768ea86..8346100 100644 > --- a/sound/pci/hda/patch_ca0132.c > +++ b/sound/pci/hda/patch_ca0132.c > @@ -72,12 +72,16 @@ > #define SCP_GET1 > > #define EFX_FILE "ctefx.bin" > +#define SBZ_EFX_FILE "ctefx-sbz.bin" > +#define R3DI_EFX_FILE "ctefx-r3di.bin" > > #ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP > MODULE_FIRMWARE(EFX_FILE); > +MODULE_FIRMWARE(SBZ_EFX_FILE); > +MODULE_FIRMWARE(R3DI_EFX_FILE); > #endif > > -static char *dirstr[2] = { "Playback", "Capture" }; > +static const char *dirstr[2] = { "Playback", "Capture" }; > > enum { > SPEAKER_OUT, > @@ -734,6 +738,7 @@ struct ca0132_spec { > unsigned int scp_resp_header; > unsigned int scp_resp_data[4]; > unsigned int scp_resp_count; > + bool alt_firmware_present; > > /* mixer and effects related */ > unsigned char dmic_ctl; > @@ -762,6 +767,8 @@ struct ca0132_spec { > enum { > QUIRK_NONE, > QUIRK_ALIENWARE, > + QUIRK_SBZ, > + QUIRK_R3DI, > }; > > static const struct hda_pintbl alienware_pincfgs[] = { > @@ -782,6 +789,10 @@ static const struct snd_pci_quirk ca0132_quirks[] = { > SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), > SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), > SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", > QUIRK_ALIENWARE), > + SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ), > + SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ), > + SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), > + SND_PCI_QUIRK(0x1458, 0xA036, "Recon3Di", QUIRK_R3DI), > {} > }; > > @@ -3207,7 +3218,7 @@ static int ca0132_select_out(struct hda_codec *codec) > pin_ctl & ~PIN_HP); > /* enable speaker node */ > pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, > -AC_VERB_GET_PIN_WIDGET_CONTROL, > 0); > + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); > snd_hda_set_pin_ctl(codec, spec->out_pins[0], > pin_ctl | PIN_OUT); > } else { > @@ -4370,11 +4381,49 @@ static void ca0132_set_dsp_msr(struct hda_codec > *codec, bool is96k) > static bool ca0132_download_dsp_images(struct hda_codec *codec) > { > bool dsp_loaded = false; > + struct ca0132_spec *spec = codec->spec; > const struct dsp_image_seg *dsp_os_image; > const struct firmware *fw_entry; > - > - if (request_firmware(_entry, EFX_FILE, codec->card->dev) != 0) > - return false; > + /* > +* Alternate firmwares for different variants. The Recon3Di apparently > +* can use the default firmware, but I'll leave the option in case > +* it needs it again. > +*/ > + switch (spec->quirk) { > + case QUIRK_SBZ: > + if (request_firmware(_entry, SBZ_EFX_FILE, > + codec->card->dev) != 0) { > + codec_dbg(codec, "SBZ alt firmware not detected. "); > + spec->alt_firmware_present = false; > + } else { > + codec_dbg(codec, "Sound Blaster Z firmware > selected."); > + spec->alt_firmware_present = true; > + } > + break; > + case QUIRK_R3DI: > + if (request_firmware(_entry, R3DI_EFX_FILE, > + codec->card->dev) != 0) { > + codec_dbg(codec, "Recon3Di alt firmware not > detected."); > +
Re: [PATCH 1/9] R3Di and SBZ quirk entires + alt firmware loading
Sorry for sending these twice, I made a formatting mistake in the first series, and they would not apply properly. Hopefully these do not show up as spam because of this. I went through and fixed them all individually and re-committed them, but kept the same commit messages. I still have a lot to learn. Thanks, Connor On Fri, May 4, 2018 at 12:19 AM, Connor McAdams wrote: > This patch adds PCI quirk ID's for the Sound Blaster Z and Recon3Di. > Only the currently tested ID's have been added. > > This patch also adds the ability to load alternative firmwares for each > card, the firmwares can be obtained from within the Windows driver. > The Recon3Di uses "ctefx-r3di.bin" and the Sound Blaster Z uses > "ctefx-sbz.bin". If the alternative firmware for the given quirk is not > found, the original ctefx.bin will be used. This has been confirmed to > work for both the R3Di and the SBZ. > > This patch also makes the character array *dirstr a const. > > Signed-off-by: Connor McAdams > --- > sound/pci/hda/patch_ca0132.c | 61 > +++- > 1 file changed, 55 insertions(+), 6 deletions(-) > > diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c > index 768ea86..8346100 100644 > --- a/sound/pci/hda/patch_ca0132.c > +++ b/sound/pci/hda/patch_ca0132.c > @@ -72,12 +72,16 @@ > #define SCP_GET1 > > #define EFX_FILE "ctefx.bin" > +#define SBZ_EFX_FILE "ctefx-sbz.bin" > +#define R3DI_EFX_FILE "ctefx-r3di.bin" > > #ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP > MODULE_FIRMWARE(EFX_FILE); > +MODULE_FIRMWARE(SBZ_EFX_FILE); > +MODULE_FIRMWARE(R3DI_EFX_FILE); > #endif > > -static char *dirstr[2] = { "Playback", "Capture" }; > +static const char *dirstr[2] = { "Playback", "Capture" }; > > enum { > SPEAKER_OUT, > @@ -734,6 +738,7 @@ struct ca0132_spec { > unsigned int scp_resp_header; > unsigned int scp_resp_data[4]; > unsigned int scp_resp_count; > + bool alt_firmware_present; > > /* mixer and effects related */ > unsigned char dmic_ctl; > @@ -762,6 +767,8 @@ struct ca0132_spec { > enum { > QUIRK_NONE, > QUIRK_ALIENWARE, > + QUIRK_SBZ, > + QUIRK_R3DI, > }; > > static const struct hda_pintbl alienware_pincfgs[] = { > @@ -782,6 +789,10 @@ static const struct snd_pci_quirk ca0132_quirks[] = { > SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), > SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), > SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", > QUIRK_ALIENWARE), > + SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ), > + SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ), > + SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), > + SND_PCI_QUIRK(0x1458, 0xA036, "Recon3Di", QUIRK_R3DI), > {} > }; > > @@ -3207,7 +3218,7 @@ static int ca0132_select_out(struct hda_codec *codec) > pin_ctl & ~PIN_HP); > /* enable speaker node */ > pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, > -AC_VERB_GET_PIN_WIDGET_CONTROL, > 0); > + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); > snd_hda_set_pin_ctl(codec, spec->out_pins[0], > pin_ctl | PIN_OUT); > } else { > @@ -4370,11 +4381,49 @@ static void ca0132_set_dsp_msr(struct hda_codec > *codec, bool is96k) > static bool ca0132_download_dsp_images(struct hda_codec *codec) > { > bool dsp_loaded = false; > + struct ca0132_spec *spec = codec->spec; > const struct dsp_image_seg *dsp_os_image; > const struct firmware *fw_entry; > - > - if (request_firmware(_entry, EFX_FILE, codec->card->dev) != 0) > - return false; > + /* > +* Alternate firmwares for different variants. The Recon3Di apparently > +* can use the default firmware, but I'll leave the option in case > +* it needs it again. > +*/ > + switch (spec->quirk) { > + case QUIRK_SBZ: > + if (request_firmware(_entry, SBZ_EFX_FILE, > + codec->card->dev) != 0) { > + codec_dbg(codec, "SBZ alt firmware not detected. "); > + spec->alt_firmware_present = false; > + } else { > + codec_dbg(codec, "Sound Blaster Z firmware > selected."); > + spec->alt_firmware_present = true; > + } > + break; > + case QUIRK_R3DI: > + if (request_firmware(_entry, R3DI_EFX_FILE, > + codec->card->dev) != 0) { > + codec_dbg(codec, "Recon3Di alt firmware not > detected."); > + spec->alt_firmware_present = false; > + }
Re: [PATCH] memcg, hugetlb: pages allocated for hugetlb's overcommit will be charged to memcg
On 05/03/2018 05:09 PM, TSUKADA Koutaro wrote: > On 2018/05/03 11:33, Mike Kravetz wrote: >> On 05/01/2018 11:54 PM, TSUKADA Koutaro wrote: >>> On 2018/05/02 13:41, Mike Kravetz wrote: What is the reason for not charging pages at allocation/reserve time? I am not an expert in memcg accounting, but I would think the pages should be charged at allocation time. Otherwise, a task could allocate a large number of (reserved) pages that are not charged to a memcg. memcg charges in other code paths seem to happen at huge page allocation time. >>> >>> If we charge to memcg at page allocation time, the new page is not yet >>> registered in rmap, so it will be accounted as 'cache' inside the memcg. >>> Then, >>> after being registered in rmap, memcg will account as 'RSS' if the task >>> moves >>> cgroup, so I am worried about the possibility of inconsistency in statistics >>> (memory.stat). >>> >>> As you said, in this patch, there may be a problem that a memory leak occurs >>> due to unused pages after being reserved. >>> > This patch targets RHELSA(kernel-alt-4.11.0-45.6.1.el7a.src.rpm). It would be very helpful to rebase this patch on a recent mainline kernel. The code to allocate surplus huge pages has been significantly changed in recent kernels. I have no doubt that this is a real issue and we are not correctly charging surplus to a memcg. But your patch will be hard to evaluate when based on an older distro kernel. >>> I apologize for the patch of the old kernel. The patch was rewritten >>> for 4.17-rc2(6d08b06). >> >> Thank you very much for rebasing the patch. >> >> I did not look closely at your patch until now. My first thought was that >> you were changing/expanding the existing accounting. However, it appears >> that you want to account for hugetlb surplus pages in the memory cgroup. >> Is there any reason why the hugetlb cgroup resource controller does not meet >> your needs? It a quick look at the code, it does appear to handle surplus >> pages correctly. > > Yes, basically it is exactly what you are talking about, but my usage is > somewhat special. I would like users who submit jobs on the HPC cluster to use > the hugetlb page. When submitting a job, the user specifies a memory resource > (for example, sbatch --mem in slurm). > > If the user specifies 10GB, we assume that the system administrator has set > the > limit of 10GB for memory cgroup and hugetlb cgroup respectively, and does not > create a hugetlb pool and sets it so that can overcommit. Then, users can use > 10GB normal pages and more 10GB hugetlb page by overcommitting, which means > user can use 20GB totaly. However, the administrator should restrict the > normal > page and hugetlb page to 10GB in total. > > Since it is difficult to estimate the ratio used by user of normal pages and > hugetlb pages, setting limits of 2 GB to memory cgroup and 8 GB to hugetlb > cgroup is not very good idea. > > In such a case, with my patch, I thought that the administrator can manage the > resources just by setting 10GB for the limit of memory cgoup(No limit is set > for hugetlb cgroup). Thank you for the explanation of your use case. I now understand what you were trying to accomplish with your patch. Your use case reminds me of the session at LSFMM titled "swap accounting". https://lwn.net/Articles/753162/ I hope someone with more cgroup expertise (Johannes? Aneesh?) can provide comments. My experience in that area is limited. One question that comes to mind is "Why would the user/application writer use hugetlbfs overcommit instead of THP?". For hugetlbfs overcommit, they need to be prepared for huge page allocations to fail. So, in some cases they may not be able to use any hugetlbfs pages. This is not much different than THP. However, in the THP case huge page allocation failures and fall back to base pages is transparent to the user. With THP, the normal memory cgroup controller should work well. -- Mike Kravetz
Re: [PATCH] memcg, hugetlb: pages allocated for hugetlb's overcommit will be charged to memcg
On 05/03/2018 05:09 PM, TSUKADA Koutaro wrote: > On 2018/05/03 11:33, Mike Kravetz wrote: >> On 05/01/2018 11:54 PM, TSUKADA Koutaro wrote: >>> On 2018/05/02 13:41, Mike Kravetz wrote: What is the reason for not charging pages at allocation/reserve time? I am not an expert in memcg accounting, but I would think the pages should be charged at allocation time. Otherwise, a task could allocate a large number of (reserved) pages that are not charged to a memcg. memcg charges in other code paths seem to happen at huge page allocation time. >>> >>> If we charge to memcg at page allocation time, the new page is not yet >>> registered in rmap, so it will be accounted as 'cache' inside the memcg. >>> Then, >>> after being registered in rmap, memcg will account as 'RSS' if the task >>> moves >>> cgroup, so I am worried about the possibility of inconsistency in statistics >>> (memory.stat). >>> >>> As you said, in this patch, there may be a problem that a memory leak occurs >>> due to unused pages after being reserved. >>> > This patch targets RHELSA(kernel-alt-4.11.0-45.6.1.el7a.src.rpm). It would be very helpful to rebase this patch on a recent mainline kernel. The code to allocate surplus huge pages has been significantly changed in recent kernels. I have no doubt that this is a real issue and we are not correctly charging surplus to a memcg. But your patch will be hard to evaluate when based on an older distro kernel. >>> I apologize for the patch of the old kernel. The patch was rewritten >>> for 4.17-rc2(6d08b06). >> >> Thank you very much for rebasing the patch. >> >> I did not look closely at your patch until now. My first thought was that >> you were changing/expanding the existing accounting. However, it appears >> that you want to account for hugetlb surplus pages in the memory cgroup. >> Is there any reason why the hugetlb cgroup resource controller does not meet >> your needs? It a quick look at the code, it does appear to handle surplus >> pages correctly. > > Yes, basically it is exactly what you are talking about, but my usage is > somewhat special. I would like users who submit jobs on the HPC cluster to use > the hugetlb page. When submitting a job, the user specifies a memory resource > (for example, sbatch --mem in slurm). > > If the user specifies 10GB, we assume that the system administrator has set > the > limit of 10GB for memory cgroup and hugetlb cgroup respectively, and does not > create a hugetlb pool and sets it so that can overcommit. Then, users can use > 10GB normal pages and more 10GB hugetlb page by overcommitting, which means > user can use 20GB totaly. However, the administrator should restrict the > normal > page and hugetlb page to 10GB in total. > > Since it is difficult to estimate the ratio used by user of normal pages and > hugetlb pages, setting limits of 2 GB to memory cgroup and 8 GB to hugetlb > cgroup is not very good idea. > > In such a case, with my patch, I thought that the administrator can manage the > resources just by setting 10GB for the limit of memory cgoup(No limit is set > for hugetlb cgroup). Thank you for the explanation of your use case. I now understand what you were trying to accomplish with your patch. Your use case reminds me of the session at LSFMM titled "swap accounting". https://lwn.net/Articles/753162/ I hope someone with more cgroup expertise (Johannes? Aneesh?) can provide comments. My experience in that area is limited. One question that comes to mind is "Why would the user/application writer use hugetlbfs overcommit instead of THP?". For hugetlbfs overcommit, they need to be prepared for huge page allocations to fail. So, in some cases they may not be able to use any hugetlbfs pages. This is not much different than THP. However, in the THP case huge page allocation failures and fall back to base pages is transparent to the user. With THP, the normal memory cgroup controller should work well. -- Mike Kravetz
[PATCH 1/9] R3Di and SBZ quirk entires + alt firmware loading
This patch adds PCI quirk ID's for the Sound Blaster Z and Recon3Di. Only the currently tested ID's have been added. This patch also adds the ability to load alternative firmwares for each card, the firmwares can be obtained from within the Windows driver. The Recon3Di uses "ctefx-r3di.bin" and the Sound Blaster Z uses "ctefx-sbz.bin". If the alternative firmware for the given quirk is not found, the original ctefx.bin will be used. This has been confirmed to work for both the R3Di and the SBZ. This patch also makes the character array *dirstr a const. Signed-off-by: Connor McAdams--- sound/pci/hda/patch_ca0132.c | 61 +++- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 768ea86..8346100 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -72,12 +72,16 @@ #define SCP_GET1 #define EFX_FILE "ctefx.bin" +#define SBZ_EFX_FILE "ctefx-sbz.bin" +#define R3DI_EFX_FILE "ctefx-r3di.bin" #ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP MODULE_FIRMWARE(EFX_FILE); +MODULE_FIRMWARE(SBZ_EFX_FILE); +MODULE_FIRMWARE(R3DI_EFX_FILE); #endif -static char *dirstr[2] = { "Playback", "Capture" }; +static const char *dirstr[2] = { "Playback", "Capture" }; enum { SPEAKER_OUT, @@ -734,6 +738,7 @@ struct ca0132_spec { unsigned int scp_resp_header; unsigned int scp_resp_data[4]; unsigned int scp_resp_count; + bool alt_firmware_present; /* mixer and effects related */ unsigned char dmic_ctl; @@ -762,6 +767,8 @@ struct ca0132_spec { enum { QUIRK_NONE, QUIRK_ALIENWARE, + QUIRK_SBZ, + QUIRK_R3DI, }; static const struct hda_pintbl alienware_pincfgs[] = { @@ -782,6 +789,10 @@ static const struct snd_pci_quirk ca0132_quirks[] = { SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE), + SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ), + SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ), + SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), + SND_PCI_QUIRK(0x1458, 0xA036, "Recon3Di", QUIRK_R3DI), {} }; @@ -3207,7 +3218,7 @@ static int ca0132_select_out(struct hda_codec *codec) pin_ctl & ~PIN_HP); /* enable speaker node */ pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, -AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); snd_hda_set_pin_ctl(codec, spec->out_pins[0], pin_ctl | PIN_OUT); } else { @@ -4370,11 +4381,49 @@ static void ca0132_set_dsp_msr(struct hda_codec *codec, bool is96k) static bool ca0132_download_dsp_images(struct hda_codec *codec) { bool dsp_loaded = false; + struct ca0132_spec *spec = codec->spec; const struct dsp_image_seg *dsp_os_image; const struct firmware *fw_entry; - - if (request_firmware(_entry, EFX_FILE, codec->card->dev) != 0) - return false; + /* +* Alternate firmwares for different variants. The Recon3Di apparently +* can use the default firmware, but I'll leave the option in case +* it needs it again. +*/ + switch (spec->quirk) { + case QUIRK_SBZ: + if (request_firmware(_entry, SBZ_EFX_FILE, + codec->card->dev) != 0) { + codec_dbg(codec, "SBZ alt firmware not detected. "); + spec->alt_firmware_present = false; + } else { + codec_dbg(codec, "Sound Blaster Z firmware selected."); + spec->alt_firmware_present = true; + } + break; + case QUIRK_R3DI: + if (request_firmware(_entry, R3DI_EFX_FILE, + codec->card->dev) != 0) { + codec_dbg(codec, "Recon3Di alt firmware not detected."); + spec->alt_firmware_present = false; + } else { + codec_dbg(codec, "Recon3Di firmware selected."); + spec->alt_firmware_present = true; + } + break; + default: + spec->alt_firmware_present = false; + break; + } + /* +* Use default ctefx.bin if no alt firmware is detected, or if none +* exists for your particular codec. +*/ + if (!spec->alt_firmware_present) { + codec_dbg(codec, "Default firmware selected."); + if
[PATCH 1/9] R3Di and SBZ quirk entires + alt firmware loading
This patch adds PCI quirk ID's for the Sound Blaster Z and Recon3Di. Only the currently tested ID's have been added. This patch also adds the ability to load alternative firmwares for each card, the firmwares can be obtained from within the Windows driver. The Recon3Di uses "ctefx-r3di.bin" and the Sound Blaster Z uses "ctefx-sbz.bin". If the alternative firmware for the given quirk is not found, the original ctefx.bin will be used. This has been confirmed to work for both the R3Di and the SBZ. This patch also makes the character array *dirstr a const. Signed-off-by: Connor McAdams --- sound/pci/hda/patch_ca0132.c | 61 +++- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 768ea86..8346100 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -72,12 +72,16 @@ #define SCP_GET1 #define EFX_FILE "ctefx.bin" +#define SBZ_EFX_FILE "ctefx-sbz.bin" +#define R3DI_EFX_FILE "ctefx-r3di.bin" #ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP MODULE_FIRMWARE(EFX_FILE); +MODULE_FIRMWARE(SBZ_EFX_FILE); +MODULE_FIRMWARE(R3DI_EFX_FILE); #endif -static char *dirstr[2] = { "Playback", "Capture" }; +static const char *dirstr[2] = { "Playback", "Capture" }; enum { SPEAKER_OUT, @@ -734,6 +738,7 @@ struct ca0132_spec { unsigned int scp_resp_header; unsigned int scp_resp_data[4]; unsigned int scp_resp_count; + bool alt_firmware_present; /* mixer and effects related */ unsigned char dmic_ctl; @@ -762,6 +767,8 @@ struct ca0132_spec { enum { QUIRK_NONE, QUIRK_ALIENWARE, + QUIRK_SBZ, + QUIRK_R3DI, }; static const struct hda_pintbl alienware_pincfgs[] = { @@ -782,6 +789,10 @@ static const struct snd_pci_quirk ca0132_quirks[] = { SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE), + SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ), + SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ), + SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), + SND_PCI_QUIRK(0x1458, 0xA036, "Recon3Di", QUIRK_R3DI), {} }; @@ -3207,7 +3218,7 @@ static int ca0132_select_out(struct hda_codec *codec) pin_ctl & ~PIN_HP); /* enable speaker node */ pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, -AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); snd_hda_set_pin_ctl(codec, spec->out_pins[0], pin_ctl | PIN_OUT); } else { @@ -4370,11 +4381,49 @@ static void ca0132_set_dsp_msr(struct hda_codec *codec, bool is96k) static bool ca0132_download_dsp_images(struct hda_codec *codec) { bool dsp_loaded = false; + struct ca0132_spec *spec = codec->spec; const struct dsp_image_seg *dsp_os_image; const struct firmware *fw_entry; - - if (request_firmware(_entry, EFX_FILE, codec->card->dev) != 0) - return false; + /* +* Alternate firmwares for different variants. The Recon3Di apparently +* can use the default firmware, but I'll leave the option in case +* it needs it again. +*/ + switch (spec->quirk) { + case QUIRK_SBZ: + if (request_firmware(_entry, SBZ_EFX_FILE, + codec->card->dev) != 0) { + codec_dbg(codec, "SBZ alt firmware not detected. "); + spec->alt_firmware_present = false; + } else { + codec_dbg(codec, "Sound Blaster Z firmware selected."); + spec->alt_firmware_present = true; + } + break; + case QUIRK_R3DI: + if (request_firmware(_entry, R3DI_EFX_FILE, + codec->card->dev) != 0) { + codec_dbg(codec, "Recon3Di alt firmware not detected."); + spec->alt_firmware_present = false; + } else { + codec_dbg(codec, "Recon3Di firmware selected."); + spec->alt_firmware_present = true; + } + break; + default: + spec->alt_firmware_present = false; + break; + } + /* +* Use default ctefx.bin if no alt firmware is detected, or if none +* exists for your particular codec. +*/ + if (!spec->alt_firmware_present) { + codec_dbg(codec, "Default firmware selected."); + if (request_firmware(_entry, EFX_FILE, +
[PATCH 2/9] Add pincfg for SBZ + R3Di, add fp hp auto-detect
This patch adds an unsolicited response tag for the front headphone panel which uses the same hp_callback as the rear headphone detection. This patch also adds pincfgs for the R3Di and SBZ which were taken from the Windows driver. The pins are also defined in the function ca0132_config. Both the R3Di and SBZ are also given a max out channel value of 6 to handle 5.1 surround sound in later patches. Signed-off-by: Connor McAdams--- sound/pci/hda/patch_ca0132.c | 111 +-- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 8346100..02238fe 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -723,6 +723,7 @@ struct ca0132_spec { hda_nid_t shared_mic_nid; hda_nid_t shared_out_nid; hda_nid_t unsol_tag_hp; + hda_nid_t unsol_tag_front_hp; /* for desktop ca0132 codecs */ hda_nid_t unsol_tag_amic1; /* chip access */ @@ -785,6 +786,36 @@ static const struct hda_pintbl alienware_pincfgs[] = { {} }; +/* Sound Blaster Z pin configs taken from Windows Driver */ +static const struct hda_pintbl sbz_pincfgs[] = { + { 0x0b, 0x01017010 }, /* Port G -- Lineout FRONT L/R */ + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */ + { 0x0d, 0x014510f0 }, /* Digital Out */ + { 0x0e, 0x01c510f0 }, /* SPDIF In */ + { 0x0f, 0x0221701f }, /* Port A -- BackPanel HP */ + { 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */ + { 0x11, 0x01017014 }, /* Port B -- LineMicIn2 / Rear L/R */ + { 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */ + { 0x13, 0x908700f0 }, /* What U Hear In*/ + { 0x18, 0x50d000f0 }, /* N/A */ + {} +}; + +/* Recon3D integrated pin configs taken from Windows Driver */ +static const struct hda_pintbl r3di_pincfgs[] = { + { 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */ + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */ + { 0x0d, 0x014510f0 }, /* Digital Out */ + { 0x0e, 0x41c520f0 }, /* SPDIF In */ + { 0x0f, 0x0221401f }, /* Port A -- BackPanel HP */ + { 0x10, 0x01016011 }, /* Port D -- Center/LFE or FP Hp */ + { 0x11, 0x01011014 }, /* Port B -- LineMicIn2 / Rear L/R */ + { 0x12, 0x02a090f0 }, /* Port C -- LineIn1 */ + { 0x13, 0x908700f0 }, /* What U Hear In*/ + { 0x18, 0x50f0 }, /* N/A */ + {} +}; + static const struct snd_pci_quirk ca0132_quirks[] = { SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), @@ -4503,6 +4534,10 @@ static void ca0132_init_unsol(struct hda_codec *codec) amic_callback); snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP, ca0132_process_dsp_response); + /* Front headphone jack detection */ + if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3DI) + snd_hda_jack_detect_enable_callback(codec, + spec->unsol_tag_front_hp, hp_callback); } /* @@ -4684,9 +4719,14 @@ static void ca0132_config(struct hda_codec *codec) spec->multiout.dac_nids = spec->dacs; spec->multiout.num_dacs = 3; - spec->multiout.max_channels = 2; - if (spec->quirk == QUIRK_ALIENWARE) { + if (spec->quirk == QUIRK_NONE || spec->quirk == QUIRK_ALIENWARE) + spec->multiout.max_channels = 2; + else + spec->multiout.max_channels = 6; + + switch (spec->quirk) { + case QUIRK_ALIENWARE: codec_dbg(codec, "ca0132_config: QUIRK_ALIENWARE applied.\n"); snd_hda_apply_pincfgs(codec, alienware_pincfgs); @@ -4706,7 +4746,71 @@ static void ca0132_config(struct hda_codec *codec) spec->input_pins[2] = 0x13; spec->shared_mic_nid = 0x7; spec->unsol_tag_amic1 = 0x11; - } else { + break; + case QUIRK_SBZ: + codec_dbg(codec, "%s: QUIRK_SBZ applied.\n", __func__); + snd_hda_apply_pincfgs(codec, sbz_pincfgs); + + spec->num_outputs = 2; + spec->out_pins[0] = 0x0B; /* Line out */ + spec->out_pins[1] = 0x0F; /* Rear headphone out */ + spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/ + spec->out_pins[3] = 0x11; /* Rear surround */ + spec->shared_out_nid = 0x2; + spec->unsol_tag_hp = spec->out_pins[1]; + spec->unsol_tag_front_hp = spec->out_pins[2]; + + spec->adcs[0] = 0x7; /* Rear Mic / Line-in */ + spec->adcs[1] = 0x8; /* Front Mic, but only if no DSP */ + spec->adcs[2] = 0xa; /* what u hear */ + + spec->num_inputs = 2; + spec->input_pins[0] = 0x12; /*
[PATCH 2/9] Add pincfg for SBZ + R3Di, add fp hp auto-detect
This patch adds an unsolicited response tag for the front headphone panel which uses the same hp_callback as the rear headphone detection. This patch also adds pincfgs for the R3Di and SBZ which were taken from the Windows driver. The pins are also defined in the function ca0132_config. Both the R3Di and SBZ are also given a max out channel value of 6 to handle 5.1 surround sound in later patches. Signed-off-by: Connor McAdams --- sound/pci/hda/patch_ca0132.c | 111 +-- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 8346100..02238fe 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -723,6 +723,7 @@ struct ca0132_spec { hda_nid_t shared_mic_nid; hda_nid_t shared_out_nid; hda_nid_t unsol_tag_hp; + hda_nid_t unsol_tag_front_hp; /* for desktop ca0132 codecs */ hda_nid_t unsol_tag_amic1; /* chip access */ @@ -785,6 +786,36 @@ static const struct hda_pintbl alienware_pincfgs[] = { {} }; +/* Sound Blaster Z pin configs taken from Windows Driver */ +static const struct hda_pintbl sbz_pincfgs[] = { + { 0x0b, 0x01017010 }, /* Port G -- Lineout FRONT L/R */ + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */ + { 0x0d, 0x014510f0 }, /* Digital Out */ + { 0x0e, 0x01c510f0 }, /* SPDIF In */ + { 0x0f, 0x0221701f }, /* Port A -- BackPanel HP */ + { 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */ + { 0x11, 0x01017014 }, /* Port B -- LineMicIn2 / Rear L/R */ + { 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */ + { 0x13, 0x908700f0 }, /* What U Hear In*/ + { 0x18, 0x50d000f0 }, /* N/A */ + {} +}; + +/* Recon3D integrated pin configs taken from Windows Driver */ +static const struct hda_pintbl r3di_pincfgs[] = { + { 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */ + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */ + { 0x0d, 0x014510f0 }, /* Digital Out */ + { 0x0e, 0x41c520f0 }, /* SPDIF In */ + { 0x0f, 0x0221401f }, /* Port A -- BackPanel HP */ + { 0x10, 0x01016011 }, /* Port D -- Center/LFE or FP Hp */ + { 0x11, 0x01011014 }, /* Port B -- LineMicIn2 / Rear L/R */ + { 0x12, 0x02a090f0 }, /* Port C -- LineIn1 */ + { 0x13, 0x908700f0 }, /* What U Hear In*/ + { 0x18, 0x50f0 }, /* N/A */ + {} +}; + static const struct snd_pci_quirk ca0132_quirks[] = { SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), @@ -4503,6 +4534,10 @@ static void ca0132_init_unsol(struct hda_codec *codec) amic_callback); snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP, ca0132_process_dsp_response); + /* Front headphone jack detection */ + if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3DI) + snd_hda_jack_detect_enable_callback(codec, + spec->unsol_tag_front_hp, hp_callback); } /* @@ -4684,9 +4719,14 @@ static void ca0132_config(struct hda_codec *codec) spec->multiout.dac_nids = spec->dacs; spec->multiout.num_dacs = 3; - spec->multiout.max_channels = 2; - if (spec->quirk == QUIRK_ALIENWARE) { + if (spec->quirk == QUIRK_NONE || spec->quirk == QUIRK_ALIENWARE) + spec->multiout.max_channels = 2; + else + spec->multiout.max_channels = 6; + + switch (spec->quirk) { + case QUIRK_ALIENWARE: codec_dbg(codec, "ca0132_config: QUIRK_ALIENWARE applied.\n"); snd_hda_apply_pincfgs(codec, alienware_pincfgs); @@ -4706,7 +4746,71 @@ static void ca0132_config(struct hda_codec *codec) spec->input_pins[2] = 0x13; spec->shared_mic_nid = 0x7; spec->unsol_tag_amic1 = 0x11; - } else { + break; + case QUIRK_SBZ: + codec_dbg(codec, "%s: QUIRK_SBZ applied.\n", __func__); + snd_hda_apply_pincfgs(codec, sbz_pincfgs); + + spec->num_outputs = 2; + spec->out_pins[0] = 0x0B; /* Line out */ + spec->out_pins[1] = 0x0F; /* Rear headphone out */ + spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/ + spec->out_pins[3] = 0x11; /* Rear surround */ + spec->shared_out_nid = 0x2; + spec->unsol_tag_hp = spec->out_pins[1]; + spec->unsol_tag_front_hp = spec->out_pins[2]; + + spec->adcs[0] = 0x7; /* Rear Mic / Line-in */ + spec->adcs[1] = 0x8; /* Front Mic, but only if no DSP */ + spec->adcs[2] = 0xa; /* what u hear */ + + spec->num_inputs = 2; + spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */ +
[PATCH 4/9] Add extra exit functions for R3Di and SBZ
This patch adds extra functions for shutdown on the Sound Blaster Z and Recon3Di. The Recon3Di only has one specific functions, which sets the GPIO data pins to 0 to prevent a popping noise. The Sound Blaster Z exit sequence was taken from Windows. Without this exit function, the card will not reload properly unless the PC has been shutdown to clear the onboard memory. There are commented out functions currently in the sbz_exit_chip function that are added in a later patch. Also, a reboot notify function has been added, to make sure these functions are ran before a reboot. This helps when using the card through VFIO in a virtual machine, to make sure the card reloads the DSP properly. Signed-off-by: Connor McAdams--- sound/pci/hda/patch_ca0132.c | 126 +++ 1 file changed, 126 insertions(+) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 68e5122..3fbbb85 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4641,6 +4641,121 @@ static void ca0132_init_chip(struct hda_codec *codec) #endif } +/* + * Recon3Di exit specific commands. + */ +/* prevents popping noise on shutdown */ +static void r3di_gpio_shutdown(struct hda_codec *codec) +{ + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0x00); +} + +/* + * Sound Blaster Z exit specific commands. + */ +static void sbz_region2_exit(struct hda_codec *codec) +{ + struct ca0132_spec *spec = codec->spec; + unsigned int i; + + for (i = 0; i < 4; i++) + writeb(0x0, spec->mem_base + 0x100); + for (i = 0; i < 8; i++) + writeb(0xb3, spec->mem_base + 0x304); + /* +* I believe these are GPIO, with the right most hex digit being the +* gpio pin, and the second digit being on or off. We see this more in +* the input/output select functions. +*/ + writew(0x, spec->mem_base + 0x320); + writew(0x0001, spec->mem_base + 0x320); + writew(0x0104, spec->mem_base + 0x320); + writew(0x0005, spec->mem_base + 0x320); + writew(0x0007, spec->mem_base + 0x320); +} + +static void sbz_set_pin_ctl_default(struct hda_codec *codec) +{ + hda_nid_t pins[5] = {0x0B, 0x0C, 0x0E, 0x12, 0x13}; + unsigned int i; + + snd_hda_codec_write(codec, 0x11, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40); + + for (i = 0; i < 5; i++) + snd_hda_codec_write(codec, pins[i], 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00); +} + +static void sbz_clear_unsolicited(struct hda_codec *codec) +{ + hda_nid_t pins[7] = {0x0B, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13}; + unsigned int i; + + for (i = 0; i < 7; i++) { + snd_hda_codec_write(codec, pins[i], 0, + AC_VERB_SET_UNSOLICITED_ENABLE, 0x00); + } +} + +/* On shutdown, sends commands in sets of three */ +static void sbz_gpio_shutdown_commands(struct hda_codec *codec, int dir, + int mask, int data) +{ + if (dir >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_DIRECTION, dir); + if (mask >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_MASK, mask); + + if (data >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_DATA, data); +} + +static void sbz_exit_chip(struct hda_codec *codec) +{ + /* added in later patch. */ +// chipio_set_stream_control(codec, 0x03, 0); +// chipio_set_stream_control(codec, 0x04, 0); + + /* Mess with GPIO */ + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, -1); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x05); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x01); + +// chipio_set_stream_control(codec, 0x14, 0); +// chipio_set_stream_control(codec, 0x0C, 0); + + chipio_set_conn_rate(codec, 0x41, SR_192_000); + chipio_set_conn_rate(codec, 0x91, SR_192_000); + + chipio_write(codec, 0x18a020, 0x0083); + + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x03); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x07); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x06); + +// chipio_set_stream_control(codec, 0x0C, 0); + + chipio_set_control_param(codec, 0x0D, 0x24); + + sbz_clear_unsolicited(codec); + sbz_set_pin_ctl_default(codec); + + snd_hda_codec_write(codec, 0x0B, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + + if (dspload_is_loaded(codec)) + dsp_reset(codec); + + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x00); + + sbz_region2_exit(codec); +} + static void ca0132_exit_chip(struct hda_codec
[PATCH 4/9] Add extra exit functions for R3Di and SBZ
This patch adds extra functions for shutdown on the Sound Blaster Z and Recon3Di. The Recon3Di only has one specific functions, which sets the GPIO data pins to 0 to prevent a popping noise. The Sound Blaster Z exit sequence was taken from Windows. Without this exit function, the card will not reload properly unless the PC has been shutdown to clear the onboard memory. There are commented out functions currently in the sbz_exit_chip function that are added in a later patch. Also, a reboot notify function has been added, to make sure these functions are ran before a reboot. This helps when using the card through VFIO in a virtual machine, to make sure the card reloads the DSP properly. Signed-off-by: Connor McAdams --- sound/pci/hda/patch_ca0132.c | 126 +++ 1 file changed, 126 insertions(+) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 68e5122..3fbbb85 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4641,6 +4641,121 @@ static void ca0132_init_chip(struct hda_codec *codec) #endif } +/* + * Recon3Di exit specific commands. + */ +/* prevents popping noise on shutdown */ +static void r3di_gpio_shutdown(struct hda_codec *codec) +{ + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0x00); +} + +/* + * Sound Blaster Z exit specific commands. + */ +static void sbz_region2_exit(struct hda_codec *codec) +{ + struct ca0132_spec *spec = codec->spec; + unsigned int i; + + for (i = 0; i < 4; i++) + writeb(0x0, spec->mem_base + 0x100); + for (i = 0; i < 8; i++) + writeb(0xb3, spec->mem_base + 0x304); + /* +* I believe these are GPIO, with the right most hex digit being the +* gpio pin, and the second digit being on or off. We see this more in +* the input/output select functions. +*/ + writew(0x, spec->mem_base + 0x320); + writew(0x0001, spec->mem_base + 0x320); + writew(0x0104, spec->mem_base + 0x320); + writew(0x0005, spec->mem_base + 0x320); + writew(0x0007, spec->mem_base + 0x320); +} + +static void sbz_set_pin_ctl_default(struct hda_codec *codec) +{ + hda_nid_t pins[5] = {0x0B, 0x0C, 0x0E, 0x12, 0x13}; + unsigned int i; + + snd_hda_codec_write(codec, 0x11, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40); + + for (i = 0; i < 5; i++) + snd_hda_codec_write(codec, pins[i], 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00); +} + +static void sbz_clear_unsolicited(struct hda_codec *codec) +{ + hda_nid_t pins[7] = {0x0B, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13}; + unsigned int i; + + for (i = 0; i < 7; i++) { + snd_hda_codec_write(codec, pins[i], 0, + AC_VERB_SET_UNSOLICITED_ENABLE, 0x00); + } +} + +/* On shutdown, sends commands in sets of three */ +static void sbz_gpio_shutdown_commands(struct hda_codec *codec, int dir, + int mask, int data) +{ + if (dir >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_DIRECTION, dir); + if (mask >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_MASK, mask); + + if (data >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_DATA, data); +} + +static void sbz_exit_chip(struct hda_codec *codec) +{ + /* added in later patch. */ +// chipio_set_stream_control(codec, 0x03, 0); +// chipio_set_stream_control(codec, 0x04, 0); + + /* Mess with GPIO */ + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, -1); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x05); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x01); + +// chipio_set_stream_control(codec, 0x14, 0); +// chipio_set_stream_control(codec, 0x0C, 0); + + chipio_set_conn_rate(codec, 0x41, SR_192_000); + chipio_set_conn_rate(codec, 0x91, SR_192_000); + + chipio_write(codec, 0x18a020, 0x0083); + + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x03); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x07); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x06); + +// chipio_set_stream_control(codec, 0x0C, 0); + + chipio_set_control_param(codec, 0x0D, 0x24); + + sbz_clear_unsolicited(codec); + sbz_set_pin_ctl_default(codec); + + snd_hda_codec_write(codec, 0x0B, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + + if (dspload_is_loaded(codec)) + dsp_reset(codec); + + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x00); + + sbz_region2_exit(codec); +} + static void ca0132_exit_chip(struct hda_codec *codec) { /* put
[PATCH 5/9] add/change helper functions for R3Di and SBZ
Edit core functions to support the Sound Blaster Z and Recon3Di for startup and loading of the DSP, as well as setting effects. Signed-off-by: Connor McAdams--- sound/pci/hda/patch_ca0132.c | 1070 -- 1 file changed, 1018 insertions(+), 52 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 3fbbb85..0641c47 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -45,6 +45,7 @@ #define FLOAT_ZERO 0x #define FLOAT_ONE 0x3f80 #define FLOAT_TWO 0x4000 +#define FLOAT_THREE 0x4040 #define FLOAT_MINUS_5 0xc0a0 #define UNSOL_TAG_DSP 0x16 @@ -710,6 +711,7 @@ struct ca0132_spec { const struct hda_verb *base_init_verbs; const struct hda_verb *base_exit_verbs; const struct hda_verb *chip_init_verbs; + const struct hda_verb *sbz_init_verbs; struct hda_verb *spec_init_verbs; struct auto_pin_cfg autocfg; @@ -743,6 +745,8 @@ struct ca0132_spec { unsigned int scp_resp_data[4]; unsigned int scp_resp_count; bool alt_firmware_present; + bool startup_check_entered; + bool dsp_reload; /* mixer and effects related */ unsigned char dmic_ctl; @@ -768,6 +772,13 @@ struct ca0132_spec { * switching, and other unknown commands. */ void __iomem *mem_base; + + /* +* Whether or not to use the alt functions like alt_select_out, +* alt_select_in, etc. Only used on desktop codecs for now, because of +* surround sound support. +*/ + bool use_alt_functions; }; /* @@ -1015,6 +1026,29 @@ static int chipio_write(struct hda_codec *codec, } /* + * Write given value to the given address through the chip I/O widget. + * not protected by the Mutex + */ +static int chipio_write_no_mutex(struct hda_codec *codec, + unsigned int chip_addx, const unsigned int data) +{ + int err; + + + /* write the address, and if successful proceed to write data */ + err = chipio_write_address(codec, chip_addx); + if (err < 0) + goto exit; + + err = chipio_write_data(codec, data); + if (err < 0) + goto exit; + +exit: + return err; +} + +/* * Write multiple values to the given address through the chip I/O widget. * protected by the Mutex */ @@ -1108,6 +1142,81 @@ static void chipio_set_control_param(struct hda_codec *codec, } /* + * Set chip parameters through the chip I/O widget. NO MUTEX. + */ +static void chipio_set_control_param_no_mutex(struct hda_codec *codec, + enum control_param_id param_id, int param_val) +{ + int val; + + if ((param_id < 32) && (param_val < 8)) { + val = (param_val << 5) | (param_id); + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_SET, val); + } else { + if (chipio_send(codec, VENDOR_CHIPIO_STATUS, 0) == 0) { + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_EX_ID_SET, + param_id); + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_EX_VALUE_SET, + param_val); + } + } +} +/* + * Connect stream to a source point, and then connect + * that source point to a destination point. + */ +static void chipio_set_stream_source_dest(struct hda_codec *codec, + int streamid, int source_point, int dest_point) +{ + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_ID, streamid); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_SOURCE_CONN_POINT, source_point); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_DEST_CONN_POINT, dest_point); +} + +/* + * Set number of channels in the selected stream. + */ +static void chipio_set_stream_channels(struct hda_codec *codec, + int streamid, unsigned int channels) +{ + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_ID, streamid); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAMS_CHANNELS, channels); +} + +/* + * Enable/Disable audio stream. + */ +static void chipio_set_stream_control(struct hda_codec *codec, + int streamid, int enable) +{ + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_ID, streamid); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_CONTROL, enable); +} + + +/* +
[PATCH 5/9] add/change helper functions for R3Di and SBZ
Edit core functions to support the Sound Blaster Z and Recon3Di for startup and loading of the DSP, as well as setting effects. Signed-off-by: Connor McAdams --- sound/pci/hda/patch_ca0132.c | 1070 -- 1 file changed, 1018 insertions(+), 52 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 3fbbb85..0641c47 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -45,6 +45,7 @@ #define FLOAT_ZERO 0x #define FLOAT_ONE 0x3f80 #define FLOAT_TWO 0x4000 +#define FLOAT_THREE 0x4040 #define FLOAT_MINUS_5 0xc0a0 #define UNSOL_TAG_DSP 0x16 @@ -710,6 +711,7 @@ struct ca0132_spec { const struct hda_verb *base_init_verbs; const struct hda_verb *base_exit_verbs; const struct hda_verb *chip_init_verbs; + const struct hda_verb *sbz_init_verbs; struct hda_verb *spec_init_verbs; struct auto_pin_cfg autocfg; @@ -743,6 +745,8 @@ struct ca0132_spec { unsigned int scp_resp_data[4]; unsigned int scp_resp_count; bool alt_firmware_present; + bool startup_check_entered; + bool dsp_reload; /* mixer and effects related */ unsigned char dmic_ctl; @@ -768,6 +772,13 @@ struct ca0132_spec { * switching, and other unknown commands. */ void __iomem *mem_base; + + /* +* Whether or not to use the alt functions like alt_select_out, +* alt_select_in, etc. Only used on desktop codecs for now, because of +* surround sound support. +*/ + bool use_alt_functions; }; /* @@ -1015,6 +1026,29 @@ static int chipio_write(struct hda_codec *codec, } /* + * Write given value to the given address through the chip I/O widget. + * not protected by the Mutex + */ +static int chipio_write_no_mutex(struct hda_codec *codec, + unsigned int chip_addx, const unsigned int data) +{ + int err; + + + /* write the address, and if successful proceed to write data */ + err = chipio_write_address(codec, chip_addx); + if (err < 0) + goto exit; + + err = chipio_write_data(codec, data); + if (err < 0) + goto exit; + +exit: + return err; +} + +/* * Write multiple values to the given address through the chip I/O widget. * protected by the Mutex */ @@ -1108,6 +1142,81 @@ static void chipio_set_control_param(struct hda_codec *codec, } /* + * Set chip parameters through the chip I/O widget. NO MUTEX. + */ +static void chipio_set_control_param_no_mutex(struct hda_codec *codec, + enum control_param_id param_id, int param_val) +{ + int val; + + if ((param_id < 32) && (param_val < 8)) { + val = (param_val << 5) | (param_id); + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_SET, val); + } else { + if (chipio_send(codec, VENDOR_CHIPIO_STATUS, 0) == 0) { + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_EX_ID_SET, + param_id); + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_EX_VALUE_SET, + param_val); + } + } +} +/* + * Connect stream to a source point, and then connect + * that source point to a destination point. + */ +static void chipio_set_stream_source_dest(struct hda_codec *codec, + int streamid, int source_point, int dest_point) +{ + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_ID, streamid); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_SOURCE_CONN_POINT, source_point); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_DEST_CONN_POINT, dest_point); +} + +/* + * Set number of channels in the selected stream. + */ +static void chipio_set_stream_channels(struct hda_codec *codec, + int streamid, unsigned int channels) +{ + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_ID, streamid); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAMS_CHANNELS, channels); +} + +/* + * Enable/Disable audio stream. + */ +static void chipio_set_stream_control(struct hda_codec *codec, + int streamid, int enable) +{ + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_ID, streamid); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_CONTROL, enable); +} + + +/* + * Set sampling rate of
[PATCH 6/9] add alt_select_in/out for R3Di + SBZ
Add functions ca0132_alt_select_out and ca0132_alt_select_in for switching outputs and inputs for r3di and sbz. Also, add enumerated controls for selecting output and input source. Signed-off-by: Connor McAdams--- sound/pci/hda/patch_ca0132.c | 597 +-- 1 file changed, 572 insertions(+), 25 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 0641c47..6e217ab 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -46,6 +46,7 @@ #define FLOAT_ONE 0x3f80 #define FLOAT_TWO 0x4000 #define FLOAT_THREE 0x4040 +#define FLOAT_EIGHT 0x4100 #define FLOAT_MINUS_5 0xc0a0 #define UNSOL_TAG_DSP 0x16 @@ -87,9 +88,11 @@ MODULE_FIRMWARE(R3DI_EFX_FILE); static const char *dirstr[2] = { "Playback", "Capture" }; +#define NUM_OF_OUTPUTS 3 enum { SPEAKER_OUT, - HEADPHONE_OUT + HEADPHONE_OUT, + SURROUND_OUT }; enum { @@ -97,6 +100,15 @@ enum { LINE_MIC_IN }; +/* Strings for Input Source Enum Control */ +static const char *in_src_str[3] = {"Rear Mic", "Line", "Front Mic" }; +#define IN_SRC_NUM_OF_INPUTS 3 +enum { + REAR_MIC, + REAR_LINE_IN, + FRONT_MIC, +}; + enum { #define VNODE_START_NID0x80 VNID_SPK = VNODE_START_NID, /* Speaker vnid */ @@ -130,7 +142,9 @@ enum { VOICEFX = IN_EFFECT_END_NID, PLAY_ENHANCEMENT, CRYSTAL_VOICE, - EFFECT_END_NID + EFFECT_END_NID, + OUTPUT_SOURCE_ENUM, + INPUT_SOURCE_ENUM #define EFFECTS_COUNT (EFFECT_END_NID - EFFECT_START_NID) }; @@ -480,6 +494,49 @@ static struct ct_voicefx_preset ca0132_voicefx_presets[] = { } }; +/* DSP command sequences for ca0132_alt_select_out */ +#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */ +struct ca0132_alt_out_set { + char *name; /*preset name*/ + unsigned char commands; + unsigned int mids[ALT_OUT_SET_MAX_COMMANDS]; + unsigned int reqs[ALT_OUT_SET_MAX_COMMANDS]; + unsigned int vals[ALT_OUT_SET_MAX_COMMANDS]; +}; + +static struct ca0132_alt_out_set alt_out_presets[] = { + { .name = "Line Out", + .commands = 7, + .mids = { 0x96, 0x96, 0x96, 0x8F, + 0x96, 0x96, 0x96 }, + .reqs = { 0x19, 0x17, 0x18, 0x01, + 0x1F, 0x15, 0x3A }, + .vals = { 0x3F00, 0x42A0, 0x, + 0x, 0x, 0x, + 0x } + }, + { .name = "Headphone", + .commands = 7, + .mids = { 0x96, 0x96, 0x96, 0x8F, + 0x96, 0x96, 0x96 }, + .reqs = { 0x19, 0x17, 0x18, 0x01, + 0x1F, 0x15, 0x3A }, + .vals = { 0x3F00, 0x42A0, 0x, + 0x, 0x, 0x, + 0x } + }, + { .name = "Surround", + .commands = 8, + .mids = { 0x96, 0x8F, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96 }, + .reqs = { 0x18, 0x01, 0x1F, 0x15, + 0x3A, 0x1A, 0x1B, 0x1C }, + .vals = { 0x, 0x, 0x, + 0x, 0x, 0x, + 0x, 0x } + } +}; + enum hda_cmd_vendor_io { /* for DspIO node */ VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000, @@ -759,6 +816,9 @@ struct ca0132_spec { long effects_switch[EFFECTS_COUNT]; long voicefx_val; long cur_mic_boost; + /* ca0132_alt control related values */ + unsigned char in_enum_val; + unsigned char out_enum_val; struct hda_codec *codec; struct delayed_work unsol_hp_work; @@ -2954,15 +3014,14 @@ enum r3di_dsp_status { /* Set GPIO bit 4 to 1 once DSP is downloaded */ R3DI_DSP_DOWNLOADED = 1 }; -/* Not used until next patch in series */ -/* + static void r3di_gpio_mic_set(struct hda_codec *codec, enum r3di_mic_select cur_mic) { unsigned int cur_gpio; -*/ /* Get the current GPIO Data setup */ -/* cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); + /* Get the current GPIO Data setup */ + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); switch (cur_mic) { case R3DI_REAR_MIC: @@ -2981,8 +3040,8 @@ static void r3di_gpio_out_set(struct hda_codec *codec, { unsigned int cur_gpio; -*/ /* Get the current GPIO Data setup */ -/* cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); + /* Get the current GPIO Data setup */ + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); switch (cur_out) { case R3DI_HEADPHONE_OUT: @@ -2995,7 +3054,7 @@ static void r3di_gpio_out_set(struct hda_codec *codec,
[PATCH 6/9] add alt_select_in/out for R3Di + SBZ
Add functions ca0132_alt_select_out and ca0132_alt_select_in for switching outputs and inputs for r3di and sbz. Also, add enumerated controls for selecting output and input source. Signed-off-by: Connor McAdams --- sound/pci/hda/patch_ca0132.c | 597 +-- 1 file changed, 572 insertions(+), 25 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 0641c47..6e217ab 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -46,6 +46,7 @@ #define FLOAT_ONE 0x3f80 #define FLOAT_TWO 0x4000 #define FLOAT_THREE 0x4040 +#define FLOAT_EIGHT 0x4100 #define FLOAT_MINUS_5 0xc0a0 #define UNSOL_TAG_DSP 0x16 @@ -87,9 +88,11 @@ MODULE_FIRMWARE(R3DI_EFX_FILE); static const char *dirstr[2] = { "Playback", "Capture" }; +#define NUM_OF_OUTPUTS 3 enum { SPEAKER_OUT, - HEADPHONE_OUT + HEADPHONE_OUT, + SURROUND_OUT }; enum { @@ -97,6 +100,15 @@ enum { LINE_MIC_IN }; +/* Strings for Input Source Enum Control */ +static const char *in_src_str[3] = {"Rear Mic", "Line", "Front Mic" }; +#define IN_SRC_NUM_OF_INPUTS 3 +enum { + REAR_MIC, + REAR_LINE_IN, + FRONT_MIC, +}; + enum { #define VNODE_START_NID0x80 VNID_SPK = VNODE_START_NID, /* Speaker vnid */ @@ -130,7 +142,9 @@ enum { VOICEFX = IN_EFFECT_END_NID, PLAY_ENHANCEMENT, CRYSTAL_VOICE, - EFFECT_END_NID + EFFECT_END_NID, + OUTPUT_SOURCE_ENUM, + INPUT_SOURCE_ENUM #define EFFECTS_COUNT (EFFECT_END_NID - EFFECT_START_NID) }; @@ -480,6 +494,49 @@ static struct ct_voicefx_preset ca0132_voicefx_presets[] = { } }; +/* DSP command sequences for ca0132_alt_select_out */ +#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */ +struct ca0132_alt_out_set { + char *name; /*preset name*/ + unsigned char commands; + unsigned int mids[ALT_OUT_SET_MAX_COMMANDS]; + unsigned int reqs[ALT_OUT_SET_MAX_COMMANDS]; + unsigned int vals[ALT_OUT_SET_MAX_COMMANDS]; +}; + +static struct ca0132_alt_out_set alt_out_presets[] = { + { .name = "Line Out", + .commands = 7, + .mids = { 0x96, 0x96, 0x96, 0x8F, + 0x96, 0x96, 0x96 }, + .reqs = { 0x19, 0x17, 0x18, 0x01, + 0x1F, 0x15, 0x3A }, + .vals = { 0x3F00, 0x42A0, 0x, + 0x, 0x, 0x, + 0x } + }, + { .name = "Headphone", + .commands = 7, + .mids = { 0x96, 0x96, 0x96, 0x8F, + 0x96, 0x96, 0x96 }, + .reqs = { 0x19, 0x17, 0x18, 0x01, + 0x1F, 0x15, 0x3A }, + .vals = { 0x3F00, 0x42A0, 0x, + 0x, 0x, 0x, + 0x } + }, + { .name = "Surround", + .commands = 8, + .mids = { 0x96, 0x8F, 0x96, 0x96, + 0x96, 0x96, 0x96, 0x96 }, + .reqs = { 0x18, 0x01, 0x1F, 0x15, + 0x3A, 0x1A, 0x1B, 0x1C }, + .vals = { 0x, 0x, 0x, + 0x, 0x, 0x, + 0x, 0x } + } +}; + enum hda_cmd_vendor_io { /* for DspIO node */ VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000, @@ -759,6 +816,9 @@ struct ca0132_spec { long effects_switch[EFFECTS_COUNT]; long voicefx_val; long cur_mic_boost; + /* ca0132_alt control related values */ + unsigned char in_enum_val; + unsigned char out_enum_val; struct hda_codec *codec; struct delayed_work unsol_hp_work; @@ -2954,15 +3014,14 @@ enum r3di_dsp_status { /* Set GPIO bit 4 to 1 once DSP is downloaded */ R3DI_DSP_DOWNLOADED = 1 }; -/* Not used until next patch in series */ -/* + static void r3di_gpio_mic_set(struct hda_codec *codec, enum r3di_mic_select cur_mic) { unsigned int cur_gpio; -*/ /* Get the current GPIO Data setup */ -/* cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); + /* Get the current GPIO Data setup */ + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); switch (cur_mic) { case R3DI_REAR_MIC: @@ -2981,8 +3040,8 @@ static void r3di_gpio_out_set(struct hda_codec *codec, { unsigned int cur_gpio; -*/ /* Get the current GPIO Data setup */ -/* cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); + /* Get the current GPIO Data setup */ + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); switch (cur_out) { case R3DI_HEADPHONE_OUT: @@ -2995,7 +3054,7 @@ static void r3di_gpio_out_set(struct hda_codec *codec,
[PATCH 8/9] add ca0132_alt_set_vipsource
Add function to set vipsource on cards that use_alt_controls. Different sequence. Also, add cvoice_switch_set at end of ca0132_select_in so that when switching between inputs cvoice state is maintained. Signed-off-by: Connor McAdams--- sound/pci/hda/patch_ca0132.c | 71 +++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index c0303c9..77a7704 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -3978,6 +3978,71 @@ static int ca0132_set_vipsource(struct hda_codec *codec, int val) return 1; } +static int ca0132_alt_set_vipsource(struct hda_codec *codec, int val) +{ + struct ca0132_spec *spec = codec->spec; + unsigned int tmp; + + if (spec->dsp_state != DSP_DOWNLOADED) + return 0; + + codec_dbg(codec, "%s\n", __func__); + + chipio_set_stream_control(codec, 0x03, 0); + chipio_set_stream_control(codec, 0x04, 0); + + /* if CrystalVoice is off, vipsource should be 0 */ + if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] || + (val == 0) || spec->in_enum_val == REAR_LINE_IN) { + codec_dbg(codec, "%s: off.", __func__); + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0); + + tmp = FLOAT_ZERO; + dspio_set_uint_param(codec, 0x80, 0x05, tmp); + + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); + if (spec->quirk == QUIRK_R3DI) + chipio_set_conn_rate(codec, 0x0F, SR_96_000); + + + if (spec->in_enum_val == REAR_LINE_IN) + tmp = FLOAT_ZERO; + else { + if (spec->quirk == QUIRK_SBZ) + tmp = FLOAT_THREE; + else + tmp = FLOAT_ONE; + } + + dspio_set_uint_param(codec, 0x80, 0x00, tmp); + + } else { + codec_dbg(codec, "%s: on.", __func__); + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000); + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000); + if (spec->quirk == QUIRK_R3DI) + chipio_set_conn_rate(codec, 0x0F, SR_16_000); + + if (spec->effects_switch[VOICE_FOCUS - EFFECT_START_NID]) + tmp = FLOAT_TWO; + else + tmp = FLOAT_ONE; + dspio_set_uint_param(codec, 0x80, 0x00, tmp); + + tmp = FLOAT_ONE; + dspio_set_uint_param(codec, 0x80, 0x05, tmp); + + msleep(20); + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val); + } + + chipio_set_stream_control(codec, 0x03, 1); + chipio_set_stream_control(codec, 0x04, 1); + + return 1; +} + /* * Select the active microphone. * If autodetect is enabled, mic will be selected based on jack detection. @@ -4140,6 +4205,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec) } break; } + ca0132_cvoice_switch_set(codec); snd_hda_power_down_pm(codec); return 0; @@ -4353,7 +4419,10 @@ static int ca0132_cvoice_switch_set(struct hda_codec *codec) /* set correct vipsource */ oldval = stop_mic1(codec); - ret |= ca0132_set_vipsource(codec, 1); + if (spec->use_alt_functions) + ret |= ca0132_alt_set_vipsource(codec, 1); + else + ret |= ca0132_set_vipsource(codec, 1); resume_mic1(codec, oldval); return ret; } -- 2.7.4
[PATCH 8/9] add ca0132_alt_set_vipsource
Add function to set vipsource on cards that use_alt_controls. Different sequence. Also, add cvoice_switch_set at end of ca0132_select_in so that when switching between inputs cvoice state is maintained. Signed-off-by: Connor McAdams --- sound/pci/hda/patch_ca0132.c | 71 +++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index c0303c9..77a7704 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -3978,6 +3978,71 @@ static int ca0132_set_vipsource(struct hda_codec *codec, int val) return 1; } +static int ca0132_alt_set_vipsource(struct hda_codec *codec, int val) +{ + struct ca0132_spec *spec = codec->spec; + unsigned int tmp; + + if (spec->dsp_state != DSP_DOWNLOADED) + return 0; + + codec_dbg(codec, "%s\n", __func__); + + chipio_set_stream_control(codec, 0x03, 0); + chipio_set_stream_control(codec, 0x04, 0); + + /* if CrystalVoice is off, vipsource should be 0 */ + if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] || + (val == 0) || spec->in_enum_val == REAR_LINE_IN) { + codec_dbg(codec, "%s: off.", __func__); + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0); + + tmp = FLOAT_ZERO; + dspio_set_uint_param(codec, 0x80, 0x05, tmp); + + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); + if (spec->quirk == QUIRK_R3DI) + chipio_set_conn_rate(codec, 0x0F, SR_96_000); + + + if (spec->in_enum_val == REAR_LINE_IN) + tmp = FLOAT_ZERO; + else { + if (spec->quirk == QUIRK_SBZ) + tmp = FLOAT_THREE; + else + tmp = FLOAT_ONE; + } + + dspio_set_uint_param(codec, 0x80, 0x00, tmp); + + } else { + codec_dbg(codec, "%s: on.", __func__); + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000); + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000); + if (spec->quirk == QUIRK_R3DI) + chipio_set_conn_rate(codec, 0x0F, SR_16_000); + + if (spec->effects_switch[VOICE_FOCUS - EFFECT_START_NID]) + tmp = FLOAT_TWO; + else + tmp = FLOAT_ONE; + dspio_set_uint_param(codec, 0x80, 0x00, tmp); + + tmp = FLOAT_ONE; + dspio_set_uint_param(codec, 0x80, 0x05, tmp); + + msleep(20); + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val); + } + + chipio_set_stream_control(codec, 0x03, 1); + chipio_set_stream_control(codec, 0x04, 1); + + return 1; +} + /* * Select the active microphone. * If autodetect is enabled, mic will be selected based on jack detection. @@ -4140,6 +4205,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec) } break; } + ca0132_cvoice_switch_set(codec); snd_hda_power_down_pm(codec); return 0; @@ -4353,7 +4419,10 @@ static int ca0132_cvoice_switch_set(struct hda_codec *codec) /* set correct vipsource */ oldval = stop_mic1(codec); - ret |= ca0132_set_vipsource(codec, 1); + if (spec->use_alt_functions) + ret |= ca0132_alt_set_vipsource(codec, 1); + else + ret |= ca0132_set_vipsource(codec, 1); resume_mic1(codec, oldval); return ret; } -- 2.7.4