Re: [GIT PULL] tpmdd fixes for Linux 4.8
On Tue, 19 Jul 2016, Jarkko Sakkinen wrote: > James, > > This pull contains fixes for found regressions and TPM2 support for the > Nuvoton driver. The changes are rebased against the latest > security/next. > > /Jarkko > > The following changes since commit d4d03f74a73f3b8b2801d4d02011b6b69778cbcc: > > apparmor: fix arg_size computation for when setprocattr is null terminated > (2016-07-12 08:43:10 -0700) > > are available in the git repository at: > > git://git.infradead.org/users/jjs/linux-tpmdd.git tags/tpmdd-next-20160719 > > for you to fetch changes up to 82cc1a49b6358394938e759dc4c22b2be773bbad: > > tpm: Add TPM 2.0 support to the Nuvoton i2c driver (NPCT6xx family) > (2016-07-19 17:43:38 +0300) > Pulled, thanks. -- James Morris <jmor...@namei.org>
Re: [GIT PULL] tpmdd fixes for Linux 4.8
On Tue, 19 Jul 2016, Jarkko Sakkinen wrote: > James, > > This pull contains fixes for found regressions and TPM2 support for the > Nuvoton driver. The changes are rebased against the latest > security/next. > > /Jarkko > > The following changes since commit d4d03f74a73f3b8b2801d4d02011b6b69778cbcc: > > apparmor: fix arg_size computation for when setprocattr is null terminated > (2016-07-12 08:43:10 -0700) > > are available in the git repository at: > > git://git.infradead.org/users/jjs/linux-tpmdd.git tags/tpmdd-next-20160719 > > for you to fetch changes up to 82cc1a49b6358394938e759dc4c22b2be773bbad: > > tpm: Add TPM 2.0 support to the Nuvoton i2c driver (NPCT6xx family) > (2016-07-19 17:43:38 +0300) > Pulled, thanks. -- James Morris
Re: [REDO PATCH v7] perf/x86/amd/power: Add AMD accumulated power reporting mechanism
On Tue, Jul 19, 2016 at 02:22:36PM -0400, Vince Weaver wrote: > On Fri, 17 Jun 2016, Huang Rui wrote: > > > On Thu, Jun 16, 2016 at 06:47:00PM +0200, Borislav Petkov wrote: > > > On Thu, Jun 16, 2016 at 01:38:14PM +0800, Huang Rui wrote: > > > > I was told this feature would be supported on fam15h 60h, 70h and > > > > later processors before. Just checked the fam16h model 30h BKDG, yes, > > > > it should be also supported. But I didn't test that platform, if you > > > > confirm it works in your side. We can enable it. > > > > > > You might want to ask around first whether F16M30's acc power machinery > > > is even usable? I.e., no errata and whatnot... > > > > > > > Yep, I already asked the designers, and was waiting for their > > feedbacks. > > Was there ever any feedback about any of the problems encountered with AMD > APM support? > Vince, apology to late response. We are drafting the erratum for this feature. Will let you know if it is public. Thanks, Rui
Re: [REDO PATCH v7] perf/x86/amd/power: Add AMD accumulated power reporting mechanism
On Tue, Jul 19, 2016 at 02:22:36PM -0400, Vince Weaver wrote: > On Fri, 17 Jun 2016, Huang Rui wrote: > > > On Thu, Jun 16, 2016 at 06:47:00PM +0200, Borislav Petkov wrote: > > > On Thu, Jun 16, 2016 at 01:38:14PM +0800, Huang Rui wrote: > > > > I was told this feature would be supported on fam15h 60h, 70h and > > > > later processors before. Just checked the fam16h model 30h BKDG, yes, > > > > it should be also supported. But I didn't test that platform, if you > > > > confirm it works in your side. We can enable it. > > > > > > You might want to ask around first whether F16M30's acc power machinery > > > is even usable? I.e., no errata and whatnot... > > > > > > > Yep, I already asked the designers, and was waiting for their > > feedbacks. > > Was there ever any feedback about any of the problems encountered with AMD > APM support? > Vince, apology to late response. We are drafting the erratum for this feature. Will let you know if it is public. Thanks, Rui
[PATCH] NFC: pn533: Avoid a double free in error handling code
'phy' has been allocated with 'devm_kzalloc', so we should not free it using an explicit 'kfree'. It would result in a double free if the allocation of 'in_buf' fails. Signed-off-by: Christophe JAILLET--- drivers/nfc/pn533/usb.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 8ca0603..33ed78b 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -464,10 +464,8 @@ static int pn533_usb_probe(struct usb_interface *interface, return -ENOMEM; in_buf = kzalloc(in_buf_len, GFP_KERNEL); - if (!in_buf) { - rc = -ENOMEM; - goto out_free_phy; - } + if (!in_buf) + return -ENOMEM; phy->udev = usb_get_dev(interface_to_usbdev(interface)); phy->interface = interface; @@ -554,8 +552,7 @@ error: usb_free_urb(phy->out_urb); usb_put_dev(phy->udev); kfree(in_buf); -out_free_phy: - kfree(phy); + return rc; } -- 2.7.4 --- L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast. https://www.avast.com/antivirus
[PATCH] NFC: pn533: Avoid a double free in error handling code
'phy' has been allocated with 'devm_kzalloc', so we should not free it using an explicit 'kfree'. It would result in a double free if the allocation of 'in_buf' fails. Signed-off-by: Christophe JAILLET --- drivers/nfc/pn533/usb.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 8ca0603..33ed78b 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -464,10 +464,8 @@ static int pn533_usb_probe(struct usb_interface *interface, return -ENOMEM; in_buf = kzalloc(in_buf_len, GFP_KERNEL); - if (!in_buf) { - rc = -ENOMEM; - goto out_free_phy; - } + if (!in_buf) + return -ENOMEM; phy->udev = usb_get_dev(interface_to_usbdev(interface)); phy->interface = interface; @@ -554,8 +552,7 @@ error: usb_free_urb(phy->out_urb); usb_put_dev(phy->udev); kfree(in_buf); -out_free_phy: - kfree(phy); + return rc; } -- 2.7.4 --- L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast. https://www.avast.com/antivirus
linux-next: manual merge of the kvms390 tree with the kvm-arm tree
Hi all, Today's linux-next merge of the kvms390 tree got a conflict in: include/uapi/linux/kvm.h between commit: 2b8ddd9337ee ("KVM: Extend struct kvm_msi to hold a 32-bit device ID") from the kvm-arm tree and commit: 6502a34cfd66 ("KVM: s390: allow user space to handle instr 0x") from the kvms390 tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc include/uapi/linux/kvm.h index 84d9e5f8ab4b,70941f4ab6d8.. --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@@ -867,7 -867,7 +867,8 @@@ struct kvm_ppc_smmu_info #define KVM_CAP_VCPU_ATTRIBUTES 127 #define KVM_CAP_MAX_VCPU_ID 128 #define KVM_CAP_X2APIC_API 129 -#define KVM_CAP_S390_USER_INSTR0 130 +#define KVM_CAP_MSI_DEVID 130 ++#define KVM_CAP_S390_USER_INSTR0 131 #ifdef KVM_CAP_IRQ_ROUTING
linux-next: manual merge of the kvms390 tree with the kvm-arm tree
Hi all, Today's linux-next merge of the kvms390 tree got a conflict in: include/uapi/linux/kvm.h between commit: 2b8ddd9337ee ("KVM: Extend struct kvm_msi to hold a 32-bit device ID") from the kvm-arm tree and commit: 6502a34cfd66 ("KVM: s390: allow user space to handle instr 0x") from the kvms390 tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc include/uapi/linux/kvm.h index 84d9e5f8ab4b,70941f4ab6d8.. --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@@ -867,7 -867,7 +867,8 @@@ struct kvm_ppc_smmu_info #define KVM_CAP_VCPU_ATTRIBUTES 127 #define KVM_CAP_MAX_VCPU_ID 128 #define KVM_CAP_X2APIC_API 129 -#define KVM_CAP_S390_USER_INSTR0 130 +#define KVM_CAP_MSI_DEVID 130 ++#define KVM_CAP_S390_USER_INSTR0 131 #ifdef KVM_CAP_IRQ_ROUTING
[PATCH v2 2/2] mtd: nand: Get rid of needless 'goto'
Using "goto" and "switch" statement only makes it harder to follow control flow and doesn't bring any advantages. Rewrite the code to avoid using "goto". Signed-off-by: Brian NorrisSigned-off-by: Andrey Smirnov --- drivers/mtd/nand/nand_base.c | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bee480f..5316e00 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2122,7 +2122,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, static int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { - int ret = -ENOTSUPP; + int ret; ops->retlen = 0; @@ -2133,24 +2133,18 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, return -EINVAL; } - nand_get_device(mtd, FL_READING); - - switch (ops->mode) { - case MTD_OPS_PLACE_OOB: - case MTD_OPS_AUTO_OOB: - case MTD_OPS_RAW: - break; + if (ops->mode != MTD_OPS_PLACE_OOB && + ops->mode != MTD_OPS_AUTO_OOB && + ops->mode != MTD_OPS_RAW) + return -ENOTSUPP; - default: - goto out; - } + nand_get_device(mtd, FL_READING); if (!ops->datbuf) ret = nand_do_read_oob(mtd, from, ops); else ret = nand_do_read_ops(mtd, from, ops); -out: nand_release_device(mtd); return ret; } -- 2.5.5
[PATCH v2 2/2] mtd: nand: Get rid of needless 'goto'
Using "goto" and "switch" statement only makes it harder to follow control flow and doesn't bring any advantages. Rewrite the code to avoid using "goto". Signed-off-by: Brian Norris Signed-off-by: Andrey Smirnov --- drivers/mtd/nand/nand_base.c | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bee480f..5316e00 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2122,7 +2122,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, static int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { - int ret = -ENOTSUPP; + int ret; ops->retlen = 0; @@ -2133,24 +2133,18 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, return -EINVAL; } - nand_get_device(mtd, FL_READING); - - switch (ops->mode) { - case MTD_OPS_PLACE_OOB: - case MTD_OPS_AUTO_OOB: - case MTD_OPS_RAW: - break; + if (ops->mode != MTD_OPS_PLACE_OOB && + ops->mode != MTD_OPS_AUTO_OOB && + ops->mode != MTD_OPS_RAW) + return -ENOTSUPP; - default: - goto out; - } + nand_get_device(mtd, FL_READING); if (!ops->datbuf) ret = nand_do_read_oob(mtd, from, ops); else ret = nand_do_read_ops(mtd, from, ops); -out: nand_release_device(mtd); return ret; } -- 2.5.5
[PATCH v2 1/2] mtd: nand: Error out if cmd_ctrl() is missing
If no user specified chip->select_chip() function is provided, code in nand_base.c will automatically set this hook to nand_select_chip(), which in turn depends on chip->cmd_ctrl() hook being valid. Not providing both of those functions in NAND controller driver (for example by mistake) will result in a bit cryptic segfault. Same is true for chip->cmdfunc(). To avoid the above scenario change the prototype of nand_set_defaults() to return error code, all the callers to check for it and error out if cmd_ctrl() is not provided. Suggested-by: Brian NorrisSigned-off-by: Andrey Smirnov --- drivers/mtd/nand/nand_base.c | 29 - 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ce7b2ca..bee480f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3114,22 +3114,30 @@ static void nand_shutdown(struct mtd_info *mtd) } /* Set default functions */ -static void nand_set_defaults(struct nand_chip *chip, int busw) +static int nand_set_defaults(struct nand_chip *chip, int busw) { /* check for proper chip_delay setup, set 20us if not */ if (!chip->chip_delay) chip->chip_delay = 20; /* check, if a user supplied command function given */ - if (chip->cmdfunc == NULL) + if (chip->cmdfunc == NULL) { + if (!chip->cmd_ctrl) + goto no_cmd_ctrl; + chip->cmdfunc = nand_command; + } /* check, if a user supplied wait function given */ if (chip->waitfunc == NULL) chip->waitfunc = nand_wait; - if (!chip->select_chip) + if (!chip->select_chip) { + if (!chip->cmd_ctrl) + goto no_cmd_ctrl; + chip->select_chip = nand_select_chip; + } /* set for ONFI nand */ if (!chip->onfi_set_features) @@ -3161,6 +3169,11 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) init_waitqueue_head(>controller->wq); } + return 0; + +no_cmd_ctrl: + pr_err("chip.cmd_ctrl() callback is not provided\n"); + return -EINVAL; } /* Sanitize ONFI strings so we can safely print them */ @@ -3878,9 +3891,13 @@ ident_done: } if (chip->options & NAND_BUSWIDTH_AUTO) { + int ret; + WARN_ON(chip->options & NAND_BUSWIDTH_16); chip->options |= busw; - nand_set_defaults(chip, busw); + ret = nand_set_defaults(chip, busw); + if (ret < 0) + return ERR_PTR(ret); } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { /* * Check, if buswidth is correct. Hardware drivers should set @@ -3998,7 +4015,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, mtd->name = dev_name(mtd->dev.parent); /* Set the default functions */ - nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); + ret = nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); + if (ret < 0) + return ret; /* Read the flash type */ type = nand_get_flash_type(mtd, chip, _maf_id, -- 2.5.5
[PATCH v2 1/2] mtd: nand: Error out if cmd_ctrl() is missing
If no user specified chip->select_chip() function is provided, code in nand_base.c will automatically set this hook to nand_select_chip(), which in turn depends on chip->cmd_ctrl() hook being valid. Not providing both of those functions in NAND controller driver (for example by mistake) will result in a bit cryptic segfault. Same is true for chip->cmdfunc(). To avoid the above scenario change the prototype of nand_set_defaults() to return error code, all the callers to check for it and error out if cmd_ctrl() is not provided. Suggested-by: Brian Norris Signed-off-by: Andrey Smirnov --- drivers/mtd/nand/nand_base.c | 29 - 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ce7b2ca..bee480f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3114,22 +3114,30 @@ static void nand_shutdown(struct mtd_info *mtd) } /* Set default functions */ -static void nand_set_defaults(struct nand_chip *chip, int busw) +static int nand_set_defaults(struct nand_chip *chip, int busw) { /* check for proper chip_delay setup, set 20us if not */ if (!chip->chip_delay) chip->chip_delay = 20; /* check, if a user supplied command function given */ - if (chip->cmdfunc == NULL) + if (chip->cmdfunc == NULL) { + if (!chip->cmd_ctrl) + goto no_cmd_ctrl; + chip->cmdfunc = nand_command; + } /* check, if a user supplied wait function given */ if (chip->waitfunc == NULL) chip->waitfunc = nand_wait; - if (!chip->select_chip) + if (!chip->select_chip) { + if (!chip->cmd_ctrl) + goto no_cmd_ctrl; + chip->select_chip = nand_select_chip; + } /* set for ONFI nand */ if (!chip->onfi_set_features) @@ -3161,6 +3169,11 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) init_waitqueue_head(>controller->wq); } + return 0; + +no_cmd_ctrl: + pr_err("chip.cmd_ctrl() callback is not provided\n"); + return -EINVAL; } /* Sanitize ONFI strings so we can safely print them */ @@ -3878,9 +3891,13 @@ ident_done: } if (chip->options & NAND_BUSWIDTH_AUTO) { + int ret; + WARN_ON(chip->options & NAND_BUSWIDTH_16); chip->options |= busw; - nand_set_defaults(chip, busw); + ret = nand_set_defaults(chip, busw); + if (ret < 0) + return ERR_PTR(ret); } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { /* * Check, if buswidth is correct. Hardware drivers should set @@ -3998,7 +4015,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, mtd->name = dev_name(mtd->dev.parent); /* Set the default functions */ - nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); + ret = nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); + if (ret < 0) + return ret; /* Read the flash type */ type = nand_get_flash_type(mtd, chip, _maf_id, -- 2.5.5
linux-next: manual merge of the kvm-arm tree with the tip tree
Hi all, Today's linux-next merge of the kvm-arm tree got a conflict in: virt/kvm/kvm_main.c between commit: 8c18b2d2d088 ("virt: Convert kvm hotplug to state machine") from the tip tree and commit: 8a39d00670f0 ("KVM: kvm_io_bus: Add kvm_io_bus_get_dev() call") from the kvm-arm tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc virt/kvm/kvm_main.c index fee1f29043f8,bd2eb92c5d0e.. --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@@ -3532,6 -3496,34 +3532,30 @@@ int kvm_io_bus_unregister_dev(struct kv return r; } + struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx, +gpa_t addr) + { + struct kvm_io_bus *bus; + int dev_idx, srcu_idx; + struct kvm_io_device *iodev = NULL; + + srcu_idx = srcu_read_lock(>srcu); + + bus = srcu_dereference(kvm->buses[bus_idx], >srcu); + + dev_idx = kvm_io_bus_get_first_dev(bus, addr, 1); + if (dev_idx < 0) + goto out_unlock; + + iodev = bus->range[dev_idx].dev; + + out_unlock: + srcu_read_unlock(>srcu, srcu_idx); + + return iodev; + } + EXPORT_SYMBOL_GPL(kvm_io_bus_get_dev); + -static struct notifier_block kvm_cpu_notifier = { - .notifier_call = kvm_cpu_hotplug, -}; - static int kvm_debugfs_open(struct inode *inode, struct file *file, int (*get)(void *, u64 *), int (*set)(void *, u64), const char *fmt)
linux-next: manual merge of the kvm-arm tree with the tip tree
Hi all, Today's linux-next merge of the kvm-arm tree got a conflict in: virt/kvm/kvm_main.c between commit: 8c18b2d2d088 ("virt: Convert kvm hotplug to state machine") from the tip tree and commit: 8a39d00670f0 ("KVM: kvm_io_bus: Add kvm_io_bus_get_dev() call") from the kvm-arm tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc virt/kvm/kvm_main.c index fee1f29043f8,bd2eb92c5d0e.. --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@@ -3532,6 -3496,34 +3532,30 @@@ int kvm_io_bus_unregister_dev(struct kv return r; } + struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx, +gpa_t addr) + { + struct kvm_io_bus *bus; + int dev_idx, srcu_idx; + struct kvm_io_device *iodev = NULL; + + srcu_idx = srcu_read_lock(>srcu); + + bus = srcu_dereference(kvm->buses[bus_idx], >srcu); + + dev_idx = kvm_io_bus_get_first_dev(bus, addr, 1); + if (dev_idx < 0) + goto out_unlock; + + iodev = bus->range[dev_idx].dev; + + out_unlock: + srcu_read_unlock(>srcu, srcu_idx); + + return iodev; + } + EXPORT_SYMBOL_GPL(kvm_io_bus_get_dev); + -static struct notifier_block kvm_cpu_notifier = { - .notifier_call = kvm_cpu_hotplug, -}; - static int kvm_debugfs_open(struct inode *inode, struct file *file, int (*get)(void *, u64 *), int (*set)(void *, u64), const char *fmt)
linux-next: manual merge of the kvm-arm tree with the kvm tree
Hi all, Today's linux-next merge of the kvm-arm tree got a conflict in: include/uapi/linux/kvm.h between commit: 3713131345fb ("KVM: x86: add KVM_CAP_X2APIC_API") from the kvm tree and commit: 2b8ddd9337ee ("KVM: Extend struct kvm_msi to hold a 32-bit device ID") from the kvm-arm tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc include/uapi/linux/kvm.h index 4f8030e5b05d,d8c4c324cfae.. --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@@ -866,7 -866,7 +866,8 @@@ struct kvm_ppc_smmu_info #define KVM_CAP_ARM_PMU_V3 126 #define KVM_CAP_VCPU_ATTRIBUTES 127 #define KVM_CAP_MAX_VCPU_ID 128 -#define KVM_CAP_MSI_DEVID 129 +#define KVM_CAP_X2APIC_API 129 ++#define KVM_CAP_MSI_DEVID 130 #ifdef KVM_CAP_IRQ_ROUTING
linux-next: manual merge of the kvm-arm tree with the kvm tree
Hi all, Today's linux-next merge of the kvm-arm tree got a conflict in: include/uapi/linux/kvm.h between commit: 3713131345fb ("KVM: x86: add KVM_CAP_X2APIC_API") from the kvm tree and commit: 2b8ddd9337ee ("KVM: Extend struct kvm_msi to hold a 32-bit device ID") from the kvm-arm tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc include/uapi/linux/kvm.h index 4f8030e5b05d,d8c4c324cfae.. --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@@ -866,7 -866,7 +866,8 @@@ struct kvm_ppc_smmu_info #define KVM_CAP_ARM_PMU_V3 126 #define KVM_CAP_VCPU_ATTRIBUTES 127 #define KVM_CAP_MAX_VCPU_ID 128 -#define KVM_CAP_MSI_DEVID 129 +#define KVM_CAP_X2APIC_API 129 ++#define KVM_CAP_MSI_DEVID 130 #ifdef KVM_CAP_IRQ_ROUTING
[ANNOUNCE] kmod 23
kmod 23 is out: ftp://ftp.kernel.org/pub/linux/utils/kernel/kmod/kmod-23.tar.xz ftp://ftp.kernel.org/pub/linux/utils/kernel/kmod/kmod-23.tar.sign - Improvements: - Don't add comment to modules.devname if it would otherwise be empty to play nice with tools detecting empty files - Allow building with BSD sed, that doesn't have -E flag - Ignore .TOC. symbols in depmod parsing as it's for PPC64 the equivalent of _GLOBAL_OFFSET_TABLE_ - Teach modinfo about PKCS#7 module signatures: it doesn't add any other info besides telling the user the module is signed since kernel doesn't add other info on the module section - Bug fixes - Fix -s and -p compat options to insmod triggering force flag - Fix long lines from /proc/modules not being handled correctly by kmod_module_new_from_loaded() and kmod_module_get_size() and several other library functions that use them - Fix crash on modinfo while checking for available signature of unknown type - Fix documentation generation with gtk-doc Shortlog is below Anton Blanchard (1): depmod: Ignore PowerPC64 ABIv2 .TOC. symbol Héctor Orón Martínez (1): kmod: compiling with old sed version (!ERE support) Josh Triplett (1): depmod: Don't insert comment in modules.devname if otherwise empty Lucas De Marchi (8): travis: workaround bug in environment setup README: add link to patchwork libkmod-module: do not crash modinfo on 0 key id len libkmod-signature: handle PKCS#7 libkmod-module: modinfo: print signature id libkmod: fix integration with gtk-doc NEWS: add items for kmod 23 kmod 23 Marc-Antoine Perennou (1): insmod: fix wron fallthrough of -f Michal Marek (1): libkmod: Handle long lines in /proc/modules Peter Wu (1): kmod_module_get_refcnt: fix documentation Lucas De Marchi
[ANNOUNCE] kmod 23
kmod 23 is out: ftp://ftp.kernel.org/pub/linux/utils/kernel/kmod/kmod-23.tar.xz ftp://ftp.kernel.org/pub/linux/utils/kernel/kmod/kmod-23.tar.sign - Improvements: - Don't add comment to modules.devname if it would otherwise be empty to play nice with tools detecting empty files - Allow building with BSD sed, that doesn't have -E flag - Ignore .TOC. symbols in depmod parsing as it's for PPC64 the equivalent of _GLOBAL_OFFSET_TABLE_ - Teach modinfo about PKCS#7 module signatures: it doesn't add any other info besides telling the user the module is signed since kernel doesn't add other info on the module section - Bug fixes - Fix -s and -p compat options to insmod triggering force flag - Fix long lines from /proc/modules not being handled correctly by kmod_module_new_from_loaded() and kmod_module_get_size() and several other library functions that use them - Fix crash on modinfo while checking for available signature of unknown type - Fix documentation generation with gtk-doc Shortlog is below Anton Blanchard (1): depmod: Ignore PowerPC64 ABIv2 .TOC. symbol Héctor Orón Martínez (1): kmod: compiling with old sed version (!ERE support) Josh Triplett (1): depmod: Don't insert comment in modules.devname if otherwise empty Lucas De Marchi (8): travis: workaround bug in environment setup README: add link to patchwork libkmod-module: do not crash modinfo on 0 key id len libkmod-signature: handle PKCS#7 libkmod-module: modinfo: print signature id libkmod: fix integration with gtk-doc NEWS: add items for kmod 23 kmod 23 Marc-Antoine Perennou (1): insmod: fix wron fallthrough of -f Michal Marek (1): libkmod: Handle long lines in /proc/modules Peter Wu (1): kmod_module_get_refcnt: fix documentation Lucas De Marchi
Re: [PATCH 2/3] xen-scsiback: One function call less in scsiback_device_action() after error detection
On 20/07/16 07:10, SF Markus Elfring wrote: > @@ -606,7 +606,7 @@ static void scsiback_device_action(struct > vscsibk_pend *pending_req, > tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL); > if (!tmr) { > target_put_sess_cmd(se_cmd); > - goto err; > + goto do_resp; > } Hmm, I'm not convinced this is an improvement. I'd rather rename the new error label to "put_cmd" and get rid of the braces in above if statement: - if (!tmr) { - target_put_sess_cmd(se_cmd); - goto err; - } + if (!tmr) + goto put_cmd; and then in the error path: -err: +put_cmd: + target_put_sess_cmd(se_cmd); >>> >>> I am unsure on the relevance of this function on such a source position. >>> Would it make sense to move it further down at the end? >> >> You only want to call it in the first error case (allocation failure). > > Thanks for your clarification. > > I find that my update suggestion (from Saturday) is still appropriate > in this case. > https://lkml.org/lkml/2016/7/16/172 And I still think it isn't an improvement: Nack +free_tmr: kfree(tmr); >>> >>> How do you think about to skip this function call after a memory >>> allocation failure? >> >> I think this just doesn't matter. If it were a hot path, yes. But trying >> to do micro-optimizations in an error path is just not worth the effort. > > Would you like to reduce also the amount of function calls in such special > run-time situations? I just don't care for the extra 2 or 3 nsecs. Readability is more important here. >> I like a linear error path containing all the needed cleanups best. > > I would prefer to keep the discussed single function call within > the basic block of the if statement. > > Have we got different opinions about the shown implementation details? Yes. Juergen
Re: [PATCH 2/3] xen-scsiback: One function call less in scsiback_device_action() after error detection
On 20/07/16 07:10, SF Markus Elfring wrote: > @@ -606,7 +606,7 @@ static void scsiback_device_action(struct > vscsibk_pend *pending_req, > tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL); > if (!tmr) { > target_put_sess_cmd(se_cmd); > - goto err; > + goto do_resp; > } Hmm, I'm not convinced this is an improvement. I'd rather rename the new error label to "put_cmd" and get rid of the braces in above if statement: - if (!tmr) { - target_put_sess_cmd(se_cmd); - goto err; - } + if (!tmr) + goto put_cmd; and then in the error path: -err: +put_cmd: + target_put_sess_cmd(se_cmd); >>> >>> I am unsure on the relevance of this function on such a source position. >>> Would it make sense to move it further down at the end? >> >> You only want to call it in the first error case (allocation failure). > > Thanks for your clarification. > > I find that my update suggestion (from Saturday) is still appropriate > in this case. > https://lkml.org/lkml/2016/7/16/172 And I still think it isn't an improvement: Nack +free_tmr: kfree(tmr); >>> >>> How do you think about to skip this function call after a memory >>> allocation failure? >> >> I think this just doesn't matter. If it were a hot path, yes. But trying >> to do micro-optimizations in an error path is just not worth the effort. > > Would you like to reduce also the amount of function calls in such special > run-time situations? I just don't care for the extra 2 or 3 nsecs. Readability is more important here. >> I like a linear error path containing all the needed cleanups best. > > I would prefer to keep the discussed single function call within > the basic block of the if statement. > > Have we got different opinions about the shown implementation details? Yes. Juergen
linux-next: manual merge of the kvm-arm tree with the tip tree
Hi all, Today's linux-next merge of the kvm-arm tree got a conflict in: include/linux/irqchip/arm-gic-v3.h between commits: 9347359ad0ae ("irqchip/gicv3-its: Split its_alloc_tables() into two functions") 3faf24ea894a ("irqchip/gicv3-its: Implement two-level(indirect) device table support") from the tip tree and commit: 645b9e49a8c0 ("irqchip/gic-v3: Refactor and add GICv3 definitions") from the kvm-arm tree. I fixed it up (see below and I chose ULL over UL in the definition of GITS_BASER_INDIRECT) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc include/linux/irqchip/arm-gic-v3.h index 107eed475b94,700b4216c87a.. --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@@ -229,7 -300,7 +300,8 @@@ #define GITS_BASER_PAGE_SIZE_64K (2UL << GITS_BASER_PAGE_SIZE_SHIFT) #define GITS_BASER_PAGE_SIZE_MASK (3UL << GITS_BASER_PAGE_SIZE_SHIFT) #define GITS_BASER_PAGES_MAX 256 +#define GITS_BASER_PAGES_SHIFT(0) + #define GITS_BASER_NR_PAGES(r)(((r) & 0xff) + 1) #define GITS_BASER_TYPE_NONE 0 #define GITS_BASER_TYPE_DEVICE1
linux-next: manual merge of the kvm-arm tree with the tip tree
Hi all, Today's linux-next merge of the kvm-arm tree got a conflict in: include/linux/irqchip/arm-gic-v3.h between commits: 9347359ad0ae ("irqchip/gicv3-its: Split its_alloc_tables() into two functions") 3faf24ea894a ("irqchip/gicv3-its: Implement two-level(indirect) device table support") from the tip tree and commit: 645b9e49a8c0 ("irqchip/gic-v3: Refactor and add GICv3 definitions") from the kvm-arm tree. I fixed it up (see below and I chose ULL over UL in the definition of GITS_BASER_INDIRECT) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc include/linux/irqchip/arm-gic-v3.h index 107eed475b94,700b4216c87a.. --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@@ -229,7 -300,7 +300,8 @@@ #define GITS_BASER_PAGE_SIZE_64K (2UL << GITS_BASER_PAGE_SIZE_SHIFT) #define GITS_BASER_PAGE_SIZE_MASK (3UL << GITS_BASER_PAGE_SIZE_SHIFT) #define GITS_BASER_PAGES_MAX 256 +#define GITS_BASER_PAGES_SHIFT(0) + #define GITS_BASER_NR_PAGES(r)(((r) & 0xff) + 1) #define GITS_BASER_TYPE_NONE 0 #define GITS_BASER_TYPE_DEVICE1
[PATCH v2] 2c: mv64xxx: Use clk_enable_prepare and clk_disable_unprepare
Replace clk_enable and clk_prepare with clk_enable_prepare and clk_disable and clk_unprepare with clk_disable_unprepare. The Coccinelle semantic patch used to make this change is as follows: @@ expression e; @@ - clk_prepare(e); - clk_enable(e); + clk_prepare_enable(e); @@ expression e; @@ - clk_disable(e); - clk_unprepare(e); + clk_disable_unprepare(e); Signed-off-by: Amitoj Kaur Chawla--- Changes in v2: -Rebased patch drivers/i2c/busses/i2c-mv64xxx.c | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 43207f5..79bae48 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -910,10 +910,8 @@ mv64xxx_i2c_probe(struct platform_device *pd) #if defined(CONFIG_HAVE_CLK) /* Not all platforms have a clk */ drv_data->clk = devm_clk_get(>dev, NULL); - if (!IS_ERR(drv_data->clk)) { - clk_prepare(drv_data->clk); - clk_enable(drv_data->clk); - } + if (!IS_ERR(drv_data->clk)) + clk_prepare_enable(drv_data->clk); #endif if (pdata) { drv_data->freq_m = pdata->freq_m; @@ -966,10 +964,8 @@ exit_reset: exit_clk: #if defined(CONFIG_HAVE_CLK) /* Not all platforms have a clk */ - if (!IS_ERR(drv_data->clk)) { - clk_disable(drv_data->clk); - clk_unprepare(drv_data->clk); - } + if (!IS_ERR(drv_data->clk)) + clk_disable_unprepare(drv_data->clk); #endif return rc; } @@ -985,10 +981,8 @@ mv64xxx_i2c_remove(struct platform_device *dev) reset_control_assert(drv_data->rstc); #if defined(CONFIG_HAVE_CLK) /* Not all platforms have a clk */ - if (!IS_ERR(drv_data->clk)) { - clk_disable(drv_data->clk); - clk_unprepare(drv_data->clk); - } + if (!IS_ERR(drv_data->clk)) + clk_disable_unprepare(drv_data->clk); #endif return 0; -- 1.9.1
[PATCH v2] 2c: mv64xxx: Use clk_enable_prepare and clk_disable_unprepare
Replace clk_enable and clk_prepare with clk_enable_prepare and clk_disable and clk_unprepare with clk_disable_unprepare. The Coccinelle semantic patch used to make this change is as follows: @@ expression e; @@ - clk_prepare(e); - clk_enable(e); + clk_prepare_enable(e); @@ expression e; @@ - clk_disable(e); - clk_unprepare(e); + clk_disable_unprepare(e); Signed-off-by: Amitoj Kaur Chawla --- Changes in v2: -Rebased patch drivers/i2c/busses/i2c-mv64xxx.c | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 43207f5..79bae48 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -910,10 +910,8 @@ mv64xxx_i2c_probe(struct platform_device *pd) #if defined(CONFIG_HAVE_CLK) /* Not all platforms have a clk */ drv_data->clk = devm_clk_get(>dev, NULL); - if (!IS_ERR(drv_data->clk)) { - clk_prepare(drv_data->clk); - clk_enable(drv_data->clk); - } + if (!IS_ERR(drv_data->clk)) + clk_prepare_enable(drv_data->clk); #endif if (pdata) { drv_data->freq_m = pdata->freq_m; @@ -966,10 +964,8 @@ exit_reset: exit_clk: #if defined(CONFIG_HAVE_CLK) /* Not all platforms have a clk */ - if (!IS_ERR(drv_data->clk)) { - clk_disable(drv_data->clk); - clk_unprepare(drv_data->clk); - } + if (!IS_ERR(drv_data->clk)) + clk_disable_unprepare(drv_data->clk); #endif return rc; } @@ -985,10 +981,8 @@ mv64xxx_i2c_remove(struct platform_device *dev) reset_control_assert(drv_data->rstc); #if defined(CONFIG_HAVE_CLK) /* Not all platforms have a clk */ - if (!IS_ERR(drv_data->clk)) { - clk_disable(drv_data->clk); - clk_unprepare(drv_data->clk); - } + if (!IS_ERR(drv_data->clk)) + clk_disable_unprepare(drv_data->clk); #endif return 0; -- 1.9.1
Re: [PATCH 2/3] xen-scsiback: One function call less in scsiback_device_action() after error detection
@@ -606,7 +606,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req, tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL); if (!tmr) { target_put_sess_cmd(se_cmd); - goto err; + goto do_resp; } >>> >>> Hmm, I'm not convinced this is an improvement. >>> >>> I'd rather rename the new error label to "put_cmd" and get rid of the >>> braces in above if statement: >>> >>> - if (!tmr) { >>> - target_put_sess_cmd(se_cmd); >>> - goto err; >>> - } >>> + if (!tmr) >>> + goto put_cmd; >>> >>> and then in the error path: >>> >>> -err: >>> +put_cmd: >>> + target_put_sess_cmd(se_cmd); >> >> I am unsure on the relevance of this function on such a source position. >> Would it make sense to move it further down at the end? > > You only want to call it in the first error case (allocation failure). Thanks for your clarification. I find that my update suggestion (from Saturday) is still appropriate in this case. https://lkml.org/lkml/2016/7/16/172 >>> +free_tmr: >>> kfree(tmr); >> >> How do you think about to skip this function call after a memory >> allocation failure? > > I think this just doesn't matter. If it were a hot path, yes. But trying > to do micro-optimizations in an error path is just not worth the effort. Would you like to reduce also the amount of function calls in such special run-time situations? > I like a linear error path containing all the needed cleanups best. I would prefer to keep the discussed single function call within the basic block of the if statement. Have we got different opinions about the shown implementation details? Regards, Markus
Re: [PATCH 2/3] xen-scsiback: One function call less in scsiback_device_action() after error detection
@@ -606,7 +606,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req, tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL); if (!tmr) { target_put_sess_cmd(se_cmd); - goto err; + goto do_resp; } >>> >>> Hmm, I'm not convinced this is an improvement. >>> >>> I'd rather rename the new error label to "put_cmd" and get rid of the >>> braces in above if statement: >>> >>> - if (!tmr) { >>> - target_put_sess_cmd(se_cmd); >>> - goto err; >>> - } >>> + if (!tmr) >>> + goto put_cmd; >>> >>> and then in the error path: >>> >>> -err: >>> +put_cmd: >>> + target_put_sess_cmd(se_cmd); >> >> I am unsure on the relevance of this function on such a source position. >> Would it make sense to move it further down at the end? > > You only want to call it in the first error case (allocation failure). Thanks for your clarification. I find that my update suggestion (from Saturday) is still appropriate in this case. https://lkml.org/lkml/2016/7/16/172 >>> +free_tmr: >>> kfree(tmr); >> >> How do you think about to skip this function call after a memory >> allocation failure? > > I think this just doesn't matter. If it were a hot path, yes. But trying > to do micro-optimizations in an error path is just not worth the effort. Would you like to reduce also the amount of function calls in such special run-time situations? > I like a linear error path containing all the needed cleanups best. I would prefer to keep the discussed single function call within the basic block of the if statement. Have we got different opinions about the shown implementation details? Regards, Markus
Re: [RFC PATCH 0/3] ECAM quirks handling for ARM64 platforms
On 19.07.2016 23:17, Bjorn Helgaas wrote: On Thu, Jun 02, 2016 at 10:41:00AM +0200, Tomasz Nowicki wrote: This series bases on pending ACPI PCI support for ARM64: https://lkml.org/lkml/2016/5/30/468 Quirk handling relies on an idea of matching MCFG OEM ID and OEM revision (the ones from standard header of MCFG table). Linker section is used so that quirks can be registered using special macro (see patches) and kept self contained. As an example, last patch presents above mechanism usage for ThunderX PEM driver. Tomasz Nowicki (3): pci, acpi: Match PCI config space accessors against platfrom specific ECAM quirks. arm64, pci: Start using quirks handling for ACPI based PCI host controller. pci, pci-thunder-pem: Add ACPI support for ThunderX PEM. arch/arm64/kernel/pci.c| 7 +- drivers/acpi/pci_mcfg.c| 32 + drivers/pci/host/pci-thunder-pem.c | 132 + include/asm-generic/vmlinux.lds.h | 7 ++ include/linux/pci-acpi.h | 19 ++ 5 files changed, 181 insertions(+), 16 deletions(-) Is this series superceded by Dongdong's series of 6/13 ("[RFC,V2,1/2] ACPI/PCI: Match PCI config space accessors against platfrom specific ECAM quirks")? Yes this series had two another versions (v2,v3) posted by someone else. However, I posted another v4 which is the latest one: [RFC PATCH v4 0/5] ECAM quirks handling for ARM64 platforms https://lkml.org/lkml/2016/6/28/165 In v4 there is one minor thing to be fixed. Do you want me to resend it as v5 including mentioned fix ? Thanks, Tomasz
Re: [PATCH v3 02/12] binfmt_flat: convert printk invocations to their modern form
On Tue, 19 Jul 2016, Joe Perches wrote: > On Wed, 2016-07-20 at 00:20 -0400, Nicolas Pitre wrote: > > diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c > [] > > @@ -15,6 +15,8 @@ > > * JAN/99 -- coded full program relocation (g...@snapgear.com) > > */ > > > > +#define pr_fmt(fmt)"BINFMT_FLAT: : " fmt > > Why the double colon? Go figure. > Much more common would be > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt Sure. I used the all-caps version as that's what most former printk's used. But if you say KBUILD_MODNAME is more common then I have no issue with that. > > > @@ -106,8 +98,8 @@ static struct linux_binfmt flat_format = { > > > > static int flat_core_dump(struct coredump_params *cprm) > > { > > - printk("Process %s:%d received signr %d and should have core dumped\n", > > - current->comm, current->pid, cprm->siginfo->si_signo); > > + pr_warning("Process %s:%d received signr %d and should have core > > dumped\n", > > + current->comm, current->pid, cprm->siginfo->si_signo); > > Prefer pr_warn OK. Updated in my repo and pushed out. > > return(1); > > } > > > > @@ -190,17 +182,17 @@ static int decompress_exec( > > loff_t fpos; > > int ret, retval; > > > > - DBG_FLT("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, > > len); > > + pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, > > len); > > Generally unnecessary as the function tracer works well Not necessarily on uClinux where you might not aford it. And this patch is about converting existing printk()'s so if some of them should be removed then it would be best to do that separately. > > memset(, 0, sizeof(strm)); > > strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); > > if (strm.workspace == NULL) { > > - DBG_FLT("binfmt_flat: no memory for decompress workspace\n"); > > + pr_debug("no memory for decompress workspace\n"); > > return -ENOMEM; > > } > > buf = kmalloc(LBUFSIZE, GFP_KERNEL); > > if (buf == NULL) { > > - DBG_FLT("binfmt_flat: no memory for read buffer\n"); > > + pr_debug("no memory for read buffer\n"); > > Unnecessary OOM messages as allocs do a stack dump Again this should probably be done separately. Nicolas
Re: [RFC PATCH 0/3] ECAM quirks handling for ARM64 platforms
On 19.07.2016 23:17, Bjorn Helgaas wrote: On Thu, Jun 02, 2016 at 10:41:00AM +0200, Tomasz Nowicki wrote: This series bases on pending ACPI PCI support for ARM64: https://lkml.org/lkml/2016/5/30/468 Quirk handling relies on an idea of matching MCFG OEM ID and OEM revision (the ones from standard header of MCFG table). Linker section is used so that quirks can be registered using special macro (see patches) and kept self contained. As an example, last patch presents above mechanism usage for ThunderX PEM driver. Tomasz Nowicki (3): pci, acpi: Match PCI config space accessors against platfrom specific ECAM quirks. arm64, pci: Start using quirks handling for ACPI based PCI host controller. pci, pci-thunder-pem: Add ACPI support for ThunderX PEM. arch/arm64/kernel/pci.c| 7 +- drivers/acpi/pci_mcfg.c| 32 + drivers/pci/host/pci-thunder-pem.c | 132 + include/asm-generic/vmlinux.lds.h | 7 ++ include/linux/pci-acpi.h | 19 ++ 5 files changed, 181 insertions(+), 16 deletions(-) Is this series superceded by Dongdong's series of 6/13 ("[RFC,V2,1/2] ACPI/PCI: Match PCI config space accessors against platfrom specific ECAM quirks")? Yes this series had two another versions (v2,v3) posted by someone else. However, I posted another v4 which is the latest one: [RFC PATCH v4 0/5] ECAM quirks handling for ARM64 platforms https://lkml.org/lkml/2016/6/28/165 In v4 there is one minor thing to be fixed. Do you want me to resend it as v5 including mentioned fix ? Thanks, Tomasz
Re: [PATCH v3 02/12] binfmt_flat: convert printk invocations to their modern form
On Tue, 19 Jul 2016, Joe Perches wrote: > On Wed, 2016-07-20 at 00:20 -0400, Nicolas Pitre wrote: > > diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c > [] > > @@ -15,6 +15,8 @@ > > * JAN/99 -- coded full program relocation (g...@snapgear.com) > > */ > > > > +#define pr_fmt(fmt)"BINFMT_FLAT: : " fmt > > Why the double colon? Go figure. > Much more common would be > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt Sure. I used the all-caps version as that's what most former printk's used. But if you say KBUILD_MODNAME is more common then I have no issue with that. > > > @@ -106,8 +98,8 @@ static struct linux_binfmt flat_format = { > > > > static int flat_core_dump(struct coredump_params *cprm) > > { > > - printk("Process %s:%d received signr %d and should have core dumped\n", > > - current->comm, current->pid, cprm->siginfo->si_signo); > > + pr_warning("Process %s:%d received signr %d and should have core > > dumped\n", > > + current->comm, current->pid, cprm->siginfo->si_signo); > > Prefer pr_warn OK. Updated in my repo and pushed out. > > return(1); > > } > > > > @@ -190,17 +182,17 @@ static int decompress_exec( > > loff_t fpos; > > int ret, retval; > > > > - DBG_FLT("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, > > len); > > + pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, > > len); > > Generally unnecessary as the function tracer works well Not necessarily on uClinux where you might not aford it. And this patch is about converting existing printk()'s so if some of them should be removed then it would be best to do that separately. > > memset(, 0, sizeof(strm)); > > strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); > > if (strm.workspace == NULL) { > > - DBG_FLT("binfmt_flat: no memory for decompress workspace\n"); > > + pr_debug("no memory for decompress workspace\n"); > > return -ENOMEM; > > } > > buf = kmalloc(LBUFSIZE, GFP_KERNEL); > > if (buf == NULL) { > > - DBG_FLT("binfmt_flat: no memory for read buffer\n"); > > + pr_debug("no memory for read buffer\n"); > > Unnecessary OOM messages as allocs do a stack dump Again this should probably be done separately. Nicolas
Re: [ANNOUNCE] 2016-Q2 release of KVMGT (Was Re: KVMGT - the implementation of ...)
Hi all, We are pleased to announce another update of Intel GVT-g for KVM. Intel GVT-g for KVM (a.k.a. KVMGT) is a full GPU virtualization solution with mediated pass-through, starting from 5th generation Intel Core™ processors with Intel Graphics processors. A virtual GPU instance is maintained for each VM, with part of performance critical resources directly assigned. The capability of running native graphics driver inside a VM, without hypervisor intervention in performance critical paths, achieves a good balance among performance, feature, and sharing capability. Repositories: - Kernel: https://github.com/01org/igvtg-kernel (2016q2-4.3.0 branch) - Qemu: https://github.com/01org/igvtg-qemu (2016q2-2.3.0 branch) This update consists of: - KVMGT stable release for Xeon E3 v4 (Broadwell), E3 v5(Skylake), Intel Core™ processors 5th generation (Boadwell) , 6th generation (Skylake) - 2D/3D/Media workloads can run simultaneously in multiple guests Known issues: - At least 2GB memory is suggested for Guest Virtual Machine (VM) to run most 3D workloads. - Using Windows Media Player play videos may cause host crash. Using VLC to play .ogg file may cause mosaic or slow response. - Suggest to X window mode like xinit instead of lightdm to launch host if running heavy workload in both guest and host for more than 6 hours. - Change i915.preemption_policy=3 in host kernel cmdline, if you see problem when running heavy 3D workloads in multiple Guests (>=3) in some extreme stress configuration. Please subscribe to join the mailing list: - https://lists.01.org/mailman/listinfo/igvt-g Official iGVT-g portal: - https://01.org/igvt-g More information about background, architecture and others about Intel GVT-g, can be found at: http://www.linux-kvm.org/images/f/f3/01x08b-KVMGT-a.pdf https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian Note: The KVMGT project should be considered a work in progress. As such it is not a complete product nor should it be considered one. Extra care should be taken when testing and configuring a system to use the KVMGT project. -- Thanks, Jike On 04/16/2016 02:31 PM, Jike Song wrote: > Hi all, > > We are pleased to announce another update of Intel GVT-g for KVM. > > Intel GVT-g for KVM (a.k.a. KVMGT) is a full GPU virtualization solution with > mediated pass-through, starting from 4th generation Intel Core(TM) processors > with Intel Graphics processors. A virtual GPU instance is maintained for > each VM, with part of performance critical resources directly assigned. The > capability of running native graphics driver inside a VM, without hypervisor > intervention in performance critical paths, achieves a good balance among > performance, feature, and sharing capability. > > > Repositories: > > Kernel: https://github.com/01org/igvtg-kernel (2016q1-4.3.0 branch) > Qemu: https://github.com/01org/igvtg-qemu (2016q1-2.3.0 branch) > > > This update consists of: > > - KVMGT now has better support for 5th generation (Broadwell) Intel Core(TM) > processors, Xeon(R) E3 v4 > - A new feature, QEMU compositor display is added to support display VM in > QEMU window. (use i915.enable_vgtbuffer=1 in kernel command line to enable > this feature, disabled by default, details please refer to the Setup Guide) > - 2D/3D/Media workloads can be run simultaneously in multiple guests. > - Support both Windows Guest and Linux Guest(Win7-32, Win7-64, Win8.1-64, > Ubuntu14.04-64) > - Host Linux kernel has been upgraded from 4.2.0 to 4.3.0 (based on drm-intel) > - KVMGT has preliminary support for 6th generation (Skylake) Intel Core(TM) > processors. > > > Known issues: > >- At least 2GB memory is suggested for VM to run most 3D workloads. >- On some particular platform, assigning >2G memory to VM will cause Linux > VM failed to boot up and Windows VM failed to load GFX driver. >- Using VLC to play .ogg file may cause mosaic or slow response. >- Running heavy 3D workloads in multiple guests for couple of hours may > cause stability issue.(use i915.preemption_policy=3 in host kernel cmd line > can work around this stability issue) > > > Please subscribe to join the mailing list: > https://lists.01.org/mailman/listinfo/igvt-g > > Official iGVT-g portal: https://01.org/igvt-g > > More information about background, architecture and others about Intel GVT-g, > can be found at: > > > http://www.linux-kvm.org/images/f/f3/01x08b-KVMGT-a.pdf > > https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian > > > The upstreaming effort of iGVT-g project is ongoing elsewhere, not as a part > of this release. > > > Note: > > The KVMGT project should be considered a work in progress. As such it is not > a complete product nor should it be considered one. Extra care should be > taken when testing and configuring a system to use the KVMGT project. > > > -- >
Re: [ANNOUNCE] 2016-Q2 release of KVMGT (Was Re: KVMGT - the implementation of ...)
Hi all, We are pleased to announce another update of Intel GVT-g for KVM. Intel GVT-g for KVM (a.k.a. KVMGT) is a full GPU virtualization solution with mediated pass-through, starting from 5th generation Intel Core™ processors with Intel Graphics processors. A virtual GPU instance is maintained for each VM, with part of performance critical resources directly assigned. The capability of running native graphics driver inside a VM, without hypervisor intervention in performance critical paths, achieves a good balance among performance, feature, and sharing capability. Repositories: - Kernel: https://github.com/01org/igvtg-kernel (2016q2-4.3.0 branch) - Qemu: https://github.com/01org/igvtg-qemu (2016q2-2.3.0 branch) This update consists of: - KVMGT stable release for Xeon E3 v4 (Broadwell), E3 v5(Skylake), Intel Core™ processors 5th generation (Boadwell) , 6th generation (Skylake) - 2D/3D/Media workloads can run simultaneously in multiple guests Known issues: - At least 2GB memory is suggested for Guest Virtual Machine (VM) to run most 3D workloads. - Using Windows Media Player play videos may cause host crash. Using VLC to play .ogg file may cause mosaic or slow response. - Suggest to X window mode like xinit instead of lightdm to launch host if running heavy workload in both guest and host for more than 6 hours. - Change i915.preemption_policy=3 in host kernel cmdline, if you see problem when running heavy 3D workloads in multiple Guests (>=3) in some extreme stress configuration. Please subscribe to join the mailing list: - https://lists.01.org/mailman/listinfo/igvt-g Official iGVT-g portal: - https://01.org/igvt-g More information about background, architecture and others about Intel GVT-g, can be found at: http://www.linux-kvm.org/images/f/f3/01x08b-KVMGT-a.pdf https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian Note: The KVMGT project should be considered a work in progress. As such it is not a complete product nor should it be considered one. Extra care should be taken when testing and configuring a system to use the KVMGT project. -- Thanks, Jike On 04/16/2016 02:31 PM, Jike Song wrote: > Hi all, > > We are pleased to announce another update of Intel GVT-g for KVM. > > Intel GVT-g for KVM (a.k.a. KVMGT) is a full GPU virtualization solution with > mediated pass-through, starting from 4th generation Intel Core(TM) processors > with Intel Graphics processors. A virtual GPU instance is maintained for > each VM, with part of performance critical resources directly assigned. The > capability of running native graphics driver inside a VM, without hypervisor > intervention in performance critical paths, achieves a good balance among > performance, feature, and sharing capability. > > > Repositories: > > Kernel: https://github.com/01org/igvtg-kernel (2016q1-4.3.0 branch) > Qemu: https://github.com/01org/igvtg-qemu (2016q1-2.3.0 branch) > > > This update consists of: > > - KVMGT now has better support for 5th generation (Broadwell) Intel Core(TM) > processors, Xeon(R) E3 v4 > - A new feature, QEMU compositor display is added to support display VM in > QEMU window. (use i915.enable_vgtbuffer=1 in kernel command line to enable > this feature, disabled by default, details please refer to the Setup Guide) > - 2D/3D/Media workloads can be run simultaneously in multiple guests. > - Support both Windows Guest and Linux Guest(Win7-32, Win7-64, Win8.1-64, > Ubuntu14.04-64) > - Host Linux kernel has been upgraded from 4.2.0 to 4.3.0 (based on drm-intel) > - KVMGT has preliminary support for 6th generation (Skylake) Intel Core(TM) > processors. > > > Known issues: > >- At least 2GB memory is suggested for VM to run most 3D workloads. >- On some particular platform, assigning >2G memory to VM will cause Linux > VM failed to boot up and Windows VM failed to load GFX driver. >- Using VLC to play .ogg file may cause mosaic or slow response. >- Running heavy 3D workloads in multiple guests for couple of hours may > cause stability issue.(use i915.preemption_policy=3 in host kernel cmd line > can work around this stability issue) > > > Please subscribe to join the mailing list: > https://lists.01.org/mailman/listinfo/igvt-g > > Official iGVT-g portal: https://01.org/igvt-g > > More information about background, architecture and others about Intel GVT-g, > can be found at: > > > http://www.linux-kvm.org/images/f/f3/01x08b-KVMGT-a.pdf > > https://www.usenix.org/conference/atc14/technical-sessions/presentation/tian > > > The upstreaming effort of iGVT-g project is ongoing elsewhere, not as a part > of this release. > > > Note: > > The KVMGT project should be considered a work in progress. As such it is not > a complete product nor should it be considered one. Extra care should be > taken when testing and configuring a system to use the KVMGT project. > > > -- >
Re: [RFC] Avoid mutex starvation when optimistic spinning is disabled
On Tue, 2016-07-19 at 16:04 -0700, Jason Low wrote: > Hi Imre, > > Here is a patch which prevents a thread from spending too much "time" > waiting for a mutex in the !CONFIG_MUTEX_SPIN_ON_OWNER case. > > Would you like to try this out and see if this addresses the mutex > starvation issue you are seeing in your workload when optimistic > spinning is disabled? Although it looks like it didn't take care of the 'lock stealing' case in the slowpath. Here is the updated fixed version: --- Signed-off-by: Jason Low--- include/linux/mutex.h | 2 ++ kernel/locking/mutex.c | 65 -- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 2cb7531..c1ca68d 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -57,6 +57,8 @@ struct mutex { #endif #ifdef CONFIG_MUTEX_SPIN_ON_OWNER struct optimistic_spin_queue osq; /* Spinner MCS lock */ +#else + bool yield_to_waiter; /* Prevent starvation when spinning disabled */ #endif #ifdef CONFIG_DEBUG_MUTEXES void*magic; diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index a70b90d..6c915ca 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -55,6 +55,8 @@ __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) mutex_clear_owner(lock); #ifdef CONFIG_MUTEX_SPIN_ON_OWNER osq_lock_init(>osq); +#else + lock->yield_to_waiter = false; #endif debug_mutex_init(lock, name, key); @@ -71,6 +73,9 @@ EXPORT_SYMBOL(__mutex_init); */ __visible void __sched __mutex_lock_slowpath(atomic_t *lock_count); + +static inline bool need_yield_to_waiter(struct mutex *lock); + /** * mutex_lock - acquire the mutex * @lock: the mutex to be acquired @@ -95,11 +100,15 @@ __visible void __sched __mutex_lock_slowpath(atomic_t *lock_count); void __sched mutex_lock(struct mutex *lock) { might_sleep(); + /* * The locking fastpath is the 1->0 transition from * 'unlocked' into 'locked' state. */ - __mutex_fastpath_lock(>count, __mutex_lock_slowpath); + if (!need_yield_to_waiter(lock)) + __mutex_fastpath_lock(>count, __mutex_lock_slowpath); + else + __mutex_lock_slowpath(>count); mutex_set_owner(lock); } @@ -398,12 +407,39 @@ done: return false; } + +static inline void do_yield_to_waiter(struct mutex *lock, int loops) +{ + return; +} + +static inline bool need_yield_to_waiter(struct mutex *lock) +{ + return false; +} + #else static bool mutex_optimistic_spin(struct mutex *lock, struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx) { return false; } + +#define MUTEX_MAX_WAIT 32 + +static inline void do_yield_to_waiter(struct mutex *lock, int loops) +{ + if (loops < MUTEX_MAX_WAIT) + return; + + if (lock->yield_to_waiter != true) + lock->yield_to_waiter =true; +} + +static inline bool need_yield_to_waiter(struct mutex *lock) +{ + return lock->yield_to_waiter; +} #endif __visible __used noinline @@ -510,6 +546,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, struct mutex_waiter waiter; unsigned long flags; int ret; + int loop = 0; if (use_ww_ctx) { struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); @@ -532,7 +569,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, * Once more, try to acquire the lock. Only try-lock the mutex if * it is unlocked to reduce unnecessary xchg() operations. */ - if (!mutex_is_locked(lock) && + if (!need_yield_to_waiter(lock) && !mutex_is_locked(lock) && (atomic_xchg_acquire(>count, 0) == 1)) goto skip_wait; @@ -546,6 +583,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, lock_contended(>dep_map, ip); for (;;) { + loop++; + /* * Lets try to take the lock again - this is needed even if * we get here for the first time (shortly after failing to @@ -556,7 +595,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, * other waiters. We only attempt the xchg if the count is * non-negative in order to avoid unnecessary xchg operations: */ - if (atomic_read(>count) >= 0 && + if ((!need_yield_to_waiter(lock) || loop > 1) && + atomic_read(>count) >= 0 && (atomic_xchg_acquire(>count, -1) == 1)) break; @@ -581,6 +621,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
Re: [RFC] Avoid mutex starvation when optimistic spinning is disabled
On Tue, 2016-07-19 at 16:04 -0700, Jason Low wrote: > Hi Imre, > > Here is a patch which prevents a thread from spending too much "time" > waiting for a mutex in the !CONFIG_MUTEX_SPIN_ON_OWNER case. > > Would you like to try this out and see if this addresses the mutex > starvation issue you are seeing in your workload when optimistic > spinning is disabled? Although it looks like it didn't take care of the 'lock stealing' case in the slowpath. Here is the updated fixed version: --- Signed-off-by: Jason Low --- include/linux/mutex.h | 2 ++ kernel/locking/mutex.c | 65 -- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 2cb7531..c1ca68d 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -57,6 +57,8 @@ struct mutex { #endif #ifdef CONFIG_MUTEX_SPIN_ON_OWNER struct optimistic_spin_queue osq; /* Spinner MCS lock */ +#else + bool yield_to_waiter; /* Prevent starvation when spinning disabled */ #endif #ifdef CONFIG_DEBUG_MUTEXES void*magic; diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index a70b90d..6c915ca 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -55,6 +55,8 @@ __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) mutex_clear_owner(lock); #ifdef CONFIG_MUTEX_SPIN_ON_OWNER osq_lock_init(>osq); +#else + lock->yield_to_waiter = false; #endif debug_mutex_init(lock, name, key); @@ -71,6 +73,9 @@ EXPORT_SYMBOL(__mutex_init); */ __visible void __sched __mutex_lock_slowpath(atomic_t *lock_count); + +static inline bool need_yield_to_waiter(struct mutex *lock); + /** * mutex_lock - acquire the mutex * @lock: the mutex to be acquired @@ -95,11 +100,15 @@ __visible void __sched __mutex_lock_slowpath(atomic_t *lock_count); void __sched mutex_lock(struct mutex *lock) { might_sleep(); + /* * The locking fastpath is the 1->0 transition from * 'unlocked' into 'locked' state. */ - __mutex_fastpath_lock(>count, __mutex_lock_slowpath); + if (!need_yield_to_waiter(lock)) + __mutex_fastpath_lock(>count, __mutex_lock_slowpath); + else + __mutex_lock_slowpath(>count); mutex_set_owner(lock); } @@ -398,12 +407,39 @@ done: return false; } + +static inline void do_yield_to_waiter(struct mutex *lock, int loops) +{ + return; +} + +static inline bool need_yield_to_waiter(struct mutex *lock) +{ + return false; +} + #else static bool mutex_optimistic_spin(struct mutex *lock, struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx) { return false; } + +#define MUTEX_MAX_WAIT 32 + +static inline void do_yield_to_waiter(struct mutex *lock, int loops) +{ + if (loops < MUTEX_MAX_WAIT) + return; + + if (lock->yield_to_waiter != true) + lock->yield_to_waiter =true; +} + +static inline bool need_yield_to_waiter(struct mutex *lock) +{ + return lock->yield_to_waiter; +} #endif __visible __used noinline @@ -510,6 +546,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, struct mutex_waiter waiter; unsigned long flags; int ret; + int loop = 0; if (use_ww_ctx) { struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); @@ -532,7 +569,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, * Once more, try to acquire the lock. Only try-lock the mutex if * it is unlocked to reduce unnecessary xchg() operations. */ - if (!mutex_is_locked(lock) && + if (!need_yield_to_waiter(lock) && !mutex_is_locked(lock) && (atomic_xchg_acquire(>count, 0) == 1)) goto skip_wait; @@ -546,6 +583,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, lock_contended(>dep_map, ip); for (;;) { + loop++; + /* * Lets try to take the lock again - this is needed even if * we get here for the first time (shortly after failing to @@ -556,7 +595,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, * other waiters. We only attempt the xchg if the count is * non-negative in order to avoid unnecessary xchg operations: */ - if (atomic_read(>count) >= 0 && + if ((!need_yield_to_waiter(lock) || loop > 1) && + atomic_read(>count) >= 0 && (atomic_xchg_acquire(>count, -1) == 1)) break; @@ -581,6 +621,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, spin_unlock_mutex(>wait_lock, flags);
Re: staging/wilc1000: wrong conversion to completion?
On 11 July 2016 at 13:38, Arnd Bergmannwrote: > On Monday, July 11, 2016 9:41:15 AM CEST Jiri Slaby wrote: >> Hi, >> >> while looking at this commit: >> >> commit b27a6d5e636ac80b223a18ca2b3c892f1caef9e3 >> Author: Binoy Jayan >> Date: Wed Jun 15 11:00:34 2016 +0530 >> >> staging: wilc1000: Replace semaphore txq_event with completion >> >> The semaphore 'txq_event' is used as completion, so convert it >> to a struct completion type. >> >> Signed-off-by: Binoy Jayan >> Reviewed-by: Arnd Bergmann >> Signed-off-by: Greg Kroah-Hartman >> >> diff --git a/drivers/staging/wilc1000/linux_wlan.c >> b/drivers/staging/wilc1000/linux_wlan.c >> index 274c390d17cd..baf932681362 100644 >> --- a/drivers/staging/wilc1000/linux_wlan.c >> +++ b/drivers/staging/wilc1000/linux_wlan.c >> @@ -316,7 +316,7 @@ static int linux_wlan_txq_task(void *vp) >> >> complete(>txq_thread_started); >> while (1) { >> - down(>txq_event); >> + wait_for_completion(>txq_event); >> >> if (wl->close) { >> complete(>txq_thread_started); >> @@ -650,7 +650,7 @@ void wilc1000_wlan_deinit(struct net_device *dev) >> mutex_unlock(>hif_cs); >> } >> if (>txq_event) >> - up(>txq_event); >> + wait_for_completion(>txq_event); >> >> >> I wonder: is this correct? Should that be complete() instead? >> > > Yes, I agree, sorry for missing that in my review. > > Arnd Sorry for the typo. Just saw the email after coming back from vacation. Will send the patch soon. Binoy
Re: staging/wilc1000: wrong conversion to completion?
On 11 July 2016 at 13:38, Arnd Bergmann wrote: > On Monday, July 11, 2016 9:41:15 AM CEST Jiri Slaby wrote: >> Hi, >> >> while looking at this commit: >> >> commit b27a6d5e636ac80b223a18ca2b3c892f1caef9e3 >> Author: Binoy Jayan >> Date: Wed Jun 15 11:00:34 2016 +0530 >> >> staging: wilc1000: Replace semaphore txq_event with completion >> >> The semaphore 'txq_event' is used as completion, so convert it >> to a struct completion type. >> >> Signed-off-by: Binoy Jayan >> Reviewed-by: Arnd Bergmann >> Signed-off-by: Greg Kroah-Hartman >> >> diff --git a/drivers/staging/wilc1000/linux_wlan.c >> b/drivers/staging/wilc1000/linux_wlan.c >> index 274c390d17cd..baf932681362 100644 >> --- a/drivers/staging/wilc1000/linux_wlan.c >> +++ b/drivers/staging/wilc1000/linux_wlan.c >> @@ -316,7 +316,7 @@ static int linux_wlan_txq_task(void *vp) >> >> complete(>txq_thread_started); >> while (1) { >> - down(>txq_event); >> + wait_for_completion(>txq_event); >> >> if (wl->close) { >> complete(>txq_thread_started); >> @@ -650,7 +650,7 @@ void wilc1000_wlan_deinit(struct net_device *dev) >> mutex_unlock(>hif_cs); >> } >> if (>txq_event) >> - up(>txq_event); >> + wait_for_completion(>txq_event); >> >> >> I wonder: is this correct? Should that be complete() instead? >> > > Yes, I agree, sorry for missing that in my review. > > Arnd Sorry for the typo. Just saw the email after coming back from vacation. Will send the patch soon. Binoy
Re: [PATCH 2/3] xen-scsiback: One function call less in scsiback_device_action() after error detection
On 19/07/16 16:56, SF Markus Elfring wrote: >>> @@ -606,7 +606,7 @@ static void scsiback_device_action(struct vscsibk_pend >>> *pending_req, >>> tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL); >>> if (!tmr) { >>> target_put_sess_cmd(se_cmd); >>> - goto err; >>> + goto do_resp; >>> } >> >> Hmm, I'm not convinced this is an improvement. >> >> I'd rather rename the new error label to "put_cmd" and get rid of the >> braces in above if statement: >> >> -if (!tmr) { >> -target_put_sess_cmd(se_cmd); >> -goto err; >> -} >> +if (!tmr) >> +goto put_cmd; >> >> and then in the error path: >> >> -err: >> +put_cmd: >> +target_put_sess_cmd(se_cmd); > > I am unsure on the relevance of this function on such a source position. > Would it make sense to move it further down at the end? You only want to call it in the first error case (allocation failure). >> +free_tmr: >> kfree(tmr); > > How do you think about to skip this function call after a memory > allocation failure? I think this just doesn't matter. If it were a hot path, yes. But trying to do micro-optimizations in an error path is just not worth the effort. I like a linear error path containing all the needed cleanups best. Juergen
Re: [PATCH 2/3] xen-scsiback: One function call less in scsiback_device_action() after error detection
On 19/07/16 16:56, SF Markus Elfring wrote: >>> @@ -606,7 +606,7 @@ static void scsiback_device_action(struct vscsibk_pend >>> *pending_req, >>> tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL); >>> if (!tmr) { >>> target_put_sess_cmd(se_cmd); >>> - goto err; >>> + goto do_resp; >>> } >> >> Hmm, I'm not convinced this is an improvement. >> >> I'd rather rename the new error label to "put_cmd" and get rid of the >> braces in above if statement: >> >> -if (!tmr) { >> -target_put_sess_cmd(se_cmd); >> -goto err; >> -} >> +if (!tmr) >> +goto put_cmd; >> >> and then in the error path: >> >> -err: >> +put_cmd: >> +target_put_sess_cmd(se_cmd); > > I am unsure on the relevance of this function on such a source position. > Would it make sense to move it further down at the end? You only want to call it in the first error case (allocation failure). >> +free_tmr: >> kfree(tmr); > > How do you think about to skip this function call after a memory > allocation failure? I think this just doesn't matter. If it were a hot path, yes. But trying to do micro-optimizations in an error path is just not worth the effort. I like a linear error path containing all the needed cleanups best. Juergen
[PATCH kernel v2 1/2] powerpc/iommu: Stop using @current in mm_iommu_xxx
In some situations the userspace memory context may live longer than the userspace process itself so if we need to do proper memory context cleanup, we better cache @mm and use it later when the process is gone (@current or @current->mm are NULL). This changes mm_iommu_xxx API to receive mm_struct instead of using one from @current. This is needed by the following patch to do proper cleanup in time. This depends on "powerpc/powernv/ioda: Fix endianness when reading TCEs" to do proper cleanup via tce_iommu_clear() patch. This should cause no behavioral change. Signed-off-by: Alexey Kardashevskiy--- arch/powerpc/include/asm/mmu_context.h | 15 ++-- arch/powerpc/mm/mmu_context_iommu.c| 45 +- drivers/vfio/vfio_iommu_spapr_tce.c| 41 +++ 3 files changed, 51 insertions(+), 50 deletions(-) diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 9d2cd0c..745b4bd 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -18,16 +18,17 @@ extern void destroy_context(struct mm_struct *mm); #ifdef CONFIG_SPAPR_TCE_IOMMU struct mm_iommu_table_group_mem_t; -extern bool mm_iommu_preregistered(void); -extern long mm_iommu_get(unsigned long ua, unsigned long entries, +extern bool mm_iommu_preregistered(struct mm_struct *mm); +extern long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries, struct mm_iommu_table_group_mem_t **pmem); -extern long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem); +extern long mm_iommu_put(struct mm_struct *mm, + struct mm_iommu_table_group_mem_t *mem); extern void mm_iommu_init(mm_context_t *ctx); extern void mm_iommu_cleanup(mm_context_t *ctx); -extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(unsigned long ua, - unsigned long size); -extern struct mm_iommu_table_group_mem_t *mm_iommu_find(unsigned long ua, - unsigned long entries); +extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm, + unsigned long ua, unsigned long size); +extern struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm, + unsigned long ua, unsigned long entries); extern long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem, unsigned long ua, unsigned long *hpa); extern long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem); diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c index da6a216..65086bf 100644 --- a/arch/powerpc/mm/mmu_context_iommu.c +++ b/arch/powerpc/mm/mmu_context_iommu.c @@ -53,7 +53,7 @@ static long mm_iommu_adjust_locked_vm(struct mm_struct *mm, } pr_debug("[%d] RLIMIT_MEMLOCK HASH64 %c%ld %ld/%ld\n", - current->pid, + current ? current->pid : 0, incr ? '+' : '-', npages << PAGE_SHIFT, mm->locked_vm << PAGE_SHIFT, @@ -63,28 +63,22 @@ static long mm_iommu_adjust_locked_vm(struct mm_struct *mm, return ret; } -bool mm_iommu_preregistered(void) +bool mm_iommu_preregistered(struct mm_struct *mm) { - if (!current || !current->mm) - return false; - - return !list_empty(>mm->context.iommu_group_mem_list); + return !list_empty(>context.iommu_group_mem_list); } EXPORT_SYMBOL_GPL(mm_iommu_preregistered); -long mm_iommu_get(unsigned long ua, unsigned long entries, +long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries, struct mm_iommu_table_group_mem_t **pmem) { struct mm_iommu_table_group_mem_t *mem; long i, j, ret = 0, locked_entries = 0; struct page *page = NULL; - if (!current || !current->mm) - return -ESRCH; /* process exited */ - mutex_lock(_list_mutex); - list_for_each_entry_rcu(mem, >mm->context.iommu_group_mem_list, + list_for_each_entry_rcu(mem, >context.iommu_group_mem_list, next) { if ((mem->ua == ua) && (mem->entries == entries)) { ++mem->used; @@ -102,7 +96,7 @@ long mm_iommu_get(unsigned long ua, unsigned long entries, } - ret = mm_iommu_adjust_locked_vm(current->mm, entries, true); + ret = mm_iommu_adjust_locked_vm(mm, entries, true); if (ret) goto unlock_exit; @@ -142,11 +136,11 @@ long mm_iommu_get(unsigned long ua, unsigned long entries, mem->entries = entries; *pmem = mem; - list_add_rcu(>next, >mm->context.iommu_group_mem_list); + list_add_rcu(>next, >context.iommu_group_mem_list); unlock_exit: if (locked_entries && ret) - mm_iommu_adjust_locked_vm(current->mm, locked_entries, false); +
[PATCH kernel v2 2/2] powerpc/mm/iommu: Put pages on process exit
At the moment VFIO IOMMU SPAPR v2 driver pins all guest RAM pages when the userspace starts using VFIO. When the userspace process finishes, all the pinned pages need to be put; this is done as a part of the userspace memory context (MM) destruction which happens on the very last mmdrop(). This approach has a problem that a MM of the userspace process may live longer than the userspace process itself as kernel threads use userspace process MMs which was runnning on a CPU where the kernel thread was scheduled to. If this happened, the MM remains referenced until this exact kernel thread wakes up again and releases the very last reference to the MM, on an idle system this can take even hours. This references and caches MM once per container and adds tracking how many times each preregistered area was registered in a specific container. This way we do not depend on @current pointing to a valid task descriptor. This changes the userspce interface to return EBUSY if memory is already registered (mm_iommu_get() used to increment the counter); however it should not have any practical effect as the only userspace tool available now does register memory area once per container anyway. As tce_iommu_register_pages/tce_iommu_unregister_pages are called under container->lock, this does not need additional locking. Cc: David GibsonCc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Balbir Singh Cc: Nicholas Piggin Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/include/asm/mmu_context.h | 1 - arch/powerpc/mm/mmu_context_book3s64.c | 4 --- arch/powerpc/mm/mmu_context_iommu.c| 10 --- drivers/vfio/vfio_iommu_spapr_tce.c| 52 +- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 745b4bd..90338fd 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -24,7 +24,6 @@ extern long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long e extern long mm_iommu_put(struct mm_struct *mm, struct mm_iommu_table_group_mem_t *mem); extern void mm_iommu_init(mm_context_t *ctx); -extern void mm_iommu_cleanup(mm_context_t *ctx); extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm, unsigned long ua, unsigned long size); extern struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm, diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c index 227b2a6..5c67d1c 100644 --- a/arch/powerpc/mm/mmu_context_book3s64.c +++ b/arch/powerpc/mm/mmu_context_book3s64.c @@ -159,10 +159,6 @@ static inline void destroy_pagetable_page(struct mm_struct *mm) void destroy_context(struct mm_struct *mm) { -#ifdef CONFIG_SPAPR_TCE_IOMMU - mm_iommu_cleanup(>context); -#endif - #ifdef CONFIG_PPC_ICSWX drop_cop(mm->context.acop, mm); kfree(mm->context.cop_lockp); diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c index 65086bf..901773d 100644 --- a/arch/powerpc/mm/mmu_context_iommu.c +++ b/arch/powerpc/mm/mmu_context_iommu.c @@ -293,13 +293,3 @@ void mm_iommu_init(mm_context_t *ctx) { INIT_LIST_HEAD_RCU(>iommu_group_mem_list); } - -void mm_iommu_cleanup(mm_context_t *ctx) -{ - struct mm_iommu_table_group_mem_t *mem, *tmp; - - list_for_each_entry_safe(mem, tmp, >iommu_group_mem_list, next) { - list_del_rcu(>next); - mm_iommu_do_free(mem); - } -} diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 9752e77..40e71a0 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -89,6 +89,15 @@ struct tce_iommu_group { }; /* + * A container needs to remember which preregistered areas and how many times + * it has referenced to do proper cleanup at the userspace process exit. + */ +struct tce_iommu_prereg { + struct list_head next; + struct mm_iommu_table_group_mem_t *mem; +}; + +/* * The container descriptor supports only a single group per container. * Required by the API as the container is not supplied with the IOMMU group * at the moment of initialization. @@ -101,12 +110,26 @@ struct tce_container { struct mm_struct *mm; struct iommu_table *tables[IOMMU_TABLE_GROUP_MAX_TABLES]; struct list_head group_list; + struct list_head prereg_list; }; +static long tce_iommu_prereg_free(struct tce_container *container, + struct tce_iommu_prereg *tcemem) +{ + long ret; + + list_del(>next); + ret = mm_iommu_put(container->mm, tcemem->mem); + kfree(tcemem); + + return ret; +} + static long tce_iommu_unregister_pages(struct
[PATCH kernel v2 1/2] powerpc/iommu: Stop using @current in mm_iommu_xxx
In some situations the userspace memory context may live longer than the userspace process itself so if we need to do proper memory context cleanup, we better cache @mm and use it later when the process is gone (@current or @current->mm are NULL). This changes mm_iommu_xxx API to receive mm_struct instead of using one from @current. This is needed by the following patch to do proper cleanup in time. This depends on "powerpc/powernv/ioda: Fix endianness when reading TCEs" to do proper cleanup via tce_iommu_clear() patch. This should cause no behavioral change. Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/include/asm/mmu_context.h | 15 ++-- arch/powerpc/mm/mmu_context_iommu.c| 45 +- drivers/vfio/vfio_iommu_spapr_tce.c| 41 +++ 3 files changed, 51 insertions(+), 50 deletions(-) diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 9d2cd0c..745b4bd 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -18,16 +18,17 @@ extern void destroy_context(struct mm_struct *mm); #ifdef CONFIG_SPAPR_TCE_IOMMU struct mm_iommu_table_group_mem_t; -extern bool mm_iommu_preregistered(void); -extern long mm_iommu_get(unsigned long ua, unsigned long entries, +extern bool mm_iommu_preregistered(struct mm_struct *mm); +extern long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries, struct mm_iommu_table_group_mem_t **pmem); -extern long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem); +extern long mm_iommu_put(struct mm_struct *mm, + struct mm_iommu_table_group_mem_t *mem); extern void mm_iommu_init(mm_context_t *ctx); extern void mm_iommu_cleanup(mm_context_t *ctx); -extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(unsigned long ua, - unsigned long size); -extern struct mm_iommu_table_group_mem_t *mm_iommu_find(unsigned long ua, - unsigned long entries); +extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm, + unsigned long ua, unsigned long size); +extern struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm, + unsigned long ua, unsigned long entries); extern long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem, unsigned long ua, unsigned long *hpa); extern long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem); diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c index da6a216..65086bf 100644 --- a/arch/powerpc/mm/mmu_context_iommu.c +++ b/arch/powerpc/mm/mmu_context_iommu.c @@ -53,7 +53,7 @@ static long mm_iommu_adjust_locked_vm(struct mm_struct *mm, } pr_debug("[%d] RLIMIT_MEMLOCK HASH64 %c%ld %ld/%ld\n", - current->pid, + current ? current->pid : 0, incr ? '+' : '-', npages << PAGE_SHIFT, mm->locked_vm << PAGE_SHIFT, @@ -63,28 +63,22 @@ static long mm_iommu_adjust_locked_vm(struct mm_struct *mm, return ret; } -bool mm_iommu_preregistered(void) +bool mm_iommu_preregistered(struct mm_struct *mm) { - if (!current || !current->mm) - return false; - - return !list_empty(>mm->context.iommu_group_mem_list); + return !list_empty(>context.iommu_group_mem_list); } EXPORT_SYMBOL_GPL(mm_iommu_preregistered); -long mm_iommu_get(unsigned long ua, unsigned long entries, +long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries, struct mm_iommu_table_group_mem_t **pmem) { struct mm_iommu_table_group_mem_t *mem; long i, j, ret = 0, locked_entries = 0; struct page *page = NULL; - if (!current || !current->mm) - return -ESRCH; /* process exited */ - mutex_lock(_list_mutex); - list_for_each_entry_rcu(mem, >mm->context.iommu_group_mem_list, + list_for_each_entry_rcu(mem, >context.iommu_group_mem_list, next) { if ((mem->ua == ua) && (mem->entries == entries)) { ++mem->used; @@ -102,7 +96,7 @@ long mm_iommu_get(unsigned long ua, unsigned long entries, } - ret = mm_iommu_adjust_locked_vm(current->mm, entries, true); + ret = mm_iommu_adjust_locked_vm(mm, entries, true); if (ret) goto unlock_exit; @@ -142,11 +136,11 @@ long mm_iommu_get(unsigned long ua, unsigned long entries, mem->entries = entries; *pmem = mem; - list_add_rcu(>next, >mm->context.iommu_group_mem_list); + list_add_rcu(>next, >context.iommu_group_mem_list); unlock_exit: if (locked_entries && ret) - mm_iommu_adjust_locked_vm(current->mm, locked_entries, false); + mm_iommu_adjust_locked_vm(mm,
[PATCH kernel v2 2/2] powerpc/mm/iommu: Put pages on process exit
At the moment VFIO IOMMU SPAPR v2 driver pins all guest RAM pages when the userspace starts using VFIO. When the userspace process finishes, all the pinned pages need to be put; this is done as a part of the userspace memory context (MM) destruction which happens on the very last mmdrop(). This approach has a problem that a MM of the userspace process may live longer than the userspace process itself as kernel threads use userspace process MMs which was runnning on a CPU where the kernel thread was scheduled to. If this happened, the MM remains referenced until this exact kernel thread wakes up again and releases the very last reference to the MM, on an idle system this can take even hours. This references and caches MM once per container and adds tracking how many times each preregistered area was registered in a specific container. This way we do not depend on @current pointing to a valid task descriptor. This changes the userspce interface to return EBUSY if memory is already registered (mm_iommu_get() used to increment the counter); however it should not have any practical effect as the only userspace tool available now does register memory area once per container anyway. As tce_iommu_register_pages/tce_iommu_unregister_pages are called under container->lock, this does not need additional locking. Cc: David Gibson Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Balbir Singh Cc: Nicholas Piggin Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/include/asm/mmu_context.h | 1 - arch/powerpc/mm/mmu_context_book3s64.c | 4 --- arch/powerpc/mm/mmu_context_iommu.c| 10 --- drivers/vfio/vfio_iommu_spapr_tce.c| 52 +- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 745b4bd..90338fd 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -24,7 +24,6 @@ extern long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long e extern long mm_iommu_put(struct mm_struct *mm, struct mm_iommu_table_group_mem_t *mem); extern void mm_iommu_init(mm_context_t *ctx); -extern void mm_iommu_cleanup(mm_context_t *ctx); extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm, unsigned long ua, unsigned long size); extern struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm, diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c index 227b2a6..5c67d1c 100644 --- a/arch/powerpc/mm/mmu_context_book3s64.c +++ b/arch/powerpc/mm/mmu_context_book3s64.c @@ -159,10 +159,6 @@ static inline void destroy_pagetable_page(struct mm_struct *mm) void destroy_context(struct mm_struct *mm) { -#ifdef CONFIG_SPAPR_TCE_IOMMU - mm_iommu_cleanup(>context); -#endif - #ifdef CONFIG_PPC_ICSWX drop_cop(mm->context.acop, mm); kfree(mm->context.cop_lockp); diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c index 65086bf..901773d 100644 --- a/arch/powerpc/mm/mmu_context_iommu.c +++ b/arch/powerpc/mm/mmu_context_iommu.c @@ -293,13 +293,3 @@ void mm_iommu_init(mm_context_t *ctx) { INIT_LIST_HEAD_RCU(>iommu_group_mem_list); } - -void mm_iommu_cleanup(mm_context_t *ctx) -{ - struct mm_iommu_table_group_mem_t *mem, *tmp; - - list_for_each_entry_safe(mem, tmp, >iommu_group_mem_list, next) { - list_del_rcu(>next); - mm_iommu_do_free(mem); - } -} diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 9752e77..40e71a0 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -89,6 +89,15 @@ struct tce_iommu_group { }; /* + * A container needs to remember which preregistered areas and how many times + * it has referenced to do proper cleanup at the userspace process exit. + */ +struct tce_iommu_prereg { + struct list_head next; + struct mm_iommu_table_group_mem_t *mem; +}; + +/* * The container descriptor supports only a single group per container. * Required by the API as the container is not supplied with the IOMMU group * at the moment of initialization. @@ -101,12 +110,26 @@ struct tce_container { struct mm_struct *mm; struct iommu_table *tables[IOMMU_TABLE_GROUP_MAX_TABLES]; struct list_head group_list; + struct list_head prereg_list; }; +static long tce_iommu_prereg_free(struct tce_container *container, + struct tce_iommu_prereg *tcemem) +{ + long ret; + + list_del(>next); + ret = mm_iommu_put(container->mm, tcemem->mem); + kfree(tcemem); + + return ret; +} + static long tce_iommu_unregister_pages(struct tce_container *container, __u64 vaddr, __u64 size) { struct mm_iommu_table_group_mem_t *mem; + struct
[PATCH kernel v2 0/2] powerpc/mm/iommu: Put pages on process exit
This is a fix to a bug when guest memory stays Active after QEMU process exited. This happened because the QEMU memory context was not released in a short period of time after QEMU process exited. More details are in the commit logs. Please comment. Thanks. Alexey Kardashevskiy (2): powerpc/iommu: Stop using @current in mm_iommu_xxx powerpc/mm/iommu: Put pages on process exit arch/powerpc/include/asm/mmu_context.h | 16 +++--- arch/powerpc/mm/mmu_context_book3s64.c | 4 -- arch/powerpc/mm/mmu_context_iommu.c| 55 +++-- drivers/vfio/vfio_iommu_spapr_tce.c| 89 -- 4 files changed, 100 insertions(+), 64 deletions(-) -- 2.5.0.rc3
[PATCH kernel v2 0/2] powerpc/mm/iommu: Put pages on process exit
This is a fix to a bug when guest memory stays Active after QEMU process exited. This happened because the QEMU memory context was not released in a short period of time after QEMU process exited. More details are in the commit logs. Please comment. Thanks. Alexey Kardashevskiy (2): powerpc/iommu: Stop using @current in mm_iommu_xxx powerpc/mm/iommu: Put pages on process exit arch/powerpc/include/asm/mmu_context.h | 16 +++--- arch/powerpc/mm/mmu_context_book3s64.c | 4 -- arch/powerpc/mm/mmu_context_iommu.c| 55 +++-- drivers/vfio/vfio_iommu_spapr_tce.c| 89 -- 4 files changed, 100 insertions(+), 64 deletions(-) -- 2.5.0.rc3
Re: [PATCH v3 02/12] binfmt_flat: convert printk invocations to their modern form
On Wed, 2016-07-20 at 00:20 -0400, Nicolas Pitre wrote: > diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c [] > @@ -15,6 +15,8 @@ > * JAN/99 -- coded full program relocation (g...@snapgear.com) > */ > > +#define pr_fmt(fmt) "BINFMT_FLAT: : " fmt Why the double colon? Much more common would be #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > @@ -106,8 +98,8 @@ static struct linux_binfmt flat_format = { > > static int flat_core_dump(struct coredump_params *cprm) > { > - printk("Process %s:%d received signr %d and should have core dumped\n", > - current->comm, current->pid, cprm->siginfo->si_signo); > + pr_warning("Process %s:%d received signr %d and should have core > dumped\n", > + current->comm, current->pid, cprm->siginfo->si_signo); Prefer pr_warn > return(1); > } > > @@ -190,17 +182,17 @@ static int decompress_exec( > loff_t fpos; > int ret, retval; > > - DBG_FLT("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, > len); > + pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, > len); Generally unnecessary as the function tracer works well > > memset(, 0, sizeof(strm)); > strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); > if (strm.workspace == NULL) { > - DBG_FLT("binfmt_flat: no memory for decompress workspace\n"); > + pr_debug("no memory for decompress workspace\n"); > return -ENOMEM; > } > buf = kmalloc(LBUFSIZE, GFP_KERNEL); > if (buf == NULL) { > - DBG_FLT("binfmt_flat: no memory for read buffer\n"); > + pr_debug("no memory for read buffer\n"); Unnecessary OOM messages as allocs do a stack dump
Re: [PATCH v3 02/12] binfmt_flat: convert printk invocations to their modern form
On Wed, 2016-07-20 at 00:20 -0400, Nicolas Pitre wrote: > diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c [] > @@ -15,6 +15,8 @@ > * JAN/99 -- coded full program relocation (g...@snapgear.com) > */ > > +#define pr_fmt(fmt) "BINFMT_FLAT: : " fmt Why the double colon? Much more common would be #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > @@ -106,8 +98,8 @@ static struct linux_binfmt flat_format = { > > static int flat_core_dump(struct coredump_params *cprm) > { > - printk("Process %s:%d received signr %d and should have core dumped\n", > - current->comm, current->pid, cprm->siginfo->si_signo); > + pr_warning("Process %s:%d received signr %d and should have core > dumped\n", > + current->comm, current->pid, cprm->siginfo->si_signo); Prefer pr_warn > return(1); > } > > @@ -190,17 +182,17 @@ static int decompress_exec( > loff_t fpos; > int ret, retval; > > - DBG_FLT("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, > len); > + pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, > len); Generally unnecessary as the function tracer works well > > memset(, 0, sizeof(strm)); > strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); > if (strm.workspace == NULL) { > - DBG_FLT("binfmt_flat: no memory for decompress workspace\n"); > + pr_debug("no memory for decompress workspace\n"); > return -ENOMEM; > } > buf = kmalloc(LBUFSIZE, GFP_KERNEL); > if (buf == NULL) { > - DBG_FLT("binfmt_flat: no memory for read buffer\n"); > + pr_debug("no memory for read buffer\n"); Unnecessary OOM messages as allocs do a stack dump
[PATCH] iio: accel: bma180: use iio helper function to guarantee direct mode
Replace the code that guarantees the device stays in direct mode with iio_device_claim_direct_mode() which does same. Signed-off-by: Alison SchofieldCc: Daniel Baluta --- Peter: I was not clear if we want to keep the data->mutex lock in addition to claiming direct mode. I see that lock assuring exclusivity amongst a few other tasks in the driver. Let me know if this needs both locks. Thanks! drivers/iio/accel/bma180.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index e3f88ba..ce5a476 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -469,13 +469,12 @@ static int bma180_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(>mutex); - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(>mutex); - return -EBUSY; - } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = bma180_get_data_reg(data, chan->scan_index); - mutex_unlock(>mutex); + iio_device_release_direct_mode(indio_dev); if (ret < 0) return ret; *val = sign_extend32(ret >> chan->scan_type.shift, -- 2.1.4
[PATCH] iio: accel: bma180: use iio helper function to guarantee direct mode
Replace the code that guarantees the device stays in direct mode with iio_device_claim_direct_mode() which does same. Signed-off-by: Alison Schofield Cc: Daniel Baluta --- Peter: I was not clear if we want to keep the data->mutex lock in addition to claiming direct mode. I see that lock assuring exclusivity amongst a few other tasks in the driver. Let me know if this needs both locks. Thanks! drivers/iio/accel/bma180.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index e3f88ba..ce5a476 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -469,13 +469,12 @@ static int bma180_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(>mutex); - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(>mutex); - return -EBUSY; - } + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = bma180_get_data_reg(data, chan->scan_index); - mutex_unlock(>mutex); + iio_device_release_direct_mode(indio_dev); if (ret < 0) return ret; *val = sign_extend32(ret >> chan->scan_type.shift, -- 2.1.4
[PATCH v3 02/12] binfmt_flat: convert printk invocations to their modern form
Signed-off-by: Nicolas Pitre--- fs/binfmt_flat.c | 118 --- 1 file changed, 51 insertions(+), 67 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 085059d879..36f5bb6b2c 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -15,6 +15,8 @@ * JAN/99 -- coded full program relocation (g...@snapgear.com) */ +#define pr_fmt(fmt)"BINFMT_FLAT: : " fmt + #include #include #include @@ -44,16 +46,6 @@ // -#if 0 -#define DEBUG 1 -#endif - -#ifdef DEBUG -#defineDBG_FLT(a...) printk(a) -#else -#defineDBG_FLT(a...) -#endif - /* * User data (data section and bss) needs to be aligned. * We pick 0x20 here because it is the max value elf2flt has always @@ -106,8 +98,8 @@ static struct linux_binfmt flat_format = { static int flat_core_dump(struct coredump_params *cprm) { - printk("Process %s:%d received signr %d and should have core dumped\n", - current->comm, current->pid, cprm->siginfo->si_signo); + pr_warning("Process %s:%d received signr %d and should have core dumped\n", + current->comm, current->pid, cprm->siginfo->si_signo); return(1); } @@ -190,17 +182,17 @@ static int decompress_exec( loff_t fpos; int ret, retval; - DBG_FLT("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, len); + pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, len); memset(, 0, sizeof(strm)); strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); if (strm.workspace == NULL) { - DBG_FLT("binfmt_flat: no memory for decompress workspace\n"); + pr_debug("no memory for decompress workspace\n"); return -ENOMEM; } buf = kmalloc(LBUFSIZE, GFP_KERNEL); if (buf == NULL) { - DBG_FLT("binfmt_flat: no memory for read buffer\n"); + pr_debug("no memory for read buffer\n"); retval = -ENOMEM; goto out_free; } @@ -218,25 +210,25 @@ static int decompress_exec( /* Check minimum size -- gzip header */ if (ret < 10) { - DBG_FLT("binfmt_flat: file too small?\n"); + pr_debug("file too small?\n"); goto out_free_buf; } /* Check gzip magic number */ if ((buf[0] != 037) || ((buf[1] != 0213) && (buf[1] != 0236))) { - DBG_FLT("binfmt_flat: unknown compression magic?\n"); + pr_debug("unknown compression magic?\n"); goto out_free_buf; } /* Check gzip method */ if (buf[2] != 8) { - DBG_FLT("binfmt_flat: unknown compression method?\n"); + pr_debug("unknown compression method?\n"); goto out_free_buf; } /* Check gzip flags */ if ((buf[3] & ENCRYPTED) || (buf[3] & CONTINUATION) || (buf[3] & RESERVED)) { - DBG_FLT("binfmt_flat: unknown flags?\n"); + pr_debug("unknown flags?\n"); goto out_free_buf; } @@ -244,7 +236,7 @@ static int decompress_exec( if (buf[3] & EXTRA_FIELD) { ret += 2 + buf[10] + (buf[11] << 8); if (unlikely(LBUFSIZE <= ret)) { - DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n"); + pr_debug("buffer overflow (EXTRA)?\n"); goto out_free_buf; } } @@ -252,7 +244,7 @@ static int decompress_exec( while (ret < LBUFSIZE && buf[ret++] != 0) ; if (unlikely(LBUFSIZE == ret)) { - DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n"); + pr_debug("buffer overflow (ORIG_NAME)?\n"); goto out_free_buf; } } @@ -260,7 +252,7 @@ static int decompress_exec( while (ret < LBUFSIZE && buf[ret++] != 0) ; if (unlikely(LBUFSIZE == ret)) { - DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n"); + pr_debug("buffer overflow (COMMENT)?\n"); goto out_free_buf; } } @@ -273,7 +265,7 @@ static int decompress_exec( strm.total_out = 0; if (zlib_inflateInit2(, -MAX_WBITS) != Z_OK) { - DBG_FLT("binfmt_flat: zlib init failed?\n"); + pr_debug("zlib init failed?\n"); goto out_free_buf; } @@ -290,7 +282,7 @@ static int decompress_exec( } if (ret < 0) { - DBG_FLT("binfmt_flat: decompression failed (%d), %s\n", + pr_debug("decompression failed (%d), %s\n",
[PATCH v3 04/12] elf_fdpic_transfer_args_to_stack(): make it generic
This copying of arguments and environment is common to both NOMMU binary formats we support. Let's make the elf_fdpic version available to the flat format as well. While at it, improve the code a bit not to copy below the actual data area. Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/binfmt_elf_fdpic.c | 38 ++ fs/exec.c | 33 + include/linux/binfmts.h | 2 ++ 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 203589311b..464a972e88 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -67,8 +67,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *, struct mm_struct *, struct elf_fdpic_params *); #ifndef CONFIG_MMU -static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *, - unsigned long *); static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *, struct file *, struct mm_struct *); @@ -515,8 +513,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, sp = mm->start_stack; /* stack the program arguments and environment */ - if (elf_fdpic_transfer_args_to_stack(bprm, ) < 0) + if (transfer_args_to_stack(bprm, ) < 0) return -EFAULT; + sp &= ~15; #endif /* @@ -711,39 +710,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, /*/ /* - * transfer the program arguments and environment from the holding pages onto - * the stack - */ -#ifndef CONFIG_MMU -static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, - unsigned long *_sp) -{ - unsigned long index, stop, sp; - char *src; - int ret = 0; - - stop = bprm->p >> PAGE_SHIFT; - sp = *_sp; - - for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { - src = kmap(bprm->page[index]); - sp -= PAGE_SIZE; - if (copy_to_user((void *) sp, src, PAGE_SIZE) != 0) - ret = -EFAULT; - kunmap(bprm->page[index]); - if (ret < 0) - goto out; - } - - *_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15; - -out: - return ret; -} -#endif - -/*/ -/* * load the appropriate binary image (executable or interpreter) into memory * - we assume no MMU is available * - if no other PIC bits are set in params->hdr->e_flags diff --git a/fs/exec.c b/fs/exec.c index 887c1c955d..ef0df2f092 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -762,6 +762,39 @@ out_unlock: } EXPORT_SYMBOL(setup_arg_pages); +#else + +/* + * Transfer the program arguments and environment from the holding pages + * onto the stack. The provided stack pointer is adjusted accordingly. + */ +int transfer_args_to_stack(struct linux_binprm *bprm, + unsigned long *sp_location) +{ + unsigned long index, stop, sp; + int ret = 0; + + stop = bprm->p >> PAGE_SHIFT; + sp = *sp_location; + + for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { + unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0; + char *src = kmap(bprm->page[index]) + offset; + sp -= PAGE_SIZE - offset; + if (copy_to_user((void *) sp, src, PAGE_SIZE - offset) != 0) + ret = -EFAULT; + kunmap(bprm->page[index]); + if (ret) + goto out; + } + + *sp_location = sp; + +out: + return ret; +} +EXPORT_SYMBOL(transfer_args_to_stack); + #endif /* CONFIG_MMU */ static struct file *do_open_execat(int fd, struct filename *name, int flags) diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 314b3caa70..1303b570b1 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -113,6 +113,8 @@ extern int suid_dumpable; extern int setup_arg_pages(struct linux_binprm * bprm, unsigned long stack_top, int executable_stack); +extern int transfer_args_to_stack(struct linux_binprm *bprm, + unsigned long *sp_location); extern int bprm_change_interp(char *interp, struct linux_binprm *bprm); extern int copy_strings_kernel(int argc, const char *const *argv, struct linux_binprm *bprm); -- 2.7.4
[PATCH v3 08/12] binfmt_flat: use proper user space accessors with old relocs code
Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 34f815540e..28fc272d9a 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -383,36 +383,39 @@ static void old_reloc(unsigned long rl) { static const char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" }; flat_v2_reloc_t r; - unsigned long *ptr; + unsigned long __user *ptr; + unsigned long val; r.value = rl; #if defined(CONFIG_COLDFIRE) - ptr = (unsigned long *) (current->mm->start_code + r.reloc.offset); + ptr = (unsigned long __user *)(current->mm->start_code + r.reloc.offset); #else - ptr = (unsigned long *) (current->mm->start_data + r.reloc.offset); + ptr = (unsigned long __user *)(current->mm->start_data + r.reloc.offset); #endif + __get_user(val, ptr); pr_debug("Relocation of variable at DATASEG+%x " "(address %p, currently %lx) into segment %s\n", -r.reloc.offset, ptr, *ptr, segment[r.reloc.type]); +r.reloc.offset, ptr, val, segment[r.reloc.type]); switch (r.reloc.type) { case OLD_FLAT_RELOC_TYPE_TEXT: - *ptr += current->mm->start_code; + val += current->mm->start_code; break; case OLD_FLAT_RELOC_TYPE_DATA: - *ptr += current->mm->start_data; + val += current->mm->start_data; break; case OLD_FLAT_RELOC_TYPE_BSS: - *ptr += current->mm->end_data; + val += current->mm->end_data; break; default: pr_err("Unknown relocation type=%x\n", r.reloc.type); break; } + __put_user(val, ptr); - pr_debug("Relocation became %lx\n", *ptr); -} + pr_debug("Relocation became %lx\n", val); +} // @@ -783,8 +786,13 @@ static int load_flat_file(struct linux_binprm * bprm, } } } else { - for (i=0; i < relocs; i++) - old_reloc(ntohl(reloc[i])); + for (i=0; i < relocs; i++) { + unsigned long relval; + if (get_user(relval, reloc + i)) + return -EFAULT; + relval = ntohl(relval); + old_reloc(relval); + } } flush_icache_range(start_code, end_code); -- 2.7.4
[PATCH v3 07/12] binfmt_flat: use proper user space accessors with relocs processing code
Relocs are fixed up in place in user space memory. The appropriate accessors are required for this code to work with an active MMU. The architecture specific handlers for ARM and M68K are also covered. SuperH and Xtensa are left out as they doesn't implement __get_user_unaligned() and __put_user_unaligned() yet. The other architectures that use BFLT don't have any MMU. Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- arch/arm/include/asm/flat.h | 5 +++-- arch/m68k/include/asm/flat.h | 5 +++-- fs/binfmt_flat.c | 31 +++ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h index e847d23351..acf1d14b89 100644 --- a/arch/arm/include/asm/flat.h +++ b/arch/arm/include/asm/flat.h @@ -8,8 +8,9 @@ #defineflat_argvp_envp_on_stack() 1 #defineflat_old_ram_flag(flags)(flags) #defineflat_reloc_valid(reloc, size) ((reloc) <= (size)) -#defineflat_get_addr_from_rp(rp, relval, flags, persistent) ((void)persistent,get_unaligned(rp)) -#defineflat_put_addr_at_rp(rp, val, relval)put_unaligned(val,rp) +#defineflat_get_addr_from_rp(rp, relval, flags, persistent) \ + ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; }) +#defineflat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp) #defineflat_get_relocate_addr(rel) (rel) #defineflat_set_persistent(relval, p) 0 diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h index f9454b89a5..f3f592d03e 100644 --- a/arch/m68k/include/asm/flat.h +++ b/arch/m68k/include/asm/flat.h @@ -8,8 +8,9 @@ #defineflat_argvp_envp_on_stack() 1 #defineflat_old_ram_flag(flags)(flags) #defineflat_reloc_valid(reloc, size) ((reloc) <= (size)) -#defineflat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp) -#defineflat_put_addr_at_rp(rp, val, relval)put_unaligned(val,rp) +#defineflat_get_addr_from_rp(rp, relval, flags, p) \ + ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; }) +#defineflat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp) #defineflat_get_relocate_addr(rel) (rel) static inline int flat_set_persistent(unsigned long relval, diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 90a10d7149..34f815540e 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -423,7 +423,7 @@ static int load_flat_file(struct linux_binprm * bprm, unsigned long textpos, datapos, realdatastart; unsigned long text_len, data_len, bss_len, stack_len, full_data, flags; unsigned long len, memp, memp_size, extra, rlim; - unsigned long *reloc, *rp; + unsigned long __user *reloc, *rp; struct inode *inode; int i, rev, relocs; loff_t fpos; @@ -595,7 +595,7 @@ static int load_flat_file(struct linux_binprm * bprm, goto err; } - reloc = (unsigned long *) + reloc = (unsigned long __user *) (datapos + (ntohl(hdr->reloc_start) - text_len)); memp = realdatastart; memp_size = len; @@ -620,7 +620,7 @@ static int load_flat_file(struct linux_binprm * bprm, MAX_SHARED_LIBS * sizeof(unsigned long), FLAT_DATA_ALIGN); - reloc = (unsigned long *) + reloc = (unsigned long __user *) (datapos + (ntohl(hdr->reloc_start) - text_len)); memp = textpos; memp_size = len; @@ -713,15 +713,20 @@ static int load_flat_file(struct linux_binprm * bprm, * image. */ if (flags & FLAT_FLAG_GOTPIC) { - for (rp = (unsigned long *)datapos; *rp != 0x; rp++) { - unsigned long addr; - if (*rp) { - addr = calc_reloc(*rp, libinfo, id, 0); + for (rp = (unsigned long __user *)datapos; ; rp++) { + unsigned long addr, rp_val; + if (get_user(rp_val, rp)) + return -EFAULT; + if (rp_val == 0x) + break; + if (rp_val) { + addr = calc_reloc(rp_val, libinfo, id, 0); if (addr == RELOC_FAILED) { ret = -ENOEXEC; goto err; } - *rp = addr; + if (put_user(addr, rp)) + return
[PATCH v3 02/12] binfmt_flat: convert printk invocations to their modern form
Signed-off-by: Nicolas Pitre --- fs/binfmt_flat.c | 118 --- 1 file changed, 51 insertions(+), 67 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 085059d879..36f5bb6b2c 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -15,6 +15,8 @@ * JAN/99 -- coded full program relocation (g...@snapgear.com) */ +#define pr_fmt(fmt)"BINFMT_FLAT: : " fmt + #include #include #include @@ -44,16 +46,6 @@ // -#if 0 -#define DEBUG 1 -#endif - -#ifdef DEBUG -#defineDBG_FLT(a...) printk(a) -#else -#defineDBG_FLT(a...) -#endif - /* * User data (data section and bss) needs to be aligned. * We pick 0x20 here because it is the max value elf2flt has always @@ -106,8 +98,8 @@ static struct linux_binfmt flat_format = { static int flat_core_dump(struct coredump_params *cprm) { - printk("Process %s:%d received signr %d and should have core dumped\n", - current->comm, current->pid, cprm->siginfo->si_signo); + pr_warning("Process %s:%d received signr %d and should have core dumped\n", + current->comm, current->pid, cprm->siginfo->si_signo); return(1); } @@ -190,17 +182,17 @@ static int decompress_exec( loff_t fpos; int ret, retval; - DBG_FLT("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, len); + pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, len); memset(, 0, sizeof(strm)); strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); if (strm.workspace == NULL) { - DBG_FLT("binfmt_flat: no memory for decompress workspace\n"); + pr_debug("no memory for decompress workspace\n"); return -ENOMEM; } buf = kmalloc(LBUFSIZE, GFP_KERNEL); if (buf == NULL) { - DBG_FLT("binfmt_flat: no memory for read buffer\n"); + pr_debug("no memory for read buffer\n"); retval = -ENOMEM; goto out_free; } @@ -218,25 +210,25 @@ static int decompress_exec( /* Check minimum size -- gzip header */ if (ret < 10) { - DBG_FLT("binfmt_flat: file too small?\n"); + pr_debug("file too small?\n"); goto out_free_buf; } /* Check gzip magic number */ if ((buf[0] != 037) || ((buf[1] != 0213) && (buf[1] != 0236))) { - DBG_FLT("binfmt_flat: unknown compression magic?\n"); + pr_debug("unknown compression magic?\n"); goto out_free_buf; } /* Check gzip method */ if (buf[2] != 8) { - DBG_FLT("binfmt_flat: unknown compression method?\n"); + pr_debug("unknown compression method?\n"); goto out_free_buf; } /* Check gzip flags */ if ((buf[3] & ENCRYPTED) || (buf[3] & CONTINUATION) || (buf[3] & RESERVED)) { - DBG_FLT("binfmt_flat: unknown flags?\n"); + pr_debug("unknown flags?\n"); goto out_free_buf; } @@ -244,7 +236,7 @@ static int decompress_exec( if (buf[3] & EXTRA_FIELD) { ret += 2 + buf[10] + (buf[11] << 8); if (unlikely(LBUFSIZE <= ret)) { - DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n"); + pr_debug("buffer overflow (EXTRA)?\n"); goto out_free_buf; } } @@ -252,7 +244,7 @@ static int decompress_exec( while (ret < LBUFSIZE && buf[ret++] != 0) ; if (unlikely(LBUFSIZE == ret)) { - DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n"); + pr_debug("buffer overflow (ORIG_NAME)?\n"); goto out_free_buf; } } @@ -260,7 +252,7 @@ static int decompress_exec( while (ret < LBUFSIZE && buf[ret++] != 0) ; if (unlikely(LBUFSIZE == ret)) { - DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n"); + pr_debug("buffer overflow (COMMENT)?\n"); goto out_free_buf; } } @@ -273,7 +265,7 @@ static int decompress_exec( strm.total_out = 0; if (zlib_inflateInit2(, -MAX_WBITS) != Z_OK) { - DBG_FLT("binfmt_flat: zlib init failed?\n"); + pr_debug("zlib init failed?\n"); goto out_free_buf; } @@ -290,7 +282,7 @@ static int decompress_exec( } if (ret < 0) { - DBG_FLT("binfmt_flat: decompression failed (%d), %s\n", + pr_debug("decompression failed (%d), %s\n", ret, strm.msg);
[PATCH v3 04/12] elf_fdpic_transfer_args_to_stack(): make it generic
This copying of arguments and environment is common to both NOMMU binary formats we support. Let's make the elf_fdpic version available to the flat format as well. While at it, improve the code a bit not to copy below the actual data area. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_elf_fdpic.c | 38 ++ fs/exec.c | 33 + include/linux/binfmts.h | 2 ++ 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 203589311b..464a972e88 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -67,8 +67,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *, struct mm_struct *, struct elf_fdpic_params *); #ifndef CONFIG_MMU -static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *, - unsigned long *); static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *, struct file *, struct mm_struct *); @@ -515,8 +513,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, sp = mm->start_stack; /* stack the program arguments and environment */ - if (elf_fdpic_transfer_args_to_stack(bprm, ) < 0) + if (transfer_args_to_stack(bprm, ) < 0) return -EFAULT; + sp &= ~15; #endif /* @@ -711,39 +710,6 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, /*/ /* - * transfer the program arguments and environment from the holding pages onto - * the stack - */ -#ifndef CONFIG_MMU -static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, - unsigned long *_sp) -{ - unsigned long index, stop, sp; - char *src; - int ret = 0; - - stop = bprm->p >> PAGE_SHIFT; - sp = *_sp; - - for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { - src = kmap(bprm->page[index]); - sp -= PAGE_SIZE; - if (copy_to_user((void *) sp, src, PAGE_SIZE) != 0) - ret = -EFAULT; - kunmap(bprm->page[index]); - if (ret < 0) - goto out; - } - - *_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15; - -out: - return ret; -} -#endif - -/*/ -/* * load the appropriate binary image (executable or interpreter) into memory * - we assume no MMU is available * - if no other PIC bits are set in params->hdr->e_flags diff --git a/fs/exec.c b/fs/exec.c index 887c1c955d..ef0df2f092 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -762,6 +762,39 @@ out_unlock: } EXPORT_SYMBOL(setup_arg_pages); +#else + +/* + * Transfer the program arguments and environment from the holding pages + * onto the stack. The provided stack pointer is adjusted accordingly. + */ +int transfer_args_to_stack(struct linux_binprm *bprm, + unsigned long *sp_location) +{ + unsigned long index, stop, sp; + int ret = 0; + + stop = bprm->p >> PAGE_SHIFT; + sp = *sp_location; + + for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { + unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0; + char *src = kmap(bprm->page[index]) + offset; + sp -= PAGE_SIZE - offset; + if (copy_to_user((void *) sp, src, PAGE_SIZE - offset) != 0) + ret = -EFAULT; + kunmap(bprm->page[index]); + if (ret) + goto out; + } + + *sp_location = sp; + +out: + return ret; +} +EXPORT_SYMBOL(transfer_args_to_stack); + #endif /* CONFIG_MMU */ static struct file *do_open_execat(int fd, struct filename *name, int flags) diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 314b3caa70..1303b570b1 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -113,6 +113,8 @@ extern int suid_dumpable; extern int setup_arg_pages(struct linux_binprm * bprm, unsigned long stack_top, int executable_stack); +extern int transfer_args_to_stack(struct linux_binprm *bprm, + unsigned long *sp_location); extern int bprm_change_interp(char *interp, struct linux_binprm *bprm); extern int copy_strings_kernel(int argc, const char *const *argv, struct linux_binprm *bprm); -- 2.7.4
[PATCH v3 08/12] binfmt_flat: use proper user space accessors with old relocs code
Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 34f815540e..28fc272d9a 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -383,36 +383,39 @@ static void old_reloc(unsigned long rl) { static const char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" }; flat_v2_reloc_t r; - unsigned long *ptr; + unsigned long __user *ptr; + unsigned long val; r.value = rl; #if defined(CONFIG_COLDFIRE) - ptr = (unsigned long *) (current->mm->start_code + r.reloc.offset); + ptr = (unsigned long __user *)(current->mm->start_code + r.reloc.offset); #else - ptr = (unsigned long *) (current->mm->start_data + r.reloc.offset); + ptr = (unsigned long __user *)(current->mm->start_data + r.reloc.offset); #endif + __get_user(val, ptr); pr_debug("Relocation of variable at DATASEG+%x " "(address %p, currently %lx) into segment %s\n", -r.reloc.offset, ptr, *ptr, segment[r.reloc.type]); +r.reloc.offset, ptr, val, segment[r.reloc.type]); switch (r.reloc.type) { case OLD_FLAT_RELOC_TYPE_TEXT: - *ptr += current->mm->start_code; + val += current->mm->start_code; break; case OLD_FLAT_RELOC_TYPE_DATA: - *ptr += current->mm->start_data; + val += current->mm->start_data; break; case OLD_FLAT_RELOC_TYPE_BSS: - *ptr += current->mm->end_data; + val += current->mm->end_data; break; default: pr_err("Unknown relocation type=%x\n", r.reloc.type); break; } + __put_user(val, ptr); - pr_debug("Relocation became %lx\n", *ptr); -} + pr_debug("Relocation became %lx\n", val); +} // @@ -783,8 +786,13 @@ static int load_flat_file(struct linux_binprm * bprm, } } } else { - for (i=0; i < relocs; i++) - old_reloc(ntohl(reloc[i])); + for (i=0; i < relocs; i++) { + unsigned long relval; + if (get_user(relval, reloc + i)) + return -EFAULT; + relval = ntohl(relval); + old_reloc(relval); + } } flush_icache_range(start_code, end_code); -- 2.7.4
[PATCH v3 07/12] binfmt_flat: use proper user space accessors with relocs processing code
Relocs are fixed up in place in user space memory. The appropriate accessors are required for this code to work with an active MMU. The architecture specific handlers for ARM and M68K are also covered. SuperH and Xtensa are left out as they doesn't implement __get_user_unaligned() and __put_user_unaligned() yet. The other architectures that use BFLT don't have any MMU. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- arch/arm/include/asm/flat.h | 5 +++-- arch/m68k/include/asm/flat.h | 5 +++-- fs/binfmt_flat.c | 31 +++ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h index e847d23351..acf1d14b89 100644 --- a/arch/arm/include/asm/flat.h +++ b/arch/arm/include/asm/flat.h @@ -8,8 +8,9 @@ #defineflat_argvp_envp_on_stack() 1 #defineflat_old_ram_flag(flags)(flags) #defineflat_reloc_valid(reloc, size) ((reloc) <= (size)) -#defineflat_get_addr_from_rp(rp, relval, flags, persistent) ((void)persistent,get_unaligned(rp)) -#defineflat_put_addr_at_rp(rp, val, relval)put_unaligned(val,rp) +#defineflat_get_addr_from_rp(rp, relval, flags, persistent) \ + ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; }) +#defineflat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp) #defineflat_get_relocate_addr(rel) (rel) #defineflat_set_persistent(relval, p) 0 diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h index f9454b89a5..f3f592d03e 100644 --- a/arch/m68k/include/asm/flat.h +++ b/arch/m68k/include/asm/flat.h @@ -8,8 +8,9 @@ #defineflat_argvp_envp_on_stack() 1 #defineflat_old_ram_flag(flags)(flags) #defineflat_reloc_valid(reloc, size) ((reloc) <= (size)) -#defineflat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp) -#defineflat_put_addr_at_rp(rp, val, relval)put_unaligned(val,rp) +#defineflat_get_addr_from_rp(rp, relval, flags, p) \ + ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; }) +#defineflat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp) #defineflat_get_relocate_addr(rel) (rel) static inline int flat_set_persistent(unsigned long relval, diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 90a10d7149..34f815540e 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -423,7 +423,7 @@ static int load_flat_file(struct linux_binprm * bprm, unsigned long textpos, datapos, realdatastart; unsigned long text_len, data_len, bss_len, stack_len, full_data, flags; unsigned long len, memp, memp_size, extra, rlim; - unsigned long *reloc, *rp; + unsigned long __user *reloc, *rp; struct inode *inode; int i, rev, relocs; loff_t fpos; @@ -595,7 +595,7 @@ static int load_flat_file(struct linux_binprm * bprm, goto err; } - reloc = (unsigned long *) + reloc = (unsigned long __user *) (datapos + (ntohl(hdr->reloc_start) - text_len)); memp = realdatastart; memp_size = len; @@ -620,7 +620,7 @@ static int load_flat_file(struct linux_binprm * bprm, MAX_SHARED_LIBS * sizeof(unsigned long), FLAT_DATA_ALIGN); - reloc = (unsigned long *) + reloc = (unsigned long __user *) (datapos + (ntohl(hdr->reloc_start) - text_len)); memp = textpos; memp_size = len; @@ -713,15 +713,20 @@ static int load_flat_file(struct linux_binprm * bprm, * image. */ if (flags & FLAT_FLAG_GOTPIC) { - for (rp = (unsigned long *)datapos; *rp != 0x; rp++) { - unsigned long addr; - if (*rp) { - addr = calc_reloc(*rp, libinfo, id, 0); + for (rp = (unsigned long __user *)datapos; ; rp++) { + unsigned long addr, rp_val; + if (get_user(rp_val, rp)) + return -EFAULT; + if (rp_val == 0x) + break; + if (rp_val) { + addr = calc_reloc(rp_val, libinfo, id, 0); if (addr == RELOC_FAILED) { ret = -ENOEXEC; goto err; } - *rp = addr; + if (put_user(addr, rp)) + return -EFAULT; }
Re: [v2,1/2] refactor code parsing size based on memory range
Ping.. On Friday 24 June 2016 10:45 PM, Hari Bathini wrote: On 06/24/2016 10:56 AM, Michael Ellerman wrote: On Wed, 2016-22-06 at 19:25:26 UTC, Hari Bathini wrote: Currently, crashkernel parameter supports the below syntax to parse size based on memory range: crashkernel=:[,:,...] While such parsing is implemented for crashkernel parameter, it applies to other parameters with similar syntax. So, move this code to a more generic place for code reuse. Cc: Eric BiedermanCc: Vivek Goyal Cc: Rusty Russell Cc: ke...@lists.infradead.org Signed-off-by: Hari Bathini Hari, it's not immediately clear that this makes no change to the logic in the kexec code. Can you reply with a longer change log explaining why the old & new logic is the same for kexec. Hi Michael, Please consider this changelog for this patch: -- crashkernel parameter supports different syntaxes to specify the amount of memory to be reserved for kdump kernel. Below is one of the supported syntaxes that needs parsing to find the memory size to reserve, based on memory range: crashkernel=:[,:,...] While such parsing is implemented for crashkernel parameter, it applies to other parameters, like fadump_reserve_mem, which could use similar syntax. So, to reuse code, moving the code that checks if the parameter syntax is as above and also the code that parses memory size to reserve, for this syntax. While the code is moved to kernel/params.c file, there is no change in logic for crashkernel parameter parsing as the moved code is invoked with function calls at appropriate places. -- Thanks Hari diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 94aa10f..72f55e5 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -436,6 +436,11 @@ extern char *get_options(const char *str, int nints, int *ints); extern unsigned long long memparse(const char *ptr, char **retptr); extern bool parse_option_str(const char *str, const char *option); +extern bool __init is_param_range_based(const char *cmdline); +extern unsigned long long __init parse_mem_range_size(const char *param, + char **str, + unsigned long long system_ram); + extern int core_kernel_text(unsigned long addr); extern int core_kernel_data(unsigned long addr); extern int __kernel_text_address(unsigned long addr); diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 56b3ed0..d43f5cc 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1083,59 +1083,9 @@ static int __init parse_crashkernel_mem(char *cmdline, char *cur = cmdline, *tmp; /* for each entry of the comma-separated list */ -do { -unsigned long long start, end = ULLONG_MAX, size; - -/* get the start of the range */ -start = memparse(cur, ); -if (cur == tmp) { -pr_warn("crashkernel: Memory value expected\n"); -return -EINVAL; -} -cur = tmp; -if (*cur != '-') { -pr_warn("crashkernel: '-' expected\n"); -return -EINVAL; -} -cur++; - -/* if no ':' is here, than we read the end */ -if (*cur != ':') { -end = memparse(cur, ); -if (cur == tmp) { -pr_warn("crashkernel: Memory value expected\n"); -return -EINVAL; -} -cur = tmp; -if (end <= start) { -pr_warn("crashkernel: end <= start\n"); -return -EINVAL; -} -} - -if (*cur != ':') { -pr_warn("crashkernel: ':' expected\n"); -return -EINVAL; -} -cur++; - -size = memparse(cur, ); -if (cur == tmp) { -pr_warn("Memory value expected\n"); -return -EINVAL; -} -cur = tmp; -if (size >= system_ram) { -pr_warn("crashkernel: invalid size\n"); -return -EINVAL; -} - -/* match ? */ -if (system_ram >= start && system_ram < end) { -*crash_size = size; -break; -} -} while (*cur++ == ','); +*crash_size = parse_mem_range_size("crashkernel", , system_ram); +if (cur == cmdline) +return -EINVAL; if (*crash_size > 0) { while (*cur && *cur != ' ' && *cur != '@') @@ -1272,7 +1222,6 @@ static int __init __parse_crashkernel(char *cmdline, const char *name, const char *suffix) { -char*first_colon, *first_space; char*ck_cmdline; BUG_ON(!crash_size || !crash_base); @@ -1290,12 +1239,10 @@ static int __init __parse_crashkernel(char *cmdline, return parse_crashkernel_suffix(ck_cmdline, crash_size, suffix); /* - * if the commandline contains a ':', then that's
Re: [v2,1/2] refactor code parsing size based on memory range
Ping.. On Friday 24 June 2016 10:45 PM, Hari Bathini wrote: On 06/24/2016 10:56 AM, Michael Ellerman wrote: On Wed, 2016-22-06 at 19:25:26 UTC, Hari Bathini wrote: Currently, crashkernel parameter supports the below syntax to parse size based on memory range: crashkernel=:[,:,...] While such parsing is implemented for crashkernel parameter, it applies to other parameters with similar syntax. So, move this code to a more generic place for code reuse. Cc: Eric Biederman Cc: Vivek Goyal Cc: Rusty Russell Cc: ke...@lists.infradead.org Signed-off-by: Hari Bathini Hari, it's not immediately clear that this makes no change to the logic in the kexec code. Can you reply with a longer change log explaining why the old & new logic is the same for kexec. Hi Michael, Please consider this changelog for this patch: -- crashkernel parameter supports different syntaxes to specify the amount of memory to be reserved for kdump kernel. Below is one of the supported syntaxes that needs parsing to find the memory size to reserve, based on memory range: crashkernel=:[,:,...] While such parsing is implemented for crashkernel parameter, it applies to other parameters, like fadump_reserve_mem, which could use similar syntax. So, to reuse code, moving the code that checks if the parameter syntax is as above and also the code that parses memory size to reserve, for this syntax. While the code is moved to kernel/params.c file, there is no change in logic for crashkernel parameter parsing as the moved code is invoked with function calls at appropriate places. -- Thanks Hari diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 94aa10f..72f55e5 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -436,6 +436,11 @@ extern char *get_options(const char *str, int nints, int *ints); extern unsigned long long memparse(const char *ptr, char **retptr); extern bool parse_option_str(const char *str, const char *option); +extern bool __init is_param_range_based(const char *cmdline); +extern unsigned long long __init parse_mem_range_size(const char *param, + char **str, + unsigned long long system_ram); + extern int core_kernel_text(unsigned long addr); extern int core_kernel_data(unsigned long addr); extern int __kernel_text_address(unsigned long addr); diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 56b3ed0..d43f5cc 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1083,59 +1083,9 @@ static int __init parse_crashkernel_mem(char *cmdline, char *cur = cmdline, *tmp; /* for each entry of the comma-separated list */ -do { -unsigned long long start, end = ULLONG_MAX, size; - -/* get the start of the range */ -start = memparse(cur, ); -if (cur == tmp) { -pr_warn("crashkernel: Memory value expected\n"); -return -EINVAL; -} -cur = tmp; -if (*cur != '-') { -pr_warn("crashkernel: '-' expected\n"); -return -EINVAL; -} -cur++; - -/* if no ':' is here, than we read the end */ -if (*cur != ':') { -end = memparse(cur, ); -if (cur == tmp) { -pr_warn("crashkernel: Memory value expected\n"); -return -EINVAL; -} -cur = tmp; -if (end <= start) { -pr_warn("crashkernel: end <= start\n"); -return -EINVAL; -} -} - -if (*cur != ':') { -pr_warn("crashkernel: ':' expected\n"); -return -EINVAL; -} -cur++; - -size = memparse(cur, ); -if (cur == tmp) { -pr_warn("Memory value expected\n"); -return -EINVAL; -} -cur = tmp; -if (size >= system_ram) { -pr_warn("crashkernel: invalid size\n"); -return -EINVAL; -} - -/* match ? */ -if (system_ram >= start && system_ram < end) { -*crash_size = size; -break; -} -} while (*cur++ == ','); +*crash_size = parse_mem_range_size("crashkernel", , system_ram); +if (cur == cmdline) +return -EINVAL; if (*crash_size > 0) { while (*cur && *cur != ' ' && *cur != '@') @@ -1272,7 +1222,6 @@ static int __init __parse_crashkernel(char *cmdline, const char *name, const char *suffix) { -char*first_colon, *first_space; char*ck_cmdline; BUG_ON(!crash_size || !crash_base); @@ -1290,12 +1239,10 @@ static int __init __parse_crashkernel(char *cmdline, return parse_crashkernel_suffix(ck_cmdline, crash_size, suffix); /* - * if the commandline contains a ':', then that's the extended + * if the parameter is range based, then that's the extended * syntax
[PATCH v3 09/12] binfmt_flat: use clear_user() rather than memset() to clear .bss
This is needed on systems with a MMU. Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 28fc272d9a..0d89830f76 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -798,10 +798,11 @@ static int load_flat_file(struct linux_binprm * bprm, flush_icache_range(start_code, end_code); /* zero the BSS, BRK and stack areas */ - memset((void*)(datapos + data_len), 0, bss_len + + if (clear_user((void __user *)(datapos + data_len), bss_len + (memp + memp_size - stack_len - /* end brk */ libinfo->lib_list[id].start_brk) + /* start brk */ - stack_len); + stack_len)) + return -EFAULT; return 0; err: -- 2.7.4
[PATCH v3 06/12] binfmt_flat: clean up create_flat_tables() and stack accesses
In addition to better code clarity, this brings proper usage of user memory accessors everywhere the stack is touched. This is essential for making this work on MMU systems. Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 117 ++- 1 file changed, 63 insertions(+), 54 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index fdd33ba9e3..90a10d7149 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -107,50 +107,58 @@ static int flat_core_dump(struct coredump_params *cprm) /* * create_flat_tables() parses the env- and arg-strings in new user * memory and creates the pointer tables from them, and puts their - * addresses on the "stack", returning the new stack pointer value. + * addresses on the "stack", recording the new stack pointer value. */ -static unsigned long create_flat_tables( - unsigned long pp, - struct linux_binprm * bprm) +static int create_flat_tables(struct linux_binprm * bprm, unsigned long arg_start) { - unsigned long *argv,*envp; - unsigned long * sp; - char * p = (char*)pp; - int argc = bprm->argc; - int envc = bprm->envc; - char uninitialized_var(dummy); - - sp = (unsigned long *)p; - sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); - sp = (unsigned long *) ((unsigned long)sp & -FLAT_STACK_ALIGN); - argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); - envp = argv + (argc + 1); + char __user *p; + unsigned long __user *sp; + long i, len; + p = (char __user *)arg_start; + sp = (unsigned long __user *)current->mm->start_stack; + + sp -= bprm->envc + 1; + sp -= bprm->argc + 1; + sp -= flat_argvp_envp_on_stack() ? 2 : 0; + sp -= 1; /* */ + + current->mm->start_stack = (unsigned long)sp & -FLAT_STACK_ALIGN; + sp = (unsigned long __user *)current->mm->start_stack; + + __put_user(bprm->argc, sp++); if (flat_argvp_envp_on_stack()) { - put_user((unsigned long) envp, sp + 2); - put_user((unsigned long) argv, sp + 1); - } - - put_user(argc, sp); - current->mm->arg_start = (unsigned long) p; - while (argc-->0) { - put_user((unsigned long) p, argv++); - do { - get_user(dummy, p); p++; - } while (dummy); - } - put_user((unsigned long) NULL, argv); - current->mm->arg_end = current->mm->env_start = (unsigned long) p; - while (envc-->0) { - put_user((unsigned long)p, envp); envp++; - do { - get_user(dummy, p); p++; - } while (dummy); - } - put_user((unsigned long) NULL, envp); - current->mm->env_end = (unsigned long) p; - return (unsigned long)sp; + unsigned long argv, envp; + argv = (unsigned long)(sp + 2); + envp = (unsigned long)(sp + 2 + bprm->argc + 1); + __put_user(argv, sp++); + __put_user(envp, sp++); + } + + current->mm->arg_start = (unsigned long)p; + for (i = bprm->argc; i > 0; i--) { + __put_user((unsigned long)p, sp++); + len = strnlen_user(p, MAX_ARG_STRLEN); + if (!len || len > MAX_ARG_STRLEN) + return -EINVAL; + p += len; + } + __put_user(0, sp++); + current->mm->arg_end = (unsigned long)p; + + current->mm->env_start = (unsigned long) p; + for (i = bprm->envc; i > 0; i--) { + __put_user((unsigned long)p, sp++); + len = strnlen_user(p, MAX_ARG_STRLEN); + if (!len || len > MAX_ARG_STRLEN) + return -EINVAL; + p += len; + } + __put_user(0, sp++); + current->mm->env_end = (unsigned long)p; + + return 0; } // @@ -849,7 +857,7 @@ static int load_flat_binary(struct linux_binprm * bprm) { struct lib_info libinfo; struct pt_regs *regs = current_pt_regs(); - unsigned long sp, stack_len; + unsigned long stack_len; unsigned long start_addr; int res; int i, j; @@ -863,11 +871,10 @@ static int load_flat_binary(struct linux_binprm * bprm) * pedantic and include space for the argv/envp array as it may have * a lot of entries. */ -#define TOP_OF_ARGS (PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *)) - stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ - stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ - stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ - stack_len += FLAT_STACK_ALIGN - 1; /* reserve for upcoming alignment */ +
[PATCH v3 03/12] binfmt_flat: prevent kernel dammage from corrupted executable headers
Signed-off-by: Nicolas Pitre--- fs/binfmt_flat.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 36f5bb6b2c..9c76d9a222 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -470,6 +470,17 @@ static int load_flat_file(struct linux_binprm * bprm, } /* +* Make sure the header params are sane. +* 28 bits (256 MB) is way more than reasonable in this case. +* If some top bits are set we have probable binary corruption. + */ + if ((text_len | data_len | bss_len | stack_len | full_data) >> 28) { + pr_err("bad header\n"); + ret = -ENOEXEC; + goto err; + } + + /* * fix up the flags for the older format, there were all kinds * of endian hacks, this only works for the simple cases */ -- 2.7.4
[PATCH v3 12/12] binfmt_flat: allow compressed flat binary format to work on MMU systems
Let's take the simple and obvious approach by decompressing the binary into a kernel buffer and then copying it to user space. Those who are looking for top performance on an MMU system are unlikely to choose this executable format anyway. Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 44 ++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index d04188267a..8dac70921b 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -632,6 +633,7 @@ static int load_flat_file(struct linux_binprm * bprm, * load it all in and treat it like a RAM load from now on */ if (flags & FLAT_FLAG_GZIP) { +#ifndef CONFIG_MMU result = decompress_exec(bprm, sizeof (struct flat_hdr), (((char *) textpos) + sizeof (struct flat_hdr)), (text_len + full_data @@ -639,14 +641,52 @@ static int load_flat_file(struct linux_binprm * bprm, 0); memmove((void *) datapos, (void *) realdatastart, full_data); +#else + /* +* This is used on MMU systems mainly for testing. +* Let's use a kernel buffer to simplify things. +*/ + long unz_text_len = text_len - sizeof(struct flat_hdr); + long unz_len = unz_text_len + full_data; + char *unz_data = vmalloc(unz_len); + if (!unz_data) { + result = -ENOMEM; + } else { + result = decompress_exec(bprm, sizeof(struct flat_hdr), +unz_data, unz_len, 0); + if (result == 0 && + (copy_to_user((void __user *)textpos + sizeof(struct flat_hdr), + unz_data, unz_text_len) || +copy_to_user((void __user *)datapos, + unz_data + unz_text_len, full_data))) + result = -EFAULT; + vfree(unz_data); + } +#endif } else if (flags & FLAT_FLAG_GZDATA) { result = read_code(bprm->file, textpos, 0, text_len); - if (!IS_ERR_VALUE(result)) + if (!IS_ERR_VALUE(result)) { +#ifndef CONFIG_MMU result = decompress_exec(bprm, text_len, (char *) datapos, full_data, 0); +#else + char *unz_data = vmalloc(full_data); + if (!unz_data) { + result = -ENOMEM; + } else { + result = decompress_exec(bprm, text_len, + unz_data, full_data, 0); + if (result == 0 && + copy_to_user((void __user *)datapos, +unz_data, full_data)) + result = -EFAULT; + vfree(unz_data); + } +#endif + } } else -#endif +#endif /* CONFIG_BINFMT_ZFLAT */ { result = read_code(bprm->file, textpos, 0, text_len); if (!IS_ERR_VALUE(result)) -- 2.7.4
[PATCH v3 05/12] binfmt_flat: use generic transfer_args_to_stack()
This gets rid of the rather ugly, open coded and suboptimal copy code. Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 22 ++ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 9c76d9a222..fdd33ba9e3 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -849,10 +849,8 @@ static int load_flat_binary(struct linux_binprm * bprm) { struct lib_info libinfo; struct pt_regs *regs = current_pt_regs(); - unsigned long p = bprm->p; - unsigned long stack_len; + unsigned long sp, stack_len; unsigned long start_addr; - unsigned long *sp; int res; int i, j; @@ -887,15 +885,15 @@ static int load_flat_binary(struct linux_binprm * bprm) set_binfmt(_format); - p = ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4; - pr_debug("p=%lx\n", p); + sp = ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4; + pr_debug("sp=%lx\n", sp); - /* copy the arg pages onto the stack, this could be more efficient :-) */ - for (i = TOP_OF_ARGS - 1; i >= bprm->p; i--) - * (char *) --p = - ((char *) page_address(bprm->page[i/PAGE_SIZE]))[i % PAGE_SIZE]; + /* copy the arg pages onto the stack */ + res = transfer_args_to_stack(bprm, ); + if (res) + return res; - sp = (unsigned long *) create_flat_tables(p, bprm); + sp = create_flat_tables(sp, bprm); /* Fake some return addresses to ensure the call chain will * initialise library in order for us. We are required to call @@ -907,14 +905,14 @@ static int load_flat_binary(struct linux_binprm * bprm) for (i = MAX_SHARED_LIBS-1; i>0; i--) { if (libinfo.lib_list[i].loaded) { /* Push previos first to call address */ - --sp; put_user(start_addr, sp); + --sp; put_user(start_addr, (unsigned long *)sp); start_addr = libinfo.lib_list[i].entry; } } #endif /* Stash our initial stack pointer into the mm structure */ - current->mm->start_stack = (unsigned long )sp; + current->mm->start_stack = sp; #ifdef FLAT_PLAT_INIT FLAT_PLAT_INIT(regs); -- 2.7.4
[PATCH v3 09/12] binfmt_flat: use clear_user() rather than memset() to clear .bss
This is needed on systems with a MMU. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 28fc272d9a..0d89830f76 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -798,10 +798,11 @@ static int load_flat_file(struct linux_binprm * bprm, flush_icache_range(start_code, end_code); /* zero the BSS, BRK and stack areas */ - memset((void*)(datapos + data_len), 0, bss_len + + if (clear_user((void __user *)(datapos + data_len), bss_len + (memp + memp_size - stack_len - /* end brk */ libinfo->lib_list[id].start_brk) + /* start brk */ - stack_len); + stack_len)) + return -EFAULT; return 0; err: -- 2.7.4
[PATCH v3 06/12] binfmt_flat: clean up create_flat_tables() and stack accesses
In addition to better code clarity, this brings proper usage of user memory accessors everywhere the stack is touched. This is essential for making this work on MMU systems. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 117 ++- 1 file changed, 63 insertions(+), 54 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index fdd33ba9e3..90a10d7149 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -107,50 +107,58 @@ static int flat_core_dump(struct coredump_params *cprm) /* * create_flat_tables() parses the env- and arg-strings in new user * memory and creates the pointer tables from them, and puts their - * addresses on the "stack", returning the new stack pointer value. + * addresses on the "stack", recording the new stack pointer value. */ -static unsigned long create_flat_tables( - unsigned long pp, - struct linux_binprm * bprm) +static int create_flat_tables(struct linux_binprm * bprm, unsigned long arg_start) { - unsigned long *argv,*envp; - unsigned long * sp; - char * p = (char*)pp; - int argc = bprm->argc; - int envc = bprm->envc; - char uninitialized_var(dummy); - - sp = (unsigned long *)p; - sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); - sp = (unsigned long *) ((unsigned long)sp & -FLAT_STACK_ALIGN); - argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); - envp = argv + (argc + 1); + char __user *p; + unsigned long __user *sp; + long i, len; + p = (char __user *)arg_start; + sp = (unsigned long __user *)current->mm->start_stack; + + sp -= bprm->envc + 1; + sp -= bprm->argc + 1; + sp -= flat_argvp_envp_on_stack() ? 2 : 0; + sp -= 1; /* */ + + current->mm->start_stack = (unsigned long)sp & -FLAT_STACK_ALIGN; + sp = (unsigned long __user *)current->mm->start_stack; + + __put_user(bprm->argc, sp++); if (flat_argvp_envp_on_stack()) { - put_user((unsigned long) envp, sp + 2); - put_user((unsigned long) argv, sp + 1); - } - - put_user(argc, sp); - current->mm->arg_start = (unsigned long) p; - while (argc-->0) { - put_user((unsigned long) p, argv++); - do { - get_user(dummy, p); p++; - } while (dummy); - } - put_user((unsigned long) NULL, argv); - current->mm->arg_end = current->mm->env_start = (unsigned long) p; - while (envc-->0) { - put_user((unsigned long)p, envp); envp++; - do { - get_user(dummy, p); p++; - } while (dummy); - } - put_user((unsigned long) NULL, envp); - current->mm->env_end = (unsigned long) p; - return (unsigned long)sp; + unsigned long argv, envp; + argv = (unsigned long)(sp + 2); + envp = (unsigned long)(sp + 2 + bprm->argc + 1); + __put_user(argv, sp++); + __put_user(envp, sp++); + } + + current->mm->arg_start = (unsigned long)p; + for (i = bprm->argc; i > 0; i--) { + __put_user((unsigned long)p, sp++); + len = strnlen_user(p, MAX_ARG_STRLEN); + if (!len || len > MAX_ARG_STRLEN) + return -EINVAL; + p += len; + } + __put_user(0, sp++); + current->mm->arg_end = (unsigned long)p; + + current->mm->env_start = (unsigned long) p; + for (i = bprm->envc; i > 0; i--) { + __put_user((unsigned long)p, sp++); + len = strnlen_user(p, MAX_ARG_STRLEN); + if (!len || len > MAX_ARG_STRLEN) + return -EINVAL; + p += len; + } + __put_user(0, sp++); + current->mm->env_end = (unsigned long)p; + + return 0; } // @@ -849,7 +857,7 @@ static int load_flat_binary(struct linux_binprm * bprm) { struct lib_info libinfo; struct pt_regs *regs = current_pt_regs(); - unsigned long sp, stack_len; + unsigned long stack_len; unsigned long start_addr; int res; int i, j; @@ -863,11 +871,10 @@ static int load_flat_binary(struct linux_binprm * bprm) * pedantic and include space for the argv/envp array as it may have * a lot of entries. */ -#define TOP_OF_ARGS (PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *)) - stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ - stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ - stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ - stack_len += FLAT_STACK_ALIGN - 1; /* reserve for upcoming alignment */ + stack_len = PAGE_SIZE * MAX_ARG_PAGES -
[PATCH v3 03/12] binfmt_flat: prevent kernel dammage from corrupted executable headers
Signed-off-by: Nicolas Pitre --- fs/binfmt_flat.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 36f5bb6b2c..9c76d9a222 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -470,6 +470,17 @@ static int load_flat_file(struct linux_binprm * bprm, } /* +* Make sure the header params are sane. +* 28 bits (256 MB) is way more than reasonable in this case. +* If some top bits are set we have probable binary corruption. + */ + if ((text_len | data_len | bss_len | stack_len | full_data) >> 28) { + pr_err("bad header\n"); + ret = -ENOEXEC; + goto err; + } + + /* * fix up the flags for the older format, there were all kinds * of endian hacks, this only works for the simple cases */ -- 2.7.4
[PATCH v3 12/12] binfmt_flat: allow compressed flat binary format to work on MMU systems
Let's take the simple and obvious approach by decompressing the binary into a kernel buffer and then copying it to user space. Those who are looking for top performance on an MMU system are unlikely to choose this executable format anyway. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 44 ++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index d04188267a..8dac70921b 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -632,6 +633,7 @@ static int load_flat_file(struct linux_binprm * bprm, * load it all in and treat it like a RAM load from now on */ if (flags & FLAT_FLAG_GZIP) { +#ifndef CONFIG_MMU result = decompress_exec(bprm, sizeof (struct flat_hdr), (((char *) textpos) + sizeof (struct flat_hdr)), (text_len + full_data @@ -639,14 +641,52 @@ static int load_flat_file(struct linux_binprm * bprm, 0); memmove((void *) datapos, (void *) realdatastart, full_data); +#else + /* +* This is used on MMU systems mainly for testing. +* Let's use a kernel buffer to simplify things. +*/ + long unz_text_len = text_len - sizeof(struct flat_hdr); + long unz_len = unz_text_len + full_data; + char *unz_data = vmalloc(unz_len); + if (!unz_data) { + result = -ENOMEM; + } else { + result = decompress_exec(bprm, sizeof(struct flat_hdr), +unz_data, unz_len, 0); + if (result == 0 && + (copy_to_user((void __user *)textpos + sizeof(struct flat_hdr), + unz_data, unz_text_len) || +copy_to_user((void __user *)datapos, + unz_data + unz_text_len, full_data))) + result = -EFAULT; + vfree(unz_data); + } +#endif } else if (flags & FLAT_FLAG_GZDATA) { result = read_code(bprm->file, textpos, 0, text_len); - if (!IS_ERR_VALUE(result)) + if (!IS_ERR_VALUE(result)) { +#ifndef CONFIG_MMU result = decompress_exec(bprm, text_len, (char *) datapos, full_data, 0); +#else + char *unz_data = vmalloc(full_data); + if (!unz_data) { + result = -ENOMEM; + } else { + result = decompress_exec(bprm, text_len, + unz_data, full_data, 0); + if (result == 0 && + copy_to_user((void __user *)datapos, +unz_data, full_data)) + result = -EFAULT; + vfree(unz_data); + } +#endif + } } else -#endif +#endif /* CONFIG_BINFMT_ZFLAT */ { result = read_code(bprm->file, textpos, 0, text_len); if (!IS_ERR_VALUE(result)) -- 2.7.4
[PATCH v3 05/12] binfmt_flat: use generic transfer_args_to_stack()
This gets rid of the rather ugly, open coded and suboptimal copy code. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 22 ++ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 9c76d9a222..fdd33ba9e3 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -849,10 +849,8 @@ static int load_flat_binary(struct linux_binprm * bprm) { struct lib_info libinfo; struct pt_regs *regs = current_pt_regs(); - unsigned long p = bprm->p; - unsigned long stack_len; + unsigned long sp, stack_len; unsigned long start_addr; - unsigned long *sp; int res; int i, j; @@ -887,15 +885,15 @@ static int load_flat_binary(struct linux_binprm * bprm) set_binfmt(_format); - p = ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4; - pr_debug("p=%lx\n", p); + sp = ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4; + pr_debug("sp=%lx\n", sp); - /* copy the arg pages onto the stack, this could be more efficient :-) */ - for (i = TOP_OF_ARGS - 1; i >= bprm->p; i--) - * (char *) --p = - ((char *) page_address(bprm->page[i/PAGE_SIZE]))[i % PAGE_SIZE]; + /* copy the arg pages onto the stack */ + res = transfer_args_to_stack(bprm, ); + if (res) + return res; - sp = (unsigned long *) create_flat_tables(p, bprm); + sp = create_flat_tables(sp, bprm); /* Fake some return addresses to ensure the call chain will * initialise library in order for us. We are required to call @@ -907,14 +905,14 @@ static int load_flat_binary(struct linux_binprm * bprm) for (i = MAX_SHARED_LIBS-1; i>0; i--) { if (libinfo.lib_list[i].loaded) { /* Push previos first to call address */ - --sp; put_user(start_addr, sp); + --sp; put_user(start_addr, (unsigned long *)sp); start_addr = libinfo.lib_list[i].entry; } } #endif /* Stash our initial stack pointer into the mm structure */ - current->mm->start_stack = (unsigned long )sp; + current->mm->start_stack = sp; #ifdef FLAT_PLAT_INIT FLAT_PLAT_INIT(regs); -- 2.7.4
[PATCH v3 11/12] binfmt_flat: add MMU-specific support
Not much else to do at this point except for the different stack setups. SuperH and Xtensa could be added to the allowed list if they implement __put_user_unaligned() and __get_user_unaligned(). Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/Kconfig.binfmt | 3 ++- fs/binfmt_flat.c | 16 +--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 72c03354c1..4c09d93d95 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -89,7 +89,8 @@ config BINFMT_SCRIPT config BINFMT_FLAT bool "Kernel support for flat binaries" - depends on !MMU && (!FRV || BROKEN) + depends on !MMU || ARM || M68K + depends on !FRV || BROKEN help Support uClinux FLAT format binaries. diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index fef94aaa36..d04188267a 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -541,7 +541,7 @@ static int load_flat_file(struct linux_binprm * bprm, * case, and then the fully copied to RAM case which lumps * it all together. */ - if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) { + if (!IS_ENABLED(CONFIG_MMU) && !(flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP))) { /* * this should give us a ROM ptr, but if it doesn't we don't * really care @@ -682,7 +682,9 @@ static int load_flat_file(struct linux_binprm * bprm, */ current->mm->start_brk = datapos + data_len + bss_len; current->mm->brk = (current->mm->start_brk + 3) & ~3; +#ifndef CONFIG_MMU current->mm->context.end_brk = memp + memp_size - stack_len; +#endif } if (flags & FLAT_FLAG_KTRACE) { @@ -873,7 +875,7 @@ static int load_flat_binary(struct linux_binprm * bprm) { struct lib_info libinfo; struct pt_regs *regs = current_pt_regs(); - unsigned long stack_len; + unsigned long stack_len = 0; unsigned long start_addr; int res; int i, j; @@ -887,7 +889,9 @@ static int load_flat_binary(struct linux_binprm * bprm) * pedantic and include space for the argv/envp array as it may have * a lot of entries. */ - stack_len = PAGE_SIZE * MAX_ARG_PAGES - bprm->p; /* the strings */ +#ifndef CONFIG_MMU + stack_len += PAGE_SIZE * MAX_ARG_PAGES - bprm->p; /* the strings */ +#endif stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ stack_len = ALIGN(stack_len, FLAT_STACK_ALIGN); @@ -915,6 +919,11 @@ static int load_flat_binary(struct linux_binprm * bprm) set_binfmt(_format); +#ifdef CONFIG_MMU + res = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); + if (!res) + res = create_flat_tables(bprm, bprm->p); +#else /* Stash our initial stack pointer into the mm structure */ current->mm->start_stack = ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4; @@ -924,6 +933,7 @@ static int load_flat_binary(struct linux_binprm * bprm) res = transfer_args_to_stack(bprm, >mm->start_stack); if (!res) res = create_flat_tables(bprm, current->mm->start_stack); +#endif if (res) return res; -- 2.7.4
[PATCH v3 01/12] binfmt_flat: assorted cleanups
Remove excessive casts, do some code grouping, etc. No functional changes. Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 118 ++- 1 file changed, 56 insertions(+), 62 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index caf9e39bb8..085059d879 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -80,7 +80,7 @@ struct lib_info { unsigned long text_len; /* Length of text segment */ unsigned long entry;/* Start address for this module */ unsigned long build_date; /* When this one was compiled */ - short loaded; /* Has this library been loaded? */ + bool loaded;/* Has this library been loaded? */ } lib_list[MAX_SHARED_LIBS]; }; @@ -107,7 +107,7 @@ static struct linux_binfmt flat_format = { static int flat_core_dump(struct coredump_params *cprm) { printk("Process %s:%d received signr %d and should have core dumped\n", - current->comm, current->pid, (int) cprm->siginfo->si_signo); + current->comm, current->pid, cprm->siginfo->si_signo); return(1); } @@ -190,7 +190,7 @@ static int decompress_exec( loff_t fpos; int ret, retval; - DBG_FLT("decompress_exec(offset=%x,buf=%x,len=%x)\n",(int)offset, (int)dst, (int)len); + DBG_FLT("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, len); memset(, 0, sizeof(strm)); strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); @@ -358,8 +358,8 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp) text_len = p->lib_list[id].text_len; if (!flat_reloc_valid(r, start_brk - start_data + text_len)) { - printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)", - (int) r,(int)(start_brk-start_data+text_len),(int)text_len); + printk("BINFMT_FLAT: reloc outside program 0x%lx (0 - 0x%lx/0x%lx)", + r, start_brk-start_data+text_len, text_len); goto failed; } @@ -383,7 +383,7 @@ failed: static void old_reloc(unsigned long rl) { #ifdef DEBUG - char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" }; + static const char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" }; #endif flat_v2_reloc_t r; unsigned long *ptr; @@ -397,8 +397,8 @@ static void old_reloc(unsigned long rl) #ifdef DEBUG printk("Relocation of variable at DATASEG+%x " - "(address %p, currently %x) into segment %s\n", - r.reloc.offset, ptr, (int)*ptr, segment[r.reloc.type]); + "(address %p, currently %lx) into segment %s\n", + r.reloc.offset, ptr, *ptr, segment[r.reloc.type]); #endif switch (r.reloc.type) { @@ -417,7 +417,7 @@ static void old_reloc(unsigned long rl) } #ifdef DEBUG - printk("Relocation became %x\n", (int)*ptr); + printk("Relocation became %lx\n", *ptr); #endif } @@ -427,17 +427,15 @@ static int load_flat_file(struct linux_binprm * bprm, struct lib_info *libinfo, int id, unsigned long *extra_stack) { struct flat_hdr * hdr; - unsigned long textpos = 0, datapos = 0, result; - unsigned long realdatastart = 0; - unsigned long text_len, data_len, bss_len, stack_len, flags; - unsigned long full_data; - unsigned long len, memp = 0; - unsigned long memp_size, extra, rlim; - unsigned long *reloc = 0, *rp; + unsigned long textpos, datapos, realdatastart; + unsigned long text_len, data_len, bss_len, stack_len, full_data, flags; + unsigned long len, memp, memp_size, extra, rlim; + unsigned long *reloc, *rp; struct inode *inode; - int i, rev, relocs = 0; + int i, rev, relocs; loff_t fpos; unsigned long start_code, end_code; + ssize_t result; int ret; hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ @@ -481,8 +479,8 @@ static int load_flat_file(struct linux_binprm * bprm, /* Don't allow old format executables to use shared libraries */ if (rev == OLD_FLAT_VERSION && id != 0) { - printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n", - (int) FLAT_VERSION); + printk("BINFMT_FLAT: shared libraries are not available before rev 0x%lx\n", + FLAT_VERSION); ret = -ENOEXEC; goto err; } @@ -517,11 +515,9 @@ static int load_flat_file(struct linux_binprm * bprm, /* Flush all traces of the currently running executable */
[PATCH v3 10/12] binfmt_flat: update libraries' data segment pointer with userspace accessors
This is needed on systems with a MMU. This also gets rid of the strangest C code I've seen lateli i.e. an integer indexed with a pointer value within square brackets. That really looked backwards. Signed-off-by: Nicolas PitreReviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 19 +-- 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 0d89830f76..fef94aaa36 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -897,12 +897,19 @@ static int load_flat_binary(struct linux_binprm * bprm) return res; /* Update data segment pointers for all libraries */ - for (i=0; i
[PATCH v3 11/12] binfmt_flat: add MMU-specific support
Not much else to do at this point except for the different stack setups. SuperH and Xtensa could be added to the allowed list if they implement __put_user_unaligned() and __get_user_unaligned(). Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/Kconfig.binfmt | 3 ++- fs/binfmt_flat.c | 16 +--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 72c03354c1..4c09d93d95 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -89,7 +89,8 @@ config BINFMT_SCRIPT config BINFMT_FLAT bool "Kernel support for flat binaries" - depends on !MMU && (!FRV || BROKEN) + depends on !MMU || ARM || M68K + depends on !FRV || BROKEN help Support uClinux FLAT format binaries. diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index fef94aaa36..d04188267a 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -541,7 +541,7 @@ static int load_flat_file(struct linux_binprm * bprm, * case, and then the fully copied to RAM case which lumps * it all together. */ - if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) { + if (!IS_ENABLED(CONFIG_MMU) && !(flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP))) { /* * this should give us a ROM ptr, but if it doesn't we don't * really care @@ -682,7 +682,9 @@ static int load_flat_file(struct linux_binprm * bprm, */ current->mm->start_brk = datapos + data_len + bss_len; current->mm->brk = (current->mm->start_brk + 3) & ~3; +#ifndef CONFIG_MMU current->mm->context.end_brk = memp + memp_size - stack_len; +#endif } if (flags & FLAT_FLAG_KTRACE) { @@ -873,7 +875,7 @@ static int load_flat_binary(struct linux_binprm * bprm) { struct lib_info libinfo; struct pt_regs *regs = current_pt_regs(); - unsigned long stack_len; + unsigned long stack_len = 0; unsigned long start_addr; int res; int i, j; @@ -887,7 +889,9 @@ static int load_flat_binary(struct linux_binprm * bprm) * pedantic and include space for the argv/envp array as it may have * a lot of entries. */ - stack_len = PAGE_SIZE * MAX_ARG_PAGES - bprm->p; /* the strings */ +#ifndef CONFIG_MMU + stack_len += PAGE_SIZE * MAX_ARG_PAGES - bprm->p; /* the strings */ +#endif stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ stack_len = ALIGN(stack_len, FLAT_STACK_ALIGN); @@ -915,6 +919,11 @@ static int load_flat_binary(struct linux_binprm * bprm) set_binfmt(_format); +#ifdef CONFIG_MMU + res = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); + if (!res) + res = create_flat_tables(bprm, bprm->p); +#else /* Stash our initial stack pointer into the mm structure */ current->mm->start_stack = ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4; @@ -924,6 +933,7 @@ static int load_flat_binary(struct linux_binprm * bprm) res = transfer_args_to_stack(bprm, >mm->start_stack); if (!res) res = create_flat_tables(bprm, current->mm->start_stack); +#endif if (res) return res; -- 2.7.4
[PATCH v3 01/12] binfmt_flat: assorted cleanups
Remove excessive casts, do some code grouping, etc. No functional changes. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 118 ++- 1 file changed, 56 insertions(+), 62 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index caf9e39bb8..085059d879 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -80,7 +80,7 @@ struct lib_info { unsigned long text_len; /* Length of text segment */ unsigned long entry;/* Start address for this module */ unsigned long build_date; /* When this one was compiled */ - short loaded; /* Has this library been loaded? */ + bool loaded;/* Has this library been loaded? */ } lib_list[MAX_SHARED_LIBS]; }; @@ -107,7 +107,7 @@ static struct linux_binfmt flat_format = { static int flat_core_dump(struct coredump_params *cprm) { printk("Process %s:%d received signr %d and should have core dumped\n", - current->comm, current->pid, (int) cprm->siginfo->si_signo); + current->comm, current->pid, cprm->siginfo->si_signo); return(1); } @@ -190,7 +190,7 @@ static int decompress_exec( loff_t fpos; int ret, retval; - DBG_FLT("decompress_exec(offset=%x,buf=%x,len=%x)\n",(int)offset, (int)dst, (int)len); + DBG_FLT("decompress_exec(offset=%lx,buf=%p,len=%lx)\n",offset, dst, len); memset(, 0, sizeof(strm)); strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); @@ -358,8 +358,8 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp) text_len = p->lib_list[id].text_len; if (!flat_reloc_valid(r, start_brk - start_data + text_len)) { - printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)", - (int) r,(int)(start_brk-start_data+text_len),(int)text_len); + printk("BINFMT_FLAT: reloc outside program 0x%lx (0 - 0x%lx/0x%lx)", + r, start_brk-start_data+text_len, text_len); goto failed; } @@ -383,7 +383,7 @@ failed: static void old_reloc(unsigned long rl) { #ifdef DEBUG - char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" }; + static const char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" }; #endif flat_v2_reloc_t r; unsigned long *ptr; @@ -397,8 +397,8 @@ static void old_reloc(unsigned long rl) #ifdef DEBUG printk("Relocation of variable at DATASEG+%x " - "(address %p, currently %x) into segment %s\n", - r.reloc.offset, ptr, (int)*ptr, segment[r.reloc.type]); + "(address %p, currently %lx) into segment %s\n", + r.reloc.offset, ptr, *ptr, segment[r.reloc.type]); #endif switch (r.reloc.type) { @@ -417,7 +417,7 @@ static void old_reloc(unsigned long rl) } #ifdef DEBUG - printk("Relocation became %x\n", (int)*ptr); + printk("Relocation became %lx\n", *ptr); #endif } @@ -427,17 +427,15 @@ static int load_flat_file(struct linux_binprm * bprm, struct lib_info *libinfo, int id, unsigned long *extra_stack) { struct flat_hdr * hdr; - unsigned long textpos = 0, datapos = 0, result; - unsigned long realdatastart = 0; - unsigned long text_len, data_len, bss_len, stack_len, flags; - unsigned long full_data; - unsigned long len, memp = 0; - unsigned long memp_size, extra, rlim; - unsigned long *reloc = 0, *rp; + unsigned long textpos, datapos, realdatastart; + unsigned long text_len, data_len, bss_len, stack_len, full_data, flags; + unsigned long len, memp, memp_size, extra, rlim; + unsigned long *reloc, *rp; struct inode *inode; - int i, rev, relocs = 0; + int i, rev, relocs; loff_t fpos; unsigned long start_code, end_code; + ssize_t result; int ret; hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ @@ -481,8 +479,8 @@ static int load_flat_file(struct linux_binprm * bprm, /* Don't allow old format executables to use shared libraries */ if (rev == OLD_FLAT_VERSION && id != 0) { - printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n", - (int) FLAT_VERSION); + printk("BINFMT_FLAT: shared libraries are not available before rev 0x%lx\n", + FLAT_VERSION); ret = -ENOEXEC; goto err; } @@ -517,11 +515,9 @@ static int load_flat_file(struct linux_binprm * bprm, /* Flush all traces of the currently running executable */ if (id == 0) { -
[PATCH v3 10/12] binfmt_flat: update libraries' data segment pointer with userspace accessors
This is needed on systems with a MMU. This also gets rid of the strangest C code I've seen lateli i.e. an integer indexed with a pointer value within square brackets. That really looked backwards. Signed-off-by: Nicolas Pitre Reviewed-by: Greg Ungerer --- fs/binfmt_flat.c | 19 +-- 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 0d89830f76..fef94aaa36 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -897,12 +897,19 @@ static int load_flat_binary(struct linux_binprm * bprm) return res; /* Update data segment pointers for all libraries */ - for (i=0; i
[PATCH v3 00/12] allow BFLT executables on systems with a MMU
This series provides the necessary changes to allow "flat" executable binaries meant for no-MMU systems to actually run on systems with a MMU. This can also be found in the following git repo: git://git.linaro.org/people/nicolas.pitre/linux binfmt_flat_with_mmu *Why?* Because developing and testing natively on a large system with lots of RAM makes it so much more convenient to use all the existing profiling tools and debugging facilities that a kernel with lots of RAM can give. And incidentally, those systems with lots of RAM all have a MMU. *Why not use elf_fdpic?* The flat executable format is simple with very small footprint overhead, either in the executables themselves or kernel support. This makes the flat format more suitable than elf_fdpic for very small single-user-app embedded systems. And while elf_fdpic binaries can run on MMU systems, flat binaries still couldn't, which just felt wrong. So here it is. The no-MMU support should remain unaffected, confirmed by Greg Ungerer. Tested on ARM with MMU only with a busybox build. Please consider for merging. Changes since v2: - Added protection against a corrupted header that could have caused nasty overflows etc. Suggested by Alan Cox. - printk() modernization. Suggested by Greg Ungerer / Geert Uytterhoeven. - Added Greg Ungerer's reviewed-by tag. Changes since v1: - Removed SuperH and Xtensa from the Kconfig rule as they fail to build due to lack of get/put_unaligned_user(). - Clarified some commit logs a bit. diffstat: arch/arm/include/asm/flat.h | 5 +- arch/m68k/include/asm/flat.h | 5 +- fs/Kconfig.binfmt| 3 +- fs/binfmt_elf_fdpic.c| 38 +--- fs/binfmt_flat.c | 453 + fs/exec.c| 33 +++ include/linux/binfmts.h | 2 + 7 files changed, 306 insertions(+), 233 deletions(-)
[PATCH v3 00/12] allow BFLT executables on systems with a MMU
This series provides the necessary changes to allow "flat" executable binaries meant for no-MMU systems to actually run on systems with a MMU. This can also be found in the following git repo: git://git.linaro.org/people/nicolas.pitre/linux binfmt_flat_with_mmu *Why?* Because developing and testing natively on a large system with lots of RAM makes it so much more convenient to use all the existing profiling tools and debugging facilities that a kernel with lots of RAM can give. And incidentally, those systems with lots of RAM all have a MMU. *Why not use elf_fdpic?* The flat executable format is simple with very small footprint overhead, either in the executables themselves or kernel support. This makes the flat format more suitable than elf_fdpic for very small single-user-app embedded systems. And while elf_fdpic binaries can run on MMU systems, flat binaries still couldn't, which just felt wrong. So here it is. The no-MMU support should remain unaffected, confirmed by Greg Ungerer. Tested on ARM with MMU only with a busybox build. Please consider for merging. Changes since v2: - Added protection against a corrupted header that could have caused nasty overflows etc. Suggested by Alan Cox. - printk() modernization. Suggested by Greg Ungerer / Geert Uytterhoeven. - Added Greg Ungerer's reviewed-by tag. Changes since v1: - Removed SuperH and Xtensa from the Kconfig rule as they fail to build due to lack of get/put_unaligned_user(). - Clarified some commit logs a bit. diffstat: arch/arm/include/asm/flat.h | 5 +- arch/m68k/include/asm/flat.h | 5 +- fs/Kconfig.binfmt| 3 +- fs/binfmt_elf_fdpic.c| 38 +--- fs/binfmt_flat.c | 453 + fs/exec.c| 33 +++ include/linux/binfmts.h | 2 + 7 files changed, 306 insertions(+), 233 deletions(-)
RE: [PATCH v17 net-next 1/1] hv_sock: introduce Hyper-V Sockets
> From: David Miller [mailto:da...@davemloft.net] > >> From: kbuild test robot [mailto:l...@intel.com] > >> [auto build test WARNING on net-next/master] > >> > >> url:https://github.com/0day-ci/linux/commits/Dexuan-Cui/introduce- > >> Hyper-V-VM-Sockets-hv_sock/20160715-223433 > >> config: x86_64-randconfig-a0-07191719 (attached as .config) > >> compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7 > >> reproduce: > >> # save the attached .config to linux build tree > >> make ARCH=x86_64 > >> > >> All warnings (new ones prefixed by >>): > >> > >>net/hv_sock/af_hvsock.c: In function 'hvsock_open_connection': > >>net/hv_sock/af_hvsock.c:693: warning: 'hvsk' may be used uninitialized > in > >> this function > >>net/hv_sock/af_hvsock.c:693: warning: 'new_hvsk' may be used > >> uninitialized in this function > >>net/hv_sock/af_hvsock.c:697: warning: 'new_sk' may be used > uninitialized > >> in this function > >>net/hv_sock/af_hvsock.c: In function 'hvsock_sendmsg_wait': > >>net/hv_sock/af_hvsock.c:1053: warning: 'ret' may be used uninitialized > in > >> this function > >> >> net/hv_sock/af_hvsock.o: warning: objtool: > hvsock_on_channel_cb()+0x1d: > >> function has unreachable instruction > > > > These warnings are all false alarms. > > But you still have to quiet them. Sure. Will do. Thanks, -- Dexuan
RE: [PATCH v17 net-next 1/1] hv_sock: introduce Hyper-V Sockets
> From: David Miller [mailto:da...@davemloft.net] > >> From: kbuild test robot [mailto:l...@intel.com] > >> [auto build test WARNING on net-next/master] > >> > >> url:https://github.com/0day-ci/linux/commits/Dexuan-Cui/introduce- > >> Hyper-V-VM-Sockets-hv_sock/20160715-223433 > >> config: x86_64-randconfig-a0-07191719 (attached as .config) > >> compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7 > >> reproduce: > >> # save the attached .config to linux build tree > >> make ARCH=x86_64 > >> > >> All warnings (new ones prefixed by >>): > >> > >>net/hv_sock/af_hvsock.c: In function 'hvsock_open_connection': > >>net/hv_sock/af_hvsock.c:693: warning: 'hvsk' may be used uninitialized > in > >> this function > >>net/hv_sock/af_hvsock.c:693: warning: 'new_hvsk' may be used > >> uninitialized in this function > >>net/hv_sock/af_hvsock.c:697: warning: 'new_sk' may be used > uninitialized > >> in this function > >>net/hv_sock/af_hvsock.c: In function 'hvsock_sendmsg_wait': > >>net/hv_sock/af_hvsock.c:1053: warning: 'ret' may be used uninitialized > in > >> this function > >> >> net/hv_sock/af_hvsock.o: warning: objtool: > hvsock_on_channel_cb()+0x1d: > >> function has unreachable instruction > > > > These warnings are all false alarms. > > But you still have to quiet them. Sure. Will do. Thanks, -- Dexuan
[PATCH] make __section_nr more efficient
When CONFIG_SPARSEMEM_EXTREME is disabled, __section_nr can get the section number with a subtraction directly. Signed-off-by: Zhou Chengming--- mm/sparse.c | 12 +++- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/mm/sparse.c b/mm/sparse.c index 5d0cf45..36d7bbb 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -100,11 +100,7 @@ static inline int sparse_index_init(unsigned long section_nr, int nid) } #endif -/* - * Although written for the SPARSEMEM_EXTREME case, this happens - * to also work for the flat array case because - * NR_SECTION_ROOTS==NR_MEM_SECTIONS. - */ +#ifdef CONFIG_SPARSEMEM_EXTREME int __section_nr(struct mem_section* ms) { unsigned long root_nr; @@ -123,6 +119,12 @@ int __section_nr(struct mem_section* ms) return (root_nr * SECTIONS_PER_ROOT) + (ms - root); } +#else +int __section_nr(struct mem_section* ms) +{ + return (int)(ms - mem_section[0]); +} +#endif /* * During early boot, before section_mem_map is used for an actual -- 1.7.7
[PATCH] make __section_nr more efficient
When CONFIG_SPARSEMEM_EXTREME is disabled, __section_nr can get the section number with a subtraction directly. Signed-off-by: Zhou Chengming --- mm/sparse.c | 12 +++- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/mm/sparse.c b/mm/sparse.c index 5d0cf45..36d7bbb 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -100,11 +100,7 @@ static inline int sparse_index_init(unsigned long section_nr, int nid) } #endif -/* - * Although written for the SPARSEMEM_EXTREME case, this happens - * to also work for the flat array case because - * NR_SECTION_ROOTS==NR_MEM_SECTIONS. - */ +#ifdef CONFIG_SPARSEMEM_EXTREME int __section_nr(struct mem_section* ms) { unsigned long root_nr; @@ -123,6 +119,12 @@ int __section_nr(struct mem_section* ms) return (root_nr * SECTIONS_PER_ROOT) + (ms - root); } +#else +int __section_nr(struct mem_section* ms) +{ + return (int)(ms - mem_section[0]); +} +#endif /* * During early boot, before section_mem_map is used for an actual -- 1.7.7
Re: [PATCH 0/3] Enable legacy irq mode before jump to kexec/kdump kernel
Hi Jiangang, On 07/20/16 at 03:54am, Wei, Jiangang wrote: > Hi Baoquan He, > > Well, Indeed there‘s a relationship between the dump-capture hangs in > calibrate_delay_converge() and the interrupt mode. > > but there‘s no essential difference between your patches and mine that > calls disable_IO_APIC() again. > Actually, disable_IO_APIC will set APIC to virtual wire mode. You didn't read my patch log carefully. disable_IO_APIC not only set APIC to PIC mode or virtual wire mode, but call clear_IO_APIC. > > In fact, > Eric and Ingo suggested that "it should be fixed in the bootup path of > the dump kernel, not the crash kernel reboot path", which is convincing > and reasonable. Well this patch doesn't do differently with Eric's original implemention in kexec/kdump path. By taking out clear_IO_APIC from disable_IO_APIC, the left code of disable_IO_APIC will only do the virtual wire setting. So for kexec/kdump path, code basically is the same as Eric's method. But for poweroff/halt/reboot, it's enough to call clear_IO_APIC to disable IO-APIC. > > And i find a better method can fix the problem. > It's better to set virtual wire mode for apic in init_bsp_APIC(), which > in the bootup path of dump kernel. > But now, init_bsp_APIC doesn't initialize the apic to vitual wire mode > when smp_found_config is non-zero. And virtual wire mode have two kinds, IO-APIC virtual wire mode and LAPIC virtual wire mode. Please read code comments in init_bsp_APIC, IO-APIC virtual wire mode could be active or need be set, you can't detect IO-APIC pin connected to i8259 equvialent PIC. > > FYI, I'm working on this point. later i will send patches to mail list. > > Wei > > On Wed, 2016-07-20 at 10:58 +0800, Baoquan He wrote: > > Wei Jiangang reported kdump kernel always hang when "notsc" is specified > > in boot parameter. After debugging I found there's no timer interrupt > > in the current kexec/kdump kernel. This is caused by commit 522e66464467 > > ("x86/apic: Disable I/O APIC before shutdown of the local APIC"). Originally > > Eric posted below patch to make system be virtual wire mode in which 8259- > > equivalent PIC fields all interrupts and the LAPIC becomes a virtual wire. > > Like this interrupts can be delivered from PIC to CPU via the LAPIC's local > > interrupt 0 (LINTIN0). In virtual wire APIC mode is disabled while LAPIC > > is software enabled and its LINT0 and LINT1 need be programmed specifically. > > > > https://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.11/2.6.11-mm1/broken-out/x86_64-apic-virtwire-on-shutdown.patch > > > > But with commit 522e66464 you can see after disable_IO_APIC had setting > > virtual wire mode, lapic_shutdown disabled LAPIC again. Now virtual wire > > mode doesn't work, then it cause no timer interrupt during kdump kernel > > initialization stage until system enter into APIC mode. > > > > So people may be wondering why only kdump kernel hang, the normal kernel > > with "notsc" can still work. This is because BIOS has already built PIC mode > > or virtual wire mode while kexec/kdump kernel doesn't go through BIOS > > initialization. That is why we have to change system to be PIC mode or > > virtual wire mode before jump to kexec/kdump kernel. > > > > Then why kdump kernel didn't hang when "notsc" is not specified. This is > > because tsc_init will assign the already calibrated value to lpj_fine. > > Then kernel doesn't need to count cpu loops between jiffies with the help > > of timer interrupt. So "notsc" is not victim, but a informer. > > > > In patch 1/3 disable_IO_APIC is changed to only contain code of changeing > > system to be PIC mode or virtual wire mode and is renamed as > > switch_to_legacy_irq_mode. Now only call clear_IO_APIC where IO-APIC need > > be disabled, and call switch_to_legacy_irq_mode before jump to kexe/kdump > > kernel. > > > > Patch 2/3 and 3/3 are clean up patch. > > > > Baoquan He (3): > > x86/apic/kexec: Enable legacy irq mode before jump to kexec/kdump > > kernel > > x86/apic: Clean up the names of legacy irq mode setting related > > functions > > x86/apic: Clean up the apic delivery mode macro definition > > > > arch/x86/include/asm/apic.h| 2 +- > > arch/x86/include/asm/apicdef.h | 1 - > > arch/x86/include/asm/io_apic.h | 6 +++--- > > arch/x86/kernel/apic/apic.c| 19 +++ > > arch/x86/kernel/apic/io_apic.c | 32 +--- > > arch/x86/kernel/crash.c| 2 +- > > arch/x86/kernel/machine_kexec_32.c | 15 +-- > > arch/x86/kernel/machine_kexec_64.c | 15 +-- > > arch/x86/kernel/reboot.c | 2 +- > > arch/x86/kernel/x86_init.c | 2 +- > > drivers/iommu/irq_remapping.c | 2 +- > > 11 files changed, 46 insertions(+), 52 deletions(-) > > > > > > ___ > kexec mailing list > ke...@lists.infradead.org >
Re: [PATCH 0/3] Enable legacy irq mode before jump to kexec/kdump kernel
Hi Jiangang, On 07/20/16 at 03:54am, Wei, Jiangang wrote: > Hi Baoquan He, > > Well, Indeed there‘s a relationship between the dump-capture hangs in > calibrate_delay_converge() and the interrupt mode. > > but there‘s no essential difference between your patches and mine that > calls disable_IO_APIC() again. > Actually, disable_IO_APIC will set APIC to virtual wire mode. You didn't read my patch log carefully. disable_IO_APIC not only set APIC to PIC mode or virtual wire mode, but call clear_IO_APIC. > > In fact, > Eric and Ingo suggested that "it should be fixed in the bootup path of > the dump kernel, not the crash kernel reboot path", which is convincing > and reasonable. Well this patch doesn't do differently with Eric's original implemention in kexec/kdump path. By taking out clear_IO_APIC from disable_IO_APIC, the left code of disable_IO_APIC will only do the virtual wire setting. So for kexec/kdump path, code basically is the same as Eric's method. But for poweroff/halt/reboot, it's enough to call clear_IO_APIC to disable IO-APIC. > > And i find a better method can fix the problem. > It's better to set virtual wire mode for apic in init_bsp_APIC(), which > in the bootup path of dump kernel. > But now, init_bsp_APIC doesn't initialize the apic to vitual wire mode > when smp_found_config is non-zero. And virtual wire mode have two kinds, IO-APIC virtual wire mode and LAPIC virtual wire mode. Please read code comments in init_bsp_APIC, IO-APIC virtual wire mode could be active or need be set, you can't detect IO-APIC pin connected to i8259 equvialent PIC. > > FYI, I'm working on this point. later i will send patches to mail list. > > Wei > > On Wed, 2016-07-20 at 10:58 +0800, Baoquan He wrote: > > Wei Jiangang reported kdump kernel always hang when "notsc" is specified > > in boot parameter. After debugging I found there's no timer interrupt > > in the current kexec/kdump kernel. This is caused by commit 522e66464467 > > ("x86/apic: Disable I/O APIC before shutdown of the local APIC"). Originally > > Eric posted below patch to make system be virtual wire mode in which 8259- > > equivalent PIC fields all interrupts and the LAPIC becomes a virtual wire. > > Like this interrupts can be delivered from PIC to CPU via the LAPIC's local > > interrupt 0 (LINTIN0). In virtual wire APIC mode is disabled while LAPIC > > is software enabled and its LINT0 and LINT1 need be programmed specifically. > > > > https://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.11/2.6.11-mm1/broken-out/x86_64-apic-virtwire-on-shutdown.patch > > > > But with commit 522e66464 you can see after disable_IO_APIC had setting > > virtual wire mode, lapic_shutdown disabled LAPIC again. Now virtual wire > > mode doesn't work, then it cause no timer interrupt during kdump kernel > > initialization stage until system enter into APIC mode. > > > > So people may be wondering why only kdump kernel hang, the normal kernel > > with "notsc" can still work. This is because BIOS has already built PIC mode > > or virtual wire mode while kexec/kdump kernel doesn't go through BIOS > > initialization. That is why we have to change system to be PIC mode or > > virtual wire mode before jump to kexec/kdump kernel. > > > > Then why kdump kernel didn't hang when "notsc" is not specified. This is > > because tsc_init will assign the already calibrated value to lpj_fine. > > Then kernel doesn't need to count cpu loops between jiffies with the help > > of timer interrupt. So "notsc" is not victim, but a informer. > > > > In patch 1/3 disable_IO_APIC is changed to only contain code of changeing > > system to be PIC mode or virtual wire mode and is renamed as > > switch_to_legacy_irq_mode. Now only call clear_IO_APIC where IO-APIC need > > be disabled, and call switch_to_legacy_irq_mode before jump to kexe/kdump > > kernel. > > > > Patch 2/3 and 3/3 are clean up patch. > > > > Baoquan He (3): > > x86/apic/kexec: Enable legacy irq mode before jump to kexec/kdump > > kernel > > x86/apic: Clean up the names of legacy irq mode setting related > > functions > > x86/apic: Clean up the apic delivery mode macro definition > > > > arch/x86/include/asm/apic.h| 2 +- > > arch/x86/include/asm/apicdef.h | 1 - > > arch/x86/include/asm/io_apic.h | 6 +++--- > > arch/x86/kernel/apic/apic.c| 19 +++ > > arch/x86/kernel/apic/io_apic.c | 32 +--- > > arch/x86/kernel/crash.c| 2 +- > > arch/x86/kernel/machine_kexec_32.c | 15 +-- > > arch/x86/kernel/machine_kexec_64.c | 15 +-- > > arch/x86/kernel/reboot.c | 2 +- > > arch/x86/kernel/x86_init.c | 2 +- > > drivers/iommu/irq_remapping.c | 2 +- > > 11 files changed, 46 insertions(+), 52 deletions(-) > > > > > > ___ > kexec mailing list > ke...@lists.infradead.org >
Re: [Patch-V2 2/3] chcr: Support for Chelsio's Crypto Hardware
From: Yeshaswi M R GowdaDate: Mon, 18 Jul 2016 22:42:14 -0700 > +config CRYPTO_DEV_CHELSIO > + tristate "Chelsio Crypto Co-processor Driver" > + depends on PCI && NETDEVICES && ETHERNET > + select CRYPTO_SHA1 > + select CRYPTO_SHA256 > + select CRYPTO_SHA512 > + select NET_VENDOR_CHELSIO > + select CHELSIO_T4 The user shouldn't have to know about the technical details about how this chip is physically implemented. It's therefore not reasonable to require an ethernet driver to be enabled to use the crypto engine. Also, selecting Kconfig symbol X does not recursively enable the "select" statement(s) of symbol X nor does it check symbol X's dependencies. This is really one big huge dependency mess, and I think you have to split out the core of the T4 driver into a driver subtype agnostic library or similar to make this work properly. Don't just shoehorn this stuff into the ethernet driver. Round peg, square hole.
[PATCH 3/3] ARM: pxa: add module.h for spitz symbol_get/symbol_put usage
During unrelated work, attempting to remove an include of the linux/module.h in favour of "struct module;" in order to reduce header entanglement, we found doing so caused a build failure in this file. mach-pxa/spitz.c: In function 'spitz_bl_kick_battery': mach-pxa/spitz.c:524:2: error: implicit declaration of function 'symbol_get' [-Werror=implicit-function-declaration] mach-pxa/spitz.c:524:12: warning: assignment makes pointer from integer without a cast [enabled by default] mach-pxa/spitz.c:527:3: error: implicit declaration of function 'symbol_put' [-Werror=implicit-function-declaration] It turns out this file uses symbol_get/symbol_put which live in the module.h header, but it wasn't including module.h -- which was being masked by the module.h in include/linux/gpio/driver.h - the one we want to remove/replace. With ARM and GPIO being different subsystems, we'll need to get this in ARM 1st, and then wait a release before changing the GPIO header, otherwise we'll risk triggering build failures. Cc: Daniel MackCc: Haojian Zhuang Cc: Robert Jarzmik Cc: Russell King Cc: Linus Walleij Cc: Alexandre Courbot Cc: linux-o...@vger.kernel.org Cc: linux-g...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Paul Gortmaker --- arch/arm/mach-pxa/spitz.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index b410698808ca..8078e3cdb6c8 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -13,6 +13,7 @@ */ #include +#include /* symbol_get ; symbol_put */ #include #include #include -- 2.8.4
Re: [Patch-V2 2/3] chcr: Support for Chelsio's Crypto Hardware
From: Yeshaswi M R Gowda Date: Mon, 18 Jul 2016 22:42:14 -0700 > +config CRYPTO_DEV_CHELSIO > + tristate "Chelsio Crypto Co-processor Driver" > + depends on PCI && NETDEVICES && ETHERNET > + select CRYPTO_SHA1 > + select CRYPTO_SHA256 > + select CRYPTO_SHA512 > + select NET_VENDOR_CHELSIO > + select CHELSIO_T4 The user shouldn't have to know about the technical details about how this chip is physically implemented. It's therefore not reasonable to require an ethernet driver to be enabled to use the crypto engine. Also, selecting Kconfig symbol X does not recursively enable the "select" statement(s) of symbol X nor does it check symbol X's dependencies. This is really one big huge dependency mess, and I think you have to split out the core of the T4 driver into a driver subtype agnostic library or similar to make this work properly. Don't just shoehorn this stuff into the ethernet driver. Round peg, square hole.
[PATCH 3/3] ARM: pxa: add module.h for spitz symbol_get/symbol_put usage
During unrelated work, attempting to remove an include of the linux/module.h in favour of "struct module;" in order to reduce header entanglement, we found doing so caused a build failure in this file. mach-pxa/spitz.c: In function 'spitz_bl_kick_battery': mach-pxa/spitz.c:524:2: error: implicit declaration of function 'symbol_get' [-Werror=implicit-function-declaration] mach-pxa/spitz.c:524:12: warning: assignment makes pointer from integer without a cast [enabled by default] mach-pxa/spitz.c:527:3: error: implicit declaration of function 'symbol_put' [-Werror=implicit-function-declaration] It turns out this file uses symbol_get/symbol_put which live in the module.h header, but it wasn't including module.h -- which was being masked by the module.h in include/linux/gpio/driver.h - the one we want to remove/replace. With ARM and GPIO being different subsystems, we'll need to get this in ARM 1st, and then wait a release before changing the GPIO header, otherwise we'll risk triggering build failures. Cc: Daniel Mack Cc: Haojian Zhuang Cc: Robert Jarzmik Cc: Russell King Cc: Linus Walleij Cc: Alexandre Courbot Cc: linux-o...@vger.kernel.org Cc: linux-g...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Paul Gortmaker --- arch/arm/mach-pxa/spitz.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index b410698808ca..8078e3cdb6c8 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -13,6 +13,7 @@ */ #include +#include /* symbol_get ; symbol_put */ #include #include #include -- 2.8.4
[PATCH 0/3] ARM: fix three implicit module use cases fed via gpio
While working on some for-4.9 cleanups of linux/gpio/driver.h it was found that changes there caused build failures when walking all the ARM defconfigs, in ARM specific mach-* files. The proposed GPIO header change is just this: --- --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -16,6 +15,7 @@ struct of_phandle_args; struct device_node; struct seq_file; struct gpio_device; +struct module; #ifdef CONFIG_GPIOLIB --- ...which is what we've already got in ~50 other include/linux/* files to try and keep cross contamination entanglement at a minimum. So we uncovered three users in ARM specific files relying on the above presence in this header, vs. dealing with it within the driver itself. But with ARM and GPIO being different subsystems, we'll need to get this in ARM 1st, and then wait a release before changing the GPIO header, otherwise we'll risk triggering these three build failures. So, if folks consider these three trivial changes OK for late in the for-4.8 cycle, then great. Otherwise I'll resubmit the ARM parts for for-4.9 and the GPIO bits for the one after that. [Yes, there were gpio implicit users too, but they are easily sync'd with the gpio header change being at the end of that series.] Paul. -- Cc: Alexandre CourbotCc: Daniel Mack Cc: Haojian Zhuang Cc: Linus Walleij Cc: linux-arm-ker...@lists.infradead.org Cc: linux-g...@vger.kernel.org Cc: linux-o...@vger.kernel.org Cc: Robert Jarzmik Cc: Russell King Cc: Tony Lindgren Paul Gortmaker (3): ARM: mach-omap2: remove bogus "or_module" from rx51-peripherals ARM: pxa: add module.h for corgi symbol_get/symbol_put usage ARM: pxa: add module.h for spitz symbol_get/symbol_put usage arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- arch/arm/mach-pxa/corgi.c| 1 + arch/arm/mach-pxa/spitz.c| 1 + 3 files changed, 3 insertions(+), 1 deletion(-) -- 2.8.4
[PATCH 2/3] ARM: pxa: add module.h for corgi symbol_get/symbol_put usage
During unrelated work, attempting to remove an include of the linux/module.h in favour of "struct module;" in order to reduce header entanglement, we found doing so caused a build failure in this file. mach-pxa/corgi.c: In function 'corgi_bl_kick_battery': mach-pxa/corgi.c:548:2: error: implicit declaration of function 'symbol_get' [-Werror=implicit-function-declaration] mach-pxa/corgi.c:548:12: warning: assignment makes pointer from integer without a cast [enabled by default] mach-pxa/corgi.c:551:3: error: implicit declaration of function 'symbol_put' [-Werror=implicit-function-declaration] It turns out this file uses symbol_get/symbol_put which live in the module.h header, but it wasn't including module.h -- which was being masked by the module.h in include/linux/gpio/driver.h - the one we want to remove/replace. With ARM and GPIO being different subsystems, we'll need to get this in ARM 1st, and then wait a release before changing the GPIO header, otherwise we'll risk triggering build failures. Cc: Daniel MackCc: Haojian Zhuang Cc: Robert Jarzmik Cc: Russell King Cc: Linus Walleij Cc: Alexandre Courbot Cc: linux-o...@vger.kernel.org Cc: linux-g...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Paul Gortmaker --- arch/arm/mach-pxa/corgi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index aa952979461f..183cd3446f25 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -13,6 +13,7 @@ */ #include +#include /* symbol_get ; symbol_put */ #include #include #include -- 2.8.4
[PATCH 1/3] ARM: mach-omap2: remove bogus "or_module" from rx51-peripherals
During unrelated work, attempting to remove an include of the linux/module.h in favour of "struct module;" in order to reduce header entanglement, we found doing so caused a build failure in this file. It turns out this file uses __init_or_module which lives in the module.h header, but it wasn't including module.h -- which was being masked by the module.h in include/linux/gpio/driver.h - the one we want to remove/replace. However, if we dig into Makefile / Kconfig we find: mach-omap2/board-rx51-peripherals.o > mach-omap2/Makefile:obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o arch/arm/mach-omap2/Kconfig:config MACH_NOKIA_RX51 arch/arm/mach-omap2/Kconfig:bool "Nokia N900 (RX-51) phone" ...and hence the __init_or_module is pointless, as it will always evaluate to plain __init. With ARM and GPIO being different subsystems, we'll need to get this in ARM 1st, and then wait a release before changing the GPIO header, otherwise we'll risk triggering build failures. Cc: Tony LindgrenCc: Russell King Cc: Linus Walleij Cc: Alexandre Courbot Cc: linux-o...@vger.kernel.org Cc: linux-g...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Paul Gortmaker --- arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index a5ab712c1a59..4ddda1d33ec1 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -978,7 +978,7 @@ static struct twl4030_platform_data rx51_twldata __initdata = { .vio= _vio, }; -static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = { +static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata = { .power_gpio = 98, }; -- 2.8.4
[PATCH 0/3] ARM: fix three implicit module use cases fed via gpio
While working on some for-4.9 cleanups of linux/gpio/driver.h it was found that changes there caused build failures when walking all the ARM defconfigs, in ARM specific mach-* files. The proposed GPIO header change is just this: --- --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -16,6 +15,7 @@ struct of_phandle_args; struct device_node; struct seq_file; struct gpio_device; +struct module; #ifdef CONFIG_GPIOLIB --- ...which is what we've already got in ~50 other include/linux/* files to try and keep cross contamination entanglement at a minimum. So we uncovered three users in ARM specific files relying on the above presence in this header, vs. dealing with it within the driver itself. But with ARM and GPIO being different subsystems, we'll need to get this in ARM 1st, and then wait a release before changing the GPIO header, otherwise we'll risk triggering these three build failures. So, if folks consider these three trivial changes OK for late in the for-4.8 cycle, then great. Otherwise I'll resubmit the ARM parts for for-4.9 and the GPIO bits for the one after that. [Yes, there were gpio implicit users too, but they are easily sync'd with the gpio header change being at the end of that series.] Paul. -- Cc: Alexandre Courbot Cc: Daniel Mack Cc: Haojian Zhuang Cc: Linus Walleij Cc: linux-arm-ker...@lists.infradead.org Cc: linux-g...@vger.kernel.org Cc: linux-o...@vger.kernel.org Cc: Robert Jarzmik Cc: Russell King Cc: Tony Lindgren Paul Gortmaker (3): ARM: mach-omap2: remove bogus "or_module" from rx51-peripherals ARM: pxa: add module.h for corgi symbol_get/symbol_put usage ARM: pxa: add module.h for spitz symbol_get/symbol_put usage arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- arch/arm/mach-pxa/corgi.c| 1 + arch/arm/mach-pxa/spitz.c| 1 + 3 files changed, 3 insertions(+), 1 deletion(-) -- 2.8.4
[PATCH 2/3] ARM: pxa: add module.h for corgi symbol_get/symbol_put usage
During unrelated work, attempting to remove an include of the linux/module.h in favour of "struct module;" in order to reduce header entanglement, we found doing so caused a build failure in this file. mach-pxa/corgi.c: In function 'corgi_bl_kick_battery': mach-pxa/corgi.c:548:2: error: implicit declaration of function 'symbol_get' [-Werror=implicit-function-declaration] mach-pxa/corgi.c:548:12: warning: assignment makes pointer from integer without a cast [enabled by default] mach-pxa/corgi.c:551:3: error: implicit declaration of function 'symbol_put' [-Werror=implicit-function-declaration] It turns out this file uses symbol_get/symbol_put which live in the module.h header, but it wasn't including module.h -- which was being masked by the module.h in include/linux/gpio/driver.h - the one we want to remove/replace. With ARM and GPIO being different subsystems, we'll need to get this in ARM 1st, and then wait a release before changing the GPIO header, otherwise we'll risk triggering build failures. Cc: Daniel Mack Cc: Haojian Zhuang Cc: Robert Jarzmik Cc: Russell King Cc: Linus Walleij Cc: Alexandre Courbot Cc: linux-o...@vger.kernel.org Cc: linux-g...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Paul Gortmaker --- arch/arm/mach-pxa/corgi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index aa952979461f..183cd3446f25 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -13,6 +13,7 @@ */ #include +#include /* symbol_get ; symbol_put */ #include #include #include -- 2.8.4
[PATCH 1/3] ARM: mach-omap2: remove bogus "or_module" from rx51-peripherals
During unrelated work, attempting to remove an include of the linux/module.h in favour of "struct module;" in order to reduce header entanglement, we found doing so caused a build failure in this file. It turns out this file uses __init_or_module which lives in the module.h header, but it wasn't including module.h -- which was being masked by the module.h in include/linux/gpio/driver.h - the one we want to remove/replace. However, if we dig into Makefile / Kconfig we find: mach-omap2/board-rx51-peripherals.o > mach-omap2/Makefile:obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o arch/arm/mach-omap2/Kconfig:config MACH_NOKIA_RX51 arch/arm/mach-omap2/Kconfig:bool "Nokia N900 (RX-51) phone" ...and hence the __init_or_module is pointless, as it will always evaluate to plain __init. With ARM and GPIO being different subsystems, we'll need to get this in ARM 1st, and then wait a release before changing the GPIO header, otherwise we'll risk triggering build failures. Cc: Tony Lindgren Cc: Russell King Cc: Linus Walleij Cc: Alexandre Courbot Cc: linux-o...@vger.kernel.org Cc: linux-g...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Paul Gortmaker --- arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index a5ab712c1a59..4ddda1d33ec1 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -978,7 +978,7 @@ static struct twl4030_platform_data rx51_twldata __initdata = { .vio= _vio, }; -static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = { +static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata = { .power_gpio = 98, }; -- 2.8.4
Re: [PATCH v2 01/10] binfmt_flat: assorted cleanups
On Tue, 19 Jul 2016, Geert Uytterhoeven wrote: > On Tue, Jul 19, 2016 at 6:52 AM, Greg Ungererwrote: > > Seeing as you have modified quite a few printk calls is it worth > > while annotating them with appropriate KERN_ERR, KERN_INFO, etc? > > You mean pr_err(), pr_info(), ... ;-) Done. Included in v3. Nicolas
Re: [PATCH v2 01/10] binfmt_flat: assorted cleanups
On Tue, 19 Jul 2016, Geert Uytterhoeven wrote: > On Tue, Jul 19, 2016 at 6:52 AM, Greg Ungerer wrote: > > Seeing as you have modified quite a few printk calls is it worth > > while annotating them with appropriate KERN_ERR, KERN_INFO, etc? > > You mean pr_err(), pr_info(), ... ;-) Done. Included in v3. Nicolas
Re: [RFC PATCH] locks: fix file locking on overlayfs
On Tue, Jul 19, 2016 at 8:01 PM, Jeff Laytonwrote: > On Tue, 2016-07-19 at 14:27 +0200, Miklos Szeredi wrote: >> > diff --git a/mm/mmap.c b/mm/mmap.c >> index de2c1769cc68..a023caff19d5 100644 >> --- a/mm/mmap.c >> +++ b/mm/mmap.c >> @@ -126,7 +126,7 @@ static void __remove_shared_vm_struct(struct >> vm_area_struct *vma, >> > struct file *file, struct address_space *mapping) >> { >> > if (vma->vm_flags & VM_DENYWRITE) >> > - atomic_inc(_inode(file)->i_writecount); >> > + atomic_inc(_inode(file)->i_writecount); >> > if (vma->vm_flags & VM_SHARED) >> > mapping_unmap_writable(mapping); >> > > > Not sure about this bit with the i_writecount, as it's used for other > things besides file locking. Could this cause problems when accessing > the writable layer while the overlay is active? ISTR that the openwrt > backup instructions have you do exactly that when overlayfs is used. Hmm, We could get write access on upper layer only. That's trivial for open (it was done that way previously) but needs some thought for truncate(2). What we want for truncate is copy up to happen before get_write_access(). It's simple enough with get_write_access(d_inode(d_real(dentry, NULL, O_WRONLY))); plus error handling. Problem with this is if something fails after that, then copy-up was done needlessly. E.g. if break_lease() was interrupted. Probably not a big deal in practice. The other thing is what happens if there's a denywrite on a lower file that is then opened for write or truncated. With the current patch get_write_access() wil fail. With the above modification it will succeed. Either behavior is acceptable, considering that the copy-up does actually create a different file, so the old, denywrite mapping won't be touched. So I'm inclined to go with this approach to prevent issues with access to underlying layers while overlay is active. Thanks, Miklos
Re: [RFC PATCH] locks: fix file locking on overlayfs
On Tue, Jul 19, 2016 at 8:01 PM, Jeff Layton wrote: > On Tue, 2016-07-19 at 14:27 +0200, Miklos Szeredi wrote: >> > diff --git a/mm/mmap.c b/mm/mmap.c >> index de2c1769cc68..a023caff19d5 100644 >> --- a/mm/mmap.c >> +++ b/mm/mmap.c >> @@ -126,7 +126,7 @@ static void __remove_shared_vm_struct(struct >> vm_area_struct *vma, >> > struct file *file, struct address_space *mapping) >> { >> > if (vma->vm_flags & VM_DENYWRITE) >> > - atomic_inc(_inode(file)->i_writecount); >> > + atomic_inc(_inode(file)->i_writecount); >> > if (vma->vm_flags & VM_SHARED) >> > mapping_unmap_writable(mapping); >> > > > Not sure about this bit with the i_writecount, as it's used for other > things besides file locking. Could this cause problems when accessing > the writable layer while the overlay is active? ISTR that the openwrt > backup instructions have you do exactly that when overlayfs is used. Hmm, We could get write access on upper layer only. That's trivial for open (it was done that way previously) but needs some thought for truncate(2). What we want for truncate is copy up to happen before get_write_access(). It's simple enough with get_write_access(d_inode(d_real(dentry, NULL, O_WRONLY))); plus error handling. Problem with this is if something fails after that, then copy-up was done needlessly. E.g. if break_lease() was interrupted. Probably not a big deal in practice. The other thing is what happens if there's a denywrite on a lower file that is then opened for write or truncated. With the current patch get_write_access() wil fail. With the above modification it will succeed. Either behavior is acceptable, considering that the copy-up does actually create a different file, so the old, denywrite mapping won't be touched. So I'm inclined to go with this approach to prevent issues with access to underlying layers while overlay is active. Thanks, Miklos
[PATCH] arm64: dts: mt8173: add tvdpll and vencpll clocks for 4K support
From: Junzhi ZhaoWhen the resolution is set to 4k*2k, the hdmi pixel clock will be 250MHz, however, the correct pixel clock should be 297MHz. Fix this error by adding the correct tvdpll clocks. If MT8173 can support 4K, the vencpll clock should be 800MHz. Add the vencpll clocks to support 4K. Signed-off-by: Junzhi Zhao Signed-off-by: Bibby Hsieh --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 78529e4..e79bacf 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -690,6 +690,8 @@ compatible = "mediatek,mt8173-mmsys", "syscon"; reg = <0 0x1400 0 0x1000>; power-domains = < MT8173_POWER_DOMAIN_MM>; + clocks = < CLK_TOP_VENCPLL>; + clock-names = "vencpll"; #clock-cells = <1>; }; @@ -857,10 +859,22 @@ reg = <0 0x1401d000 0 0x1000>; interrupts = ; power-domains = < MT8173_POWER_DOMAIN_MM>; - clocks = < CLK_MM_DPI_PIXEL>, + clocks = < CLK_TOP_TVDPLL_D2>, +< CLK_TOP_TVDPLL_D4>, +< CLK_TOP_TVDPLL_D8>, +< CLK_TOP_TVDPLL_D16>, +< CLK_TOP_DPI0_SEL>, +< CLK_MM_DPI_PIXEL>, < CLK_MM_DPI_ENGINE>, < CLK_APMIXED_TVDPLL>; - clock-names = "pixel", "engine", "pll"; + clock-names = "tvdpll_d2", + "tvdpll_d4", + "tvdpll_d8", + "tvdpll_d16", + "tvdpll_mux", + "pixel", + "engine", + "pll"; status = "disabled"; }; -- 1.7.9.5
[PATCH] arm64: dts: mt8173: add tvdpll and vencpll clocks for 4K support
From: Junzhi Zhao When the resolution is set to 4k*2k, the hdmi pixel clock will be 250MHz, however, the correct pixel clock should be 297MHz. Fix this error by adding the correct tvdpll clocks. If MT8173 can support 4K, the vencpll clock should be 800MHz. Add the vencpll clocks to support 4K. Signed-off-by: Junzhi Zhao Signed-off-by: Bibby Hsieh --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 78529e4..e79bacf 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -690,6 +690,8 @@ compatible = "mediatek,mt8173-mmsys", "syscon"; reg = <0 0x1400 0 0x1000>; power-domains = < MT8173_POWER_DOMAIN_MM>; + clocks = < CLK_TOP_VENCPLL>; + clock-names = "vencpll"; #clock-cells = <1>; }; @@ -857,10 +859,22 @@ reg = <0 0x1401d000 0 0x1000>; interrupts = ; power-domains = < MT8173_POWER_DOMAIN_MM>; - clocks = < CLK_MM_DPI_PIXEL>, + clocks = < CLK_TOP_TVDPLL_D2>, +< CLK_TOP_TVDPLL_D4>, +< CLK_TOP_TVDPLL_D8>, +< CLK_TOP_TVDPLL_D16>, +< CLK_TOP_DPI0_SEL>, +< CLK_MM_DPI_PIXEL>, < CLK_MM_DPI_ENGINE>, < CLK_APMIXED_TVDPLL>; - clock-names = "pixel", "engine", "pll"; + clock-names = "tvdpll_d2", + "tvdpll_d4", + "tvdpll_d8", + "tvdpll_d16", + "tvdpll_mux", + "pixel", + "engine", + "pll"; status = "disabled"; }; -- 1.7.9.5
[PATCH 2/4] drm/mediatek: enhance the HDMI driving current
From: Junzhi ZhaoIn order to improve 4K resolution performance, we have to enhance the HDMI driving currend when clock rate is greater than 165MHz. Signed-off-by: Junzhi Zhao Signed-off-by: Bibby Hsieh --- drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 89 +--- 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c index 8a24754..a871c14 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c @@ -298,32 +298,69 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, (0x1 << PLL_BR_SHIFT), RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC | RG_HDMITX_PLL_BR); - mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_PRD_IMP_EN); - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, - (0x3 << PRD_IBIAS_CLK_SHIFT) | - (0x3 << PRD_IBIAS_D2_SHIFT) | - (0x3 << PRD_IBIAS_D1_SHIFT) | - (0x3 << PRD_IBIAS_D0_SHIFT), - RG_HDMITX_PRD_IBIAS_CLK | - RG_HDMITX_PRD_IBIAS_D2 | - RG_HDMITX_PRD_IBIAS_D1 | - RG_HDMITX_PRD_IBIAS_D0); - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3, - (0x0 << DRV_IMP_EN_SHIFT), RG_HDMITX_DRV_IMP_EN); - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, - (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) | - (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) | - (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) | - (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT), - RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 | - RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0); - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5, - (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT), - RG_HDMITX_DRV_IBIAS_CLK | RG_HDMITX_DRV_IBIAS_D2 | - RG_HDMITX_DRV_IBIAS_D1 | RG_HDMITX_DRV_IBIAS_D0); + if (rate < 16500) { + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, + RG_HDMITX_PRD_IMP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, + (0x3 << PRD_IBIAS_CLK_SHIFT) | + (0x3 << PRD_IBIAS_D2_SHIFT) | + (0x3 << PRD_IBIAS_D1_SHIFT) | + (0x3 << PRD_IBIAS_D0_SHIFT), + RG_HDMITX_PRD_IBIAS_CLK | + RG_HDMITX_PRD_IBIAS_D2 | + RG_HDMITX_PRD_IBIAS_D1 | + RG_HDMITX_PRD_IBIAS_D0); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3, + (0x0 << DRV_IMP_EN_SHIFT), + RG_HDMITX_DRV_IMP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, + (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) | + (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) | + (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) | + (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT), + RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 | + RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5, + (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) | + (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) | + (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) | + (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT), + RG_HDMITX_DRV_IBIAS_CLK | + RG_HDMITX_DRV_IBIAS_D2 | + RG_HDMITX_DRV_IBIAS_D1 | + RG_HDMITX_DRV_IBIAS_D0); + } else { + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3, + RG_HDMITX_PRD_IMP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, + (0x6 << PRD_IBIAS_CLK_SHIFT) | + (0x6 << PRD_IBIAS_D2_SHIFT) | + (0x6 << PRD_IBIAS_D1_SHIFT) | + (0x6 << PRD_IBIAS_D0_SHIFT),
[PATCH 2/4] drm/mediatek: enhance the HDMI driving current
From: Junzhi Zhao In order to improve 4K resolution performance, we have to enhance the HDMI driving currend when clock rate is greater than 165MHz. Signed-off-by: Junzhi Zhao Signed-off-by: Bibby Hsieh --- drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 89 +--- 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c index 8a24754..a871c14 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c @@ -298,32 +298,69 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, (0x1 << PLL_BR_SHIFT), RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC | RG_HDMITX_PLL_BR); - mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_PRD_IMP_EN); - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, - (0x3 << PRD_IBIAS_CLK_SHIFT) | - (0x3 << PRD_IBIAS_D2_SHIFT) | - (0x3 << PRD_IBIAS_D1_SHIFT) | - (0x3 << PRD_IBIAS_D0_SHIFT), - RG_HDMITX_PRD_IBIAS_CLK | - RG_HDMITX_PRD_IBIAS_D2 | - RG_HDMITX_PRD_IBIAS_D1 | - RG_HDMITX_PRD_IBIAS_D0); - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3, - (0x0 << DRV_IMP_EN_SHIFT), RG_HDMITX_DRV_IMP_EN); - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, - (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) | - (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) | - (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) | - (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT), - RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 | - RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0); - mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5, - (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) | - (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT), - RG_HDMITX_DRV_IBIAS_CLK | RG_HDMITX_DRV_IBIAS_D2 | - RG_HDMITX_DRV_IBIAS_D1 | RG_HDMITX_DRV_IBIAS_D0); + if (rate < 16500) { + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, + RG_HDMITX_PRD_IMP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, + (0x3 << PRD_IBIAS_CLK_SHIFT) | + (0x3 << PRD_IBIAS_D2_SHIFT) | + (0x3 << PRD_IBIAS_D1_SHIFT) | + (0x3 << PRD_IBIAS_D0_SHIFT), + RG_HDMITX_PRD_IBIAS_CLK | + RG_HDMITX_PRD_IBIAS_D2 | + RG_HDMITX_PRD_IBIAS_D1 | + RG_HDMITX_PRD_IBIAS_D0); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3, + (0x0 << DRV_IMP_EN_SHIFT), + RG_HDMITX_DRV_IMP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, + (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) | + (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) | + (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) | + (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT), + RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 | + RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5, + (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) | + (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) | + (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) | + (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT), + RG_HDMITX_DRV_IBIAS_CLK | + RG_HDMITX_DRV_IBIAS_D2 | + RG_HDMITX_DRV_IBIAS_D1 | + RG_HDMITX_DRV_IBIAS_D0); + } else { + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3, + RG_HDMITX_PRD_IMP_EN); + mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, + (0x6 << PRD_IBIAS_CLK_SHIFT) | + (0x6 << PRD_IBIAS_D2_SHIFT) | + (0x6 << PRD_IBIAS_D1_SHIFT) | + (0x6 << PRD_IBIAS_D0_SHIFT), + RG_HDMITX_PRD_IBIAS_CLK | +