Re: [GIT PULL] tpmdd fixes for Linux 4.8

2016-07-19 Thread James Morris
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

2016-07-19 Thread James Morris
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

2016-07-19 Thread Huang Rui
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

2016-07-19 Thread Huang Rui
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

2016-07-19 Thread Christophe JAILLET
'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

2016-07-19 Thread Christophe JAILLET
'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

2016-07-19 Thread Stephen Rothwell
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

2016-07-19 Thread Stephen Rothwell
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'

2016-07-19 Thread Andrey Smirnov
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 2/2] mtd: nand: Get rid of needless 'goto'

2016-07-19 Thread Andrey Smirnov
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

2016-07-19 Thread Andrey Smirnov
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



[PATCH v2 1/2] mtd: nand: Error out if cmd_ctrl() is missing

2016-07-19 Thread Andrey Smirnov
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

2016-07-19 Thread Stephen Rothwell
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

2016-07-19 Thread Stephen Rothwell
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

2016-07-19 Thread Stephen Rothwell
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

2016-07-19 Thread Stephen Rothwell
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

2016-07-19 Thread Lucas De Marchi
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

2016-07-19 Thread Lucas De Marchi
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

2016-07-19 Thread Juergen Gross
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

2016-07-19 Thread Juergen Gross
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

2016-07-19 Thread Stephen Rothwell
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

2016-07-19 Thread Stephen Rothwell
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

2016-07-19 Thread Amitoj Kaur Chawla
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

2016-07-19 Thread Amitoj Kaur Chawla
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

2016-07-19 Thread SF Markus Elfring
 @@ -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

2016-07-19 Thread SF Markus Elfring
 @@ -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

2016-07-19 Thread Tomasz Nowicki

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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Tomasz Nowicki

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

2016-07-19 Thread Nicolas Pitre
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 ...)

2016-07-19 Thread Jike Song
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 ...)

2016-07-19 Thread Jike Song
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

2016-07-19 Thread Jason Low
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

2016-07-19 Thread Jason Low
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?

2016-07-19 Thread Binoy Jayan
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: staging/wilc1000: wrong conversion to completion?

2016-07-19 Thread Binoy Jayan
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

2016-07-19 Thread Juergen Gross
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

2016-07-19 Thread Juergen Gross
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

2016-07-19 Thread Alexey Kardashevskiy
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

2016-07-19 Thread Alexey Kardashevskiy
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 

[PATCH kernel v2 1/2] powerpc/iommu: Stop using @current in mm_iommu_xxx

2016-07-19 Thread Alexey Kardashevskiy
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

2016-07-19 Thread Alexey Kardashevskiy
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

2016-07-19 Thread Alexey Kardashevskiy
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

2016-07-19 Thread Alexey Kardashevskiy
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

2016-07-19 Thread Joe Perches
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

2016-07-19 Thread Joe Perches
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

2016-07-19 Thread Alison Schofield
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] iio: accel: bma180: use iio helper function to guarantee direct mode

2016-07-19 Thread Alison Schofield
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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 

[PATCH v3 02/12] binfmt_flat: convert printk invocations to their modern form

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Hari Bathini


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 

Re: [v2,1/2] refactor code parsing size based on memory range

2016-07-19 Thread Hari Bathini


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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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 */
+   

[PATCH v3 03/12] binfmt_flat: prevent kernel dammage from corrupted executable headers

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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()

2016-07-19 Thread Nicolas Pitre
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 09/12] binfmt_flat: use clear_user() rather than memset() to clear .bss

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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()

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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 */
  

[PATCH v3 10/12] binfmt_flat: update libraries' data segment pointer with userspace accessors

2016-07-19 Thread Nicolas Pitre
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 11/12] binfmt_flat: add MMU-specific support

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Dexuan Cui
> 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

2016-07-19 Thread Dexuan Cui
> 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

2016-07-19 Thread Zhou Chengming
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

2016-07-19 Thread Zhou Chengming
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

2016-07-19 Thread b...@redhat.com
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

2016-07-19 Thread b...@redhat.com
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

2016-07-19 Thread David Miller
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

2016-07-19 Thread Paul Gortmaker
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



Re: [Patch-V2 2/3] chcr: Support for Chelsio's Crypto Hardware

2016-07-19 Thread David Miller
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

2016-07-19 Thread Paul Gortmaker
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

2016-07-19 Thread Paul Gortmaker
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

2016-07-19 Thread Paul Gortmaker
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

2016-07-19 Thread Paul Gortmaker
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



[PATCH 0/3] ARM: fix three implicit module use cases fed via gpio

2016-07-19 Thread Paul Gortmaker
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

2016-07-19 Thread Paul Gortmaker
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

2016-07-19 Thread Paul Gortmaker
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

2016-07-19 Thread Nicolas Pitre
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: [PATCH v2 01/10] binfmt_flat: assorted cleanups

2016-07-19 Thread Nicolas Pitre
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

2016-07-19 Thread Miklos Szeredi
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


Re: [RFC PATCH] locks: fix file locking on overlayfs

2016-07-19 Thread Miklos Szeredi
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

2016-07-19 Thread Bibby Hsieh
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] arm64: dts: mt8173: add tvdpll and vencpll clocks for 4K support

2016-07-19 Thread Bibby Hsieh
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

2016-07-19 Thread Bibby Hsieh
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),

[PATCH 2/4] drm/mediatek: enhance the HDMI driving current

2016-07-19 Thread Bibby Hsieh
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 |
+ 

  1   2   3   4   5   6   7   8   9   10   >