Re: [PATCH 3/4] can: m_can: Update documentation to mention new fixed transceiver binding

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 06:36:53PM -0500, Franklin S Cooper Jr wrote:
> Add information regarding fixed transceiver binding. This is especially
> important for MCAN since the IP allows CAN FD mode to run significantly
> faster than what most transceivers are capable of.
> 
> Signed-off-by: Franklin S Cooper Jr 
> ---
>  Documentation/devicetree/bindings/net/can/m_can.txt | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/can/m_can.txt 
> b/Documentation/devicetree/bindings/net/can/m_can.txt
> index 9e33177..4440e4b 100644
> --- a/Documentation/devicetree/bindings/net/can/m_can.txt
> +++ b/Documentation/devicetree/bindings/net/can/m_can.txt
> @@ -43,6 +43,11 @@ Required properties:
> Please refer to 2.4.1 Message RAM Configuration in
> Bosch M_CAN user manual for details.
>  
> +Optional properties:
> +- fixed-transceiver  : Fixed-transceiver subnode describing maximum speed
> +   that can be used for CAN and/or CAN-FD modes.  See
> +   
> Documentation/devicetree/bindings/net/can/fixed-transceiver.txt
> +   for details.
>  Example:
>  SoC dtsi:
>  m_can1: can@020e8000 {
> @@ -64,4 +69,9 @@ Board dts:
>   pinctrl-names = "default";
>   pinctrl-0 = <_m_can1>;
>   status = "enabled";
> +
> + fixed-transceiver@0 {

unit-address should have corresponding reg prop or unit-address should 
be dropped.

> + max-arbitration-speed = <100>;
> + max-data-speed = <500>;
> + };
>  };
> -- 
> 2.10.0
> 


Re: [PATCH 3/4] can: m_can: Update documentation to mention new fixed transceiver binding

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 06:36:53PM -0500, Franklin S Cooper Jr wrote:
> Add information regarding fixed transceiver binding. This is especially
> important for MCAN since the IP allows CAN FD mode to run significantly
> faster than what most transceivers are capable of.
> 
> Signed-off-by: Franklin S Cooper Jr 
> ---
>  Documentation/devicetree/bindings/net/can/m_can.txt | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/can/m_can.txt 
> b/Documentation/devicetree/bindings/net/can/m_can.txt
> index 9e33177..4440e4b 100644
> --- a/Documentation/devicetree/bindings/net/can/m_can.txt
> +++ b/Documentation/devicetree/bindings/net/can/m_can.txt
> @@ -43,6 +43,11 @@ Required properties:
> Please refer to 2.4.1 Message RAM Configuration in
> Bosch M_CAN user manual for details.
>  
> +Optional properties:
> +- fixed-transceiver  : Fixed-transceiver subnode describing maximum speed
> +   that can be used for CAN and/or CAN-FD modes.  See
> +   
> Documentation/devicetree/bindings/net/can/fixed-transceiver.txt
> +   for details.
>  Example:
>  SoC dtsi:
>  m_can1: can@020e8000 {
> @@ -64,4 +69,9 @@ Board dts:
>   pinctrl-names = "default";
>   pinctrl-0 = <_m_can1>;
>   status = "enabled";
> +
> + fixed-transceiver@0 {

unit-address should have corresponding reg prop or unit-address should 
be dropped.

> + max-arbitration-speed = <100>;
> + max-data-speed = <500>;
> + };
>  };
> -- 
> 2.10.0
> 


[RFC 2/5] doc: fpga: add sysfs document for fpga region

2017-07-24 Thread Alan Tull
Document the firmware_name attribute added for each
region.

Signed-off-by: Alan Tull 
---
 Documentation/ABI/testing/sysfs-class-fpga-region | 7 +++
 1 file changed, 7 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-region

diff --git a/Documentation/ABI/testing/sysfs-class-fpga-region 
b/Documentation/ABI/testing/sysfs-class-fpga-region
new file mode 100644
index 000..de47645
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-fpga-region
@@ -0,0 +1,7 @@
+What:  /sys/class/fpga_region//firmware_name
+Date:  July 2017
+KernelVersion: 4.15
+Contact:   Alan Tull 
+Description:   Write the name of FPGA image file on the firmware path to
+   program the FPGA region.  Write nothing to free up the
+   FPGA region for reprogramming.
-- 
2.7.4



[RFC 2/5] doc: fpga: add sysfs document for fpga region

2017-07-24 Thread Alan Tull
Document the firmware_name attribute added for each
region.

Signed-off-by: Alan Tull 
---
 Documentation/ABI/testing/sysfs-class-fpga-region | 7 +++
 1 file changed, 7 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-region

diff --git a/Documentation/ABI/testing/sysfs-class-fpga-region 
b/Documentation/ABI/testing/sysfs-class-fpga-region
new file mode 100644
index 000..de47645
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-fpga-region
@@ -0,0 +1,7 @@
+What:  /sys/class/fpga_region//firmware_name
+Date:  July 2017
+KernelVersion: 4.15
+Contact:   Alan Tull 
+Description:   Write the name of FPGA image file on the firmware path to
+   program the FPGA region.  Write nothing to free up the
+   FPGA region for reprogramming.
-- 
2.7.4



[RFC 3/5] fpga: add dev to fpga_image_info

2017-07-24 Thread Alan Tull
This patch should be rolled into the next version of my
"non-dt support for FPGA regions" patchset.

Add a pointer to the device that owns the fpga_image_info to
fpga_image_info.  That way the fpga_image_info_free can
drop the 'dev' parameter and we are left with:

struct fpga_image_info *fpga_image_info_alloc(struct device *dev);

void fpga_image_info_free(struct fpga_image_info *info);

Signed-off-by: Alan Tull 
---
 drivers/fpga/fpga-mgr.c   | 14 ++
 drivers/fpga/of-fpga-region.c |  6 +++---
 include/linux/fpga/fpga-mgr.h |  4 +++-
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index be13cce..af33310 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -40,20 +40,26 @@ struct fpga_image_info *fpga_image_info_alloc(struct device 
*dev)
if (!info)
return ERR_PTR(-ENOMEM);
 
+   get_device(dev);
+   info->dev = dev;
+
return info;
 }
 EXPORT_SYMBOL_GPL(fpga_image_info_alloc);
 
-void fpga_image_info_free(struct device *dev,
- struct fpga_image_info *info)
+void fpga_image_info_free(struct fpga_image_info *info)
 {
+   struct device *dev;
+
if (!info)
return;
 
if (info->firmware_name)
-   devm_kfree(dev, info->firmware_name);
+   devm_kfree(info->dev, info->firmware_name);
 
-   devm_kfree(dev, info);
+   dev = info->dev;
+   devm_kfree(info->dev, info);
+   put_device(dev);
 }
 EXPORT_SYMBOL_GPL(fpga_image_info_free);
 
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index c2ea9b6..6bb5799 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -273,7 +273,7 @@ static struct fpga_image_info *of_fpga_region_parse_ov(
 
return info;
 ret_no_info:
-   fpga_image_info_free(dev, info);
+   fpga_image_info_free(info);
return ERR_PTR(ret);
 }
 
@@ -314,7 +314,7 @@ static int of_fpga_region_notify_pre_apply(struct 
fpga_region *region,
ret = fpga_region_program_fpga(region);
if (ret) {
/* error; reject overlay */
-   fpga_image_info_free(dev, info);
+   fpga_image_info_free(info);
region->info = NULL;
}
 
@@ -335,7 +335,7 @@ static void of_fpga_region_notify_post_remove(struct 
fpga_region *region,
 {
fpga_bridges_disable(>bridge_list);
fpga_bridges_put(>bridge_list);
-   fpga_image_info_free(>dev, region->info);
+   fpga_image_info_free(region->info);
region->info = NULL;
 }
 
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
index 50954cb..ddc56c0 100644
--- a/include/linux/fpga/fpga-mgr.h
+++ b/include/linux/fpga/fpga-mgr.h
@@ -79,6 +79,7 @@ enum fpga_mgr_states {
 
 /**
  * struct fpga_image_info - information specific to a FPGA image
+ * @dev: device that owns this info
  * @flags: boolean flags as defined above
  * @enable_timeout_us: maximum time to enable traffic through bridge (uSec)
  * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
@@ -91,6 +92,7 @@ enum fpga_mgr_states {
  * @overlay: Device Tree overlay
  */
 struct fpga_image_info {
+   struct device *dev;
u32 flags;
u32 enable_timeout_us;
u32 disable_timeout_us;
@@ -153,7 +155,7 @@ struct fpga_manager {
 
 struct fpga_image_info *fpga_image_info_alloc(struct device *dev);
 
-void fpga_image_info_free(struct device *dev, struct fpga_image_info *info);
+void fpga_image_info_free(struct fpga_image_info *info);
 
 int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info);
 
-- 
2.7.4



[RFC 3/5] fpga: add dev to fpga_image_info

2017-07-24 Thread Alan Tull
This patch should be rolled into the next version of my
"non-dt support for FPGA regions" patchset.

Add a pointer to the device that owns the fpga_image_info to
fpga_image_info.  That way the fpga_image_info_free can
drop the 'dev' parameter and we are left with:

struct fpga_image_info *fpga_image_info_alloc(struct device *dev);

void fpga_image_info_free(struct fpga_image_info *info);

Signed-off-by: Alan Tull 
---
 drivers/fpga/fpga-mgr.c   | 14 ++
 drivers/fpga/of-fpga-region.c |  6 +++---
 include/linux/fpga/fpga-mgr.h |  4 +++-
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index be13cce..af33310 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -40,20 +40,26 @@ struct fpga_image_info *fpga_image_info_alloc(struct device 
*dev)
if (!info)
return ERR_PTR(-ENOMEM);
 
+   get_device(dev);
+   info->dev = dev;
+
return info;
 }
 EXPORT_SYMBOL_GPL(fpga_image_info_alloc);
 
-void fpga_image_info_free(struct device *dev,
- struct fpga_image_info *info)
+void fpga_image_info_free(struct fpga_image_info *info)
 {
+   struct device *dev;
+
if (!info)
return;
 
if (info->firmware_name)
-   devm_kfree(dev, info->firmware_name);
+   devm_kfree(info->dev, info->firmware_name);
 
-   devm_kfree(dev, info);
+   dev = info->dev;
+   devm_kfree(info->dev, info);
+   put_device(dev);
 }
 EXPORT_SYMBOL_GPL(fpga_image_info_free);
 
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index c2ea9b6..6bb5799 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -273,7 +273,7 @@ static struct fpga_image_info *of_fpga_region_parse_ov(
 
return info;
 ret_no_info:
-   fpga_image_info_free(dev, info);
+   fpga_image_info_free(info);
return ERR_PTR(ret);
 }
 
@@ -314,7 +314,7 @@ static int of_fpga_region_notify_pre_apply(struct 
fpga_region *region,
ret = fpga_region_program_fpga(region);
if (ret) {
/* error; reject overlay */
-   fpga_image_info_free(dev, info);
+   fpga_image_info_free(info);
region->info = NULL;
}
 
@@ -335,7 +335,7 @@ static void of_fpga_region_notify_post_remove(struct 
fpga_region *region,
 {
fpga_bridges_disable(>bridge_list);
fpga_bridges_put(>bridge_list);
-   fpga_image_info_free(>dev, region->info);
+   fpga_image_info_free(region->info);
region->info = NULL;
 }
 
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
index 50954cb..ddc56c0 100644
--- a/include/linux/fpga/fpga-mgr.h
+++ b/include/linux/fpga/fpga-mgr.h
@@ -79,6 +79,7 @@ enum fpga_mgr_states {
 
 /**
  * struct fpga_image_info - information specific to a FPGA image
+ * @dev: device that owns this info
  * @flags: boolean flags as defined above
  * @enable_timeout_us: maximum time to enable traffic through bridge (uSec)
  * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
@@ -91,6 +92,7 @@ enum fpga_mgr_states {
  * @overlay: Device Tree overlay
  */
 struct fpga_image_info {
+   struct device *dev;
u32 flags;
u32 enable_timeout_us;
u32 disable_timeout_us;
@@ -153,7 +155,7 @@ struct fpga_manager {
 
 struct fpga_image_info *fpga_image_info_alloc(struct device *dev);
 
-void fpga_image_info_free(struct device *dev, struct fpga_image_info *info);
+void fpga_image_info_free(struct fpga_image_info *info);
 
 int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info);
 
-- 
2.7.4



[RFC 5/5] fpga-region support for fdt headers on fpga images

2017-07-24 Thread Alan Tull
Support a FDT header for FPGA images.  Header format is a simplified
FIT containing at most one FPGA image and one DT overlay.

The FPGA image section includes FPGA image info properties needed for
programming.

If present, the DT overlay image is applied after the FPGA is
programmed.

Both images are optional.  If the DT overlay isn't present, this
interface may be used on systems running without a live Device Tree.

todo: add scatter gather table support.

Signed-off-by: Alan Tull 
---
 drivers/fpga/Kconfig |   7 +
 drivers/fpga/fpga-region.c   | 440 +++
 drivers/fpga/of-fpga-region.c|   7 +
 include/linux/fpga/fpga-mgr.h|   9 +
 include/linux/fpga/fpga-region.h |   1 +
 5 files changed, 464 insertions(+)

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index c349c42..f4b595b 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -19,6 +19,13 @@ config FPGA_REGION
  and the FPGA Bridges associated with either a reconfigurable
  region of an FPGA or a whole FPGA.
 
+config FPGA_REGION_SYSFS
+   bool "FPGA Region Sysfs"
+   depends on FPGA_REGION
+   help
+ FPGA Region sysfs interface.  This creates sysfs files under
+ /sys/class/fpga_region/ to control programming FPGA regions.
+
 config OF_FPGA_REGION
tristate "FPGA Region Device Tree Overlay Support"
depends on OF && FPGA_REGION
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 944d24a..a9dd61e 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -4,6 +4,15 @@
  *  Copyright (C) 2013-2016 Altera Corporation
  *  Copyright (C) 2017 Intel Corporation
  *
+ * Dynamic DT code borrowed from Pantelis Antoniou's
+ * "OF: DT-Overlay configfs interface (v7)" patch.
+ * Copyright (C) 2013 - Pantelis Antoniou 
+ *
+ * FIT image parsing adapted from u-boot
+ * (C) Copyright 2008 Semihalf
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, w...@denx.de.
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
  * version 2, as published by the Free Software Foundation.
@@ -17,6 +26,7 @@
  * this program.  If not, see .
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -24,6 +34,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 
@@ -91,6 +104,312 @@ static void fpga_region_put(struct fpga_region *region)
mutex_unlock(>mutex);
 }
 
+/*
+ * todo - of_fpga_region_overlay_apply() is adapted from create_overlay()
+ * (some changed structs) from Pantelis Antoniou's
+ * "OF: DT-Overlay configfs interface (v7)" patch.
+ * that hasn't been accepted upstream yet.
+ */
+static int of_fpga_region_overlay_apply(struct fpga_region *region)
+{
+   struct device *dev = >dev;
+   struct fpga_image_info *info = region->info;
+   int ret;
+
+   WARN_ON(info->overlay);
+
+   of_fdt_unflatten_tree((void *)info->fdt_blob, NULL,
+ >overlay);
+   if (!info->overlay) {
+   dev_err(dev, "%s: failed to unflatten tree\n", __func__);
+   ret = -EINVAL;
+   return ret;
+   }
+   pr_debug("%s: unflattened OK\n", __func__);
+
+   /* mark it as detached */
+   of_node_set_flag(info->overlay, OF_DETACHED);
+
+   /* FDT in bitstream should not specify an external FPGA image to load */
+   if (of_find_property(info->overlay, "firmware-name", NULL))
+   dev_warn(dev, "Ignoring firmware-name property in FPGA image 
header\n");
+
+   /* perform resolution */
+   ret = of_resolve_phandles(info->overlay);
+   if (ret != 0) {
+   dev_err(dev, "%s: Failed to resolve tree\n", __func__);
+   return ret;
+   }
+   pr_debug("%s: resolved OK\n", __func__);
+
+   ret = of_overlay_create(info->overlay);
+   if (ret < 0) {
+   dev_err(dev, "%s: Failed to create overlay (err=%d)\n",
+   __func__, ret);
+   return ret;
+   }
+   info->ov_id = ret;
+
+   return 0;
+}
+
+static void fpga_region_overlay_rm(struct fpga_region *region)
+{
+   struct device *dev = >dev;
+   struct fpga_image_info *info = region->info;
+
+   if (info->ov_id >= 0) {
+   of_overlay_destroy(info->ov_id);
+   info->ov_id = -1;
+   }
+   if (info->fdt_blob) {
+   devm_kfree(dev, info->fdt_blob);
+   info->fdt_blob = NULL;
+   }
+}
+
+/**
+ * get_data_prop - get pointer, length of binary data
+ *
+ * FDT is in info->header.  Find the data property at the node offset.
+ * Give a pointer to the binary data.
+ *
+ * Returns length of data or zero
+ */
+static int get_data_prop(struct fpga_image_info *info,
+  

[RFC 4/5] fpga-region: new function fpga_region_free

2017-07-24 Thread Alan Tull
Add FPGA region API function fpga_region_free() that
undoes some of what fpga_region_program_fpga() does
to free up a region to be reprogrammed.

Signed-off-by: Alan Tull 
---
 drivers/fpga/fpga-region.c   | 20 
 drivers/fpga/of-fpga-region.c|  5 +
 include/linux/fpga/fpga-region.h |  2 ++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index afc6188..944d24a 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -162,6 +162,26 @@ int fpga_region_program_fpga(struct fpga_region *region)
 }
 EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
 
+/**
+ * fpga_region_free
+ * Undo some of what fpga_region_program_fpga() did to free up
+ * region to be reprogrammed.
+ * @region: FPGA region
+ */
+void fpga_region_free(struct fpga_region *region)
+{
+   if (!region->info)
+   return;
+
+   fpga_bridges_disable(>bridge_list);
+   if (region->get_bridges)
+   fpga_bridges_put(>bridge_list);
+
+   fpga_image_info_free(region->info);
+   region->info = NULL;
+}
+EXPORT_SYMBOL_GPL(fpga_region_free);
+
 int fpga_region_register(struct device *dev, struct fpga_region *region)
 {
int id, ret = 0;
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 6bb5799..019ca37 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -333,10 +333,7 @@ static int of_fpga_region_notify_pre_apply(struct 
fpga_region *region,
 static void of_fpga_region_notify_post_remove(struct fpga_region *region,
  struct of_overlay_notify_data *nd)
 {
-   fpga_bridges_disable(>bridge_list);
-   fpga_bridges_put(>bridge_list);
-   fpga_image_info_free(region->info);
-   region->info = NULL;
+   fpga_region_free(region);
 }
 
 /**
diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h
index f2eecdd..3b6f0b0 100644
--- a/include/linux/fpga/fpga-region.h
+++ b/include/linux/fpga/fpga-region.h
@@ -32,6 +32,8 @@ struct fpga_region *fpga_region_class_find(
int (*match)(struct device *, const void *));
 
 int fpga_region_program_fpga(struct fpga_region *region);
+void fpga_region_free(struct fpga_region *region);
+
 int fpga_region_register(struct device *dev, struct fpga_region *region);
 int fpga_region_unregister(struct fpga_region *region);
 
-- 
2.7.4



[RFC 4/5] fpga-region: new function fpga_region_free

2017-07-24 Thread Alan Tull
Add FPGA region API function fpga_region_free() that
undoes some of what fpga_region_program_fpga() does
to free up a region to be reprogrammed.

Signed-off-by: Alan Tull 
---
 drivers/fpga/fpga-region.c   | 20 
 drivers/fpga/of-fpga-region.c|  5 +
 include/linux/fpga/fpga-region.h |  2 ++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index afc6188..944d24a 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -162,6 +162,26 @@ int fpga_region_program_fpga(struct fpga_region *region)
 }
 EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
 
+/**
+ * fpga_region_free
+ * Undo some of what fpga_region_program_fpga() did to free up
+ * region to be reprogrammed.
+ * @region: FPGA region
+ */
+void fpga_region_free(struct fpga_region *region)
+{
+   if (!region->info)
+   return;
+
+   fpga_bridges_disable(>bridge_list);
+   if (region->get_bridges)
+   fpga_bridges_put(>bridge_list);
+
+   fpga_image_info_free(region->info);
+   region->info = NULL;
+}
+EXPORT_SYMBOL_GPL(fpga_region_free);
+
 int fpga_region_register(struct device *dev, struct fpga_region *region)
 {
int id, ret = 0;
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 6bb5799..019ca37 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -333,10 +333,7 @@ static int of_fpga_region_notify_pre_apply(struct 
fpga_region *region,
 static void of_fpga_region_notify_post_remove(struct fpga_region *region,
  struct of_overlay_notify_data *nd)
 {
-   fpga_bridges_disable(>bridge_list);
-   fpga_bridges_put(>bridge_list);
-   fpga_image_info_free(region->info);
-   region->info = NULL;
+   fpga_region_free(region);
 }
 
 /**
diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h
index f2eecdd..3b6f0b0 100644
--- a/include/linux/fpga/fpga-region.h
+++ b/include/linux/fpga/fpga-region.h
@@ -32,6 +32,8 @@ struct fpga_region *fpga_region_class_find(
int (*match)(struct device *, const void *));
 
 int fpga_region_program_fpga(struct fpga_region *region);
+void fpga_region_free(struct fpga_region *region);
+
 int fpga_region_register(struct device *dev, struct fpga_region *region);
 int fpga_region_unregister(struct fpga_region *region);
 
-- 
2.7.4



[RFC 5/5] fpga-region support for fdt headers on fpga images

2017-07-24 Thread Alan Tull
Support a FDT header for FPGA images.  Header format is a simplified
FIT containing at most one FPGA image and one DT overlay.

The FPGA image section includes FPGA image info properties needed for
programming.

If present, the DT overlay image is applied after the FPGA is
programmed.

Both images are optional.  If the DT overlay isn't present, this
interface may be used on systems running without a live Device Tree.

todo: add scatter gather table support.

Signed-off-by: Alan Tull 
---
 drivers/fpga/Kconfig |   7 +
 drivers/fpga/fpga-region.c   | 440 +++
 drivers/fpga/of-fpga-region.c|   7 +
 include/linux/fpga/fpga-mgr.h|   9 +
 include/linux/fpga/fpga-region.h |   1 +
 5 files changed, 464 insertions(+)

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index c349c42..f4b595b 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -19,6 +19,13 @@ config FPGA_REGION
  and the FPGA Bridges associated with either a reconfigurable
  region of an FPGA or a whole FPGA.
 
+config FPGA_REGION_SYSFS
+   bool "FPGA Region Sysfs"
+   depends on FPGA_REGION
+   help
+ FPGA Region sysfs interface.  This creates sysfs files under
+ /sys/class/fpga_region/ to control programming FPGA regions.
+
 config OF_FPGA_REGION
tristate "FPGA Region Device Tree Overlay Support"
depends on OF && FPGA_REGION
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 944d24a..a9dd61e 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -4,6 +4,15 @@
  *  Copyright (C) 2013-2016 Altera Corporation
  *  Copyright (C) 2017 Intel Corporation
  *
+ * Dynamic DT code borrowed from Pantelis Antoniou's
+ * "OF: DT-Overlay configfs interface (v7)" patch.
+ * Copyright (C) 2013 - Pantelis Antoniou 
+ *
+ * FIT image parsing adapted from u-boot
+ * (C) Copyright 2008 Semihalf
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, w...@denx.de.
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
  * version 2, as published by the Free Software Foundation.
@@ -17,6 +26,7 @@
  * this program.  If not, see .
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -24,6 +34,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 
@@ -91,6 +104,312 @@ static void fpga_region_put(struct fpga_region *region)
mutex_unlock(>mutex);
 }
 
+/*
+ * todo - of_fpga_region_overlay_apply() is adapted from create_overlay()
+ * (some changed structs) from Pantelis Antoniou's
+ * "OF: DT-Overlay configfs interface (v7)" patch.
+ * that hasn't been accepted upstream yet.
+ */
+static int of_fpga_region_overlay_apply(struct fpga_region *region)
+{
+   struct device *dev = >dev;
+   struct fpga_image_info *info = region->info;
+   int ret;
+
+   WARN_ON(info->overlay);
+
+   of_fdt_unflatten_tree((void *)info->fdt_blob, NULL,
+ >overlay);
+   if (!info->overlay) {
+   dev_err(dev, "%s: failed to unflatten tree\n", __func__);
+   ret = -EINVAL;
+   return ret;
+   }
+   pr_debug("%s: unflattened OK\n", __func__);
+
+   /* mark it as detached */
+   of_node_set_flag(info->overlay, OF_DETACHED);
+
+   /* FDT in bitstream should not specify an external FPGA image to load */
+   if (of_find_property(info->overlay, "firmware-name", NULL))
+   dev_warn(dev, "Ignoring firmware-name property in FPGA image 
header\n");
+
+   /* perform resolution */
+   ret = of_resolve_phandles(info->overlay);
+   if (ret != 0) {
+   dev_err(dev, "%s: Failed to resolve tree\n", __func__);
+   return ret;
+   }
+   pr_debug("%s: resolved OK\n", __func__);
+
+   ret = of_overlay_create(info->overlay);
+   if (ret < 0) {
+   dev_err(dev, "%s: Failed to create overlay (err=%d)\n",
+   __func__, ret);
+   return ret;
+   }
+   info->ov_id = ret;
+
+   return 0;
+}
+
+static void fpga_region_overlay_rm(struct fpga_region *region)
+{
+   struct device *dev = >dev;
+   struct fpga_image_info *info = region->info;
+
+   if (info->ov_id >= 0) {
+   of_overlay_destroy(info->ov_id);
+   info->ov_id = -1;
+   }
+   if (info->fdt_blob) {
+   devm_kfree(dev, info->fdt_blob);
+   info->fdt_blob = NULL;
+   }
+}
+
+/**
+ * get_data_prop - get pointer, length of binary data
+ *
+ * FDT is in info->header.  Find the data property at the node offset.
+ * Give a pointer to the binary data.
+ *
+ * Returns length of data or zero
+ */
+static int get_data_prop(struct fpga_image_info *info,
+int noffset, const void **data)
+{
+   

[RFC 1/5] doc: fpga: add document for the fdt FPGA header

2017-07-24 Thread Alan Tull
Add a document for the open source fdt FPGA header.

Signed-off-by: Alan Tull 
---
 Documentation/fpga/fpga-header.txt | 103 +
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/fpga/fpga-header.txt

diff --git a/Documentation/fpga/fpga-header.txt 
b/Documentation/fpga/fpga-header.txt
new file mode 100644
index 000..0045f63
--- /dev/null
+++ b/Documentation/fpga/fpga-header.txt
@@ -0,0 +1,103 @@
+Open source FPGA image headers
+
+Alan Tull 2017
+
+CONTENTS
+- Introduction
+- Format
+- Example
+- Using mkimage
+
+Introduction
+
+
+Open source FPGA image headers have been added to allow FPGA image specific
+information to be included with the image.  The header format is a simplified
+form of u-boot FIT images and can be expanded as real use cases are raised.
+As all the FPGA kernel frameworks are intended to be vendor agnostic, so also
+is the header.  As libfdt's licensing is permissive, this header is also
+intended to be useful for OS's other than Linux such that the FPGA image need
+not be rebuilt for use under another OS.
+
+Format
+==
+
+The format of the header is a reduced FIT-like header, so it can be built
+using mkimage.  The header is a FDT followed by two optional binary data
+sections: a Device Tree overlay and a raw FPGA image.  When the image is
+applied to a FPGA region, first the FPGA is programmed (if the raw image is
+present) and then the DT overlay, if present, is applied.  If the DT overlay
+is eliminated, this header format may be used on systems running without
+Device Tree.
+
+Example
+===
+
+/dts-v1/;
+
+/ {
+   description = "Program FPGA image and apply DT overlay";
+   #address-cells = <1>;
+
+   images {
+   fdt@1 {
+   description = "Flattened Device Tree blob";
+   type = "flat_dt";
+   data = /incbin/("/some/path/persona0.dtb");
+   };
+   fpga@1 {
+   description = "FPGA image";
+   type = "fpga";
+   data = /incbin/("/some/path/persona0.rbf");
+   partial-fpga-config;
+   region-unfreeze-timeout-us = <4>;
+   region-freeze-timeout-us = <4>;
+   config-complete-timeout-us = <100>;
+   };
+   };
+};
+
+This format is compatible with FIT, but leaves out a few things that were not
+needed.  The compression property is left out (assuming none).  The
+'configurations' section is left out since there is only one possible
+configuration presented here.  If we see an actual use case for
+configurations in the future, we could expand to support it seamlessly.
+
+Any FPGA image info must be included in the FPGA image section.  FPGA image
+info properties are defined in the fpga-region.txt Device Tree binding
+document at ../devicetree/bindings/fpga/fpga-region.txt.
+
+The FPGA image section has to come last.
+
+Using mkimage
+=
+
+If the above example is named persona0.its, it can be compiled by using
+mkimage as follows.  The output file is persona0.fit.
+
+ mkimage -f persona0.its persona0.fit
+
+Applying the image
+==
+
+A sysfs attribute 'firmware_name' is added for each FPGA region.
+
+To apply the image:
+
+  echo persona.fit > /sys/class/fpga_region/region0/firmware_name
+
+To free up the region for reprogramming:
+
+  echo > /sys/class/fpga_region/region0/firmware_name
+
+FPGA Region API Function
+
+
+An API for FPGA region has been added:
+
+  int fpga_region_fdt_image_apply(struct fpga_region *region)
+
+This function will parse the header of a FPGA image and do the programming
+and apply the DT overlay.  The FPGA image is presented as a scatter gather
+table, a contiguous buffer, or name of a firmware file in the region's FPGA
+image info (region->info).
-- 
2.7.4



[RFC 1/5] doc: fpga: add document for the fdt FPGA header

2017-07-24 Thread Alan Tull
Add a document for the open source fdt FPGA header.

Signed-off-by: Alan Tull 
---
 Documentation/fpga/fpga-header.txt | 103 +
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/fpga/fpga-header.txt

diff --git a/Documentation/fpga/fpga-header.txt 
b/Documentation/fpga/fpga-header.txt
new file mode 100644
index 000..0045f63
--- /dev/null
+++ b/Documentation/fpga/fpga-header.txt
@@ -0,0 +1,103 @@
+Open source FPGA image headers
+
+Alan Tull 2017
+
+CONTENTS
+- Introduction
+- Format
+- Example
+- Using mkimage
+
+Introduction
+
+
+Open source FPGA image headers have been added to allow FPGA image specific
+information to be included with the image.  The header format is a simplified
+form of u-boot FIT images and can be expanded as real use cases are raised.
+As all the FPGA kernel frameworks are intended to be vendor agnostic, so also
+is the header.  As libfdt's licensing is permissive, this header is also
+intended to be useful for OS's other than Linux such that the FPGA image need
+not be rebuilt for use under another OS.
+
+Format
+==
+
+The format of the header is a reduced FIT-like header, so it can be built
+using mkimage.  The header is a FDT followed by two optional binary data
+sections: a Device Tree overlay and a raw FPGA image.  When the image is
+applied to a FPGA region, first the FPGA is programmed (if the raw image is
+present) and then the DT overlay, if present, is applied.  If the DT overlay
+is eliminated, this header format may be used on systems running without
+Device Tree.
+
+Example
+===
+
+/dts-v1/;
+
+/ {
+   description = "Program FPGA image and apply DT overlay";
+   #address-cells = <1>;
+
+   images {
+   fdt@1 {
+   description = "Flattened Device Tree blob";
+   type = "flat_dt";
+   data = /incbin/("/some/path/persona0.dtb");
+   };
+   fpga@1 {
+   description = "FPGA image";
+   type = "fpga";
+   data = /incbin/("/some/path/persona0.rbf");
+   partial-fpga-config;
+   region-unfreeze-timeout-us = <4>;
+   region-freeze-timeout-us = <4>;
+   config-complete-timeout-us = <100>;
+   };
+   };
+};
+
+This format is compatible with FIT, but leaves out a few things that were not
+needed.  The compression property is left out (assuming none).  The
+'configurations' section is left out since there is only one possible
+configuration presented here.  If we see an actual use case for
+configurations in the future, we could expand to support it seamlessly.
+
+Any FPGA image info must be included in the FPGA image section.  FPGA image
+info properties are defined in the fpga-region.txt Device Tree binding
+document at ../devicetree/bindings/fpga/fpga-region.txt.
+
+The FPGA image section has to come last.
+
+Using mkimage
+=
+
+If the above example is named persona0.its, it can be compiled by using
+mkimage as follows.  The output file is persona0.fit.
+
+ mkimage -f persona0.its persona0.fit
+
+Applying the image
+==
+
+A sysfs attribute 'firmware_name' is added for each FPGA region.
+
+To apply the image:
+
+  echo persona.fit > /sys/class/fpga_region/region0/firmware_name
+
+To free up the region for reprogramming:
+
+  echo > /sys/class/fpga_region/region0/firmware_name
+
+FPGA Region API Function
+
+
+An API for FPGA region has been added:
+
+  int fpga_region_fdt_image_apply(struct fpga_region *region)
+
+This function will parse the header of a FPGA image and do the programming
+and apply the DT overlay.  The FPGA image is presented as a scatter gather
+table, a contiguous buffer, or name of a firmware file in the region's FPGA
+image info (region->info).
-- 
2.7.4



[RFC 0/5] Open source FPGA image header

2017-07-24 Thread Alan Tull
This patch set adds open source FPGA image headers.  This allows FPGA
FPGA image specific information to be added to the images themselves.
The header format is a simplified form of u-boot FIT images and can be
expanded as real use cases are raised.  As all the FPGA kernel
frameworks are intended to be vendor agnostic, so also is the header.
As libfdt's licensing is permissive, this header is also intended to
be useful for OS's other than Linux.

In February, there was a conversation on the linux-fpga mailing list
where Moritz and Jason suggested headers, so with their permission
I'll be happy to add 'Suggested-by'.

An API function and a sysfs interface are added for applying FPGA
images to regions.

Patches 1-2 are documentation

Patches 3-4 are small API changes and could be rolled into my "non-DT
  support for FPGA regions" patchset.

Patch 5 is the bulk of it.

todo: I've been working on scatter gather table support for this.
It's not done yet, so I pulled it out for now.

This patch applies on top of my "non-DT support for FPGA regions" v3
patchset.

Alan Tull

Alan Tull (5):
  doc: fpga: add document for the fdt FPGA header
  doc: fpga: add sysfs document for fpga region
  fpga: add dev to fpga_image_info
  fpga-region: new function fpga_region_free
  fpga-region support for fdt headers on fpga images

 Documentation/ABI/testing/sysfs-class-fpga-region |   7 +
 Documentation/fpga/fpga-header.txt| 103 +
 drivers/fpga/Kconfig  |   7 +
 drivers/fpga/fpga-mgr.c   |  14 +-
 drivers/fpga/fpga-region.c| 460 ++
 drivers/fpga/of-fpga-region.c |  16 +-
 include/linux/fpga/fpga-mgr.h |  13 +-
 include/linux/fpga/fpga-region.h  |   3 +
 8 files changed, 612 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-region
 create mode 100644 Documentation/fpga/fpga-header.txt

-- 
2.7.4



[RFC 0/5] Open source FPGA image header

2017-07-24 Thread Alan Tull
This patch set adds open source FPGA image headers.  This allows FPGA
FPGA image specific information to be added to the images themselves.
The header format is a simplified form of u-boot FIT images and can be
expanded as real use cases are raised.  As all the FPGA kernel
frameworks are intended to be vendor agnostic, so also is the header.
As libfdt's licensing is permissive, this header is also intended to
be useful for OS's other than Linux.

In February, there was a conversation on the linux-fpga mailing list
where Moritz and Jason suggested headers, so with their permission
I'll be happy to add 'Suggested-by'.

An API function and a sysfs interface are added for applying FPGA
images to regions.

Patches 1-2 are documentation

Patches 3-4 are small API changes and could be rolled into my "non-DT
  support for FPGA regions" patchset.

Patch 5 is the bulk of it.

todo: I've been working on scatter gather table support for this.
It's not done yet, so I pulled it out for now.

This patch applies on top of my "non-DT support for FPGA regions" v3
patchset.

Alan Tull

Alan Tull (5):
  doc: fpga: add document for the fdt FPGA header
  doc: fpga: add sysfs document for fpga region
  fpga: add dev to fpga_image_info
  fpga-region: new function fpga_region_free
  fpga-region support for fdt headers on fpga images

 Documentation/ABI/testing/sysfs-class-fpga-region |   7 +
 Documentation/fpga/fpga-header.txt| 103 +
 drivers/fpga/Kconfig  |   7 +
 drivers/fpga/fpga-mgr.c   |  14 +-
 drivers/fpga/fpga-region.c| 460 ++
 drivers/fpga/of-fpga-region.c |  16 +-
 include/linux/fpga/fpga-mgr.h |  13 +-
 include/linux/fpga/fpga-region.h  |   3 +
 8 files changed, 612 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-region
 create mode 100644 Documentation/fpga/fpga-header.txt

-- 
2.7.4



Re: [PATCH v1 07/13] xen/pvcalls: implement accept command

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send PVCALLS_ACCEPT to the backend. Allocate a new active socket. Make
> sure that only one accept command is executed at any given time by
> setting PVCALLS_FLAG_ACCEPT_INFLIGHT and waiting on the
> inflight_accept_req waitqueue.
> 
> sock->sk->sk_send_head is not used for ip sockets: reuse the field to
> store a pointer to the struct sock_mapping corresponding to the socket.
> 
> Convert the new struct socket pointer into an uint64_t and use it as id
> for the new socket to pass to the backend.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 79 
> +
>  drivers/xen/pvcalls-front.h |  3 ++
>  2 files changed, 82 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 80fd5fb..f3a04a2 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -410,6 +410,85 @@ int pvcalls_front_listen(struct socket *sock, int 
> backlog)
>   return ret;
>  }
>  
> +int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int 
> flags)
> +{
> + struct pvcalls_bedata *bedata;
> + struct sock_mapping *map;
> + struct sock_mapping *map2 = NULL;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret, evtchn;
> +
> + if (!pvcalls_front_dev)
> + return -ENOTCONN;
> + bedata = dev_get_drvdata(_front_dev->dev);
> +
> + map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
> + if (!map)
> + return -ENOTSOCK;
> +
> + if (map->passive.status != PVCALLS_STATUS_LISTEN)
> + return -EINVAL;
> +
> + /*
> +  * Backend only supports 1 inflight accept request, will return
> +  * errors for the others
> +  */
> + if (test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
> +  (void *)>passive.flags)) {
> + if (wait_event_interruptible(map->passive.inflight_accept_req,
> + !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
> +   (void *)>passive.flags))
> + != 0)
> + return -EINTR;
> + }
> +
> +
> + newsock->sk = kzalloc(sizeof(*newsock->sk), GFP_KERNEL);
> + if (newsock->sk == NULL)
> + return -ENOMEM;
> +
> + spin_lock(>pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
> + BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);

BUG_ON()?

> + if (RING_FULL(>ring) ||
> + READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
> + spin_unlock(>pvcallss_lock);
> + return -EAGAIN;

Leaking newsock->sk?


Juergen

> + }
> +
> + map2 = create_active();
> +
> + req = RING_GET_REQUEST(>ring, req_id);
> + req->req_id = req_id;
> + req->cmd = PVCALLS_ACCEPT;
> + req->u.accept.id = (uint64_t) sock;
> + req->u.accept.ref = map2->active.ref;
> + req->u.accept.id_new = (uint64_t) newsock;
> + req->u.accept.evtchn = evtchn;
> +
> + list_add_tail(>list, >socket_mappings);
> + WRITE_ONCE(newsock->sk->sk_send_head, (void *)map2);
> + map2->sock = newsock;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
> + spin_unlock(>pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + wait_event(bedata->inflight_req,
> +READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
> +
> + clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)>passive.flags);
> + wake_up(>passive.inflight_accept_req);
> +
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> + return ret;
> +}
> +
>  static const struct xenbus_device_id pvcalls_front_ids[] = {
>   { "pvcalls" },
>   { "" }
> diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
> index aa8fe10..ab4f1da 100644
> --- a/drivers/xen/pvcalls-front.h
> +++ b/drivers/xen/pvcalls-front.h
> @@ -10,5 +10,8 @@ int pvcalls_front_bind(struct socket *sock,
>  struct sockaddr *addr,
>  int addr_len);
>  int pvcalls_front_listen(struct socket *sock, int backlog);
> +int pvcalls_front_accept(struct socket *sock,
> +  struct socket *newsock,
> +  int flags);
>  
>  #endif
> 



Re: [PATCH v1 07/13] xen/pvcalls: implement accept command

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send PVCALLS_ACCEPT to the backend. Allocate a new active socket. Make
> sure that only one accept command is executed at any given time by
> setting PVCALLS_FLAG_ACCEPT_INFLIGHT and waiting on the
> inflight_accept_req waitqueue.
> 
> sock->sk->sk_send_head is not used for ip sockets: reuse the field to
> store a pointer to the struct sock_mapping corresponding to the socket.
> 
> Convert the new struct socket pointer into an uint64_t and use it as id
> for the new socket to pass to the backend.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 79 
> +
>  drivers/xen/pvcalls-front.h |  3 ++
>  2 files changed, 82 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 80fd5fb..f3a04a2 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -410,6 +410,85 @@ int pvcalls_front_listen(struct socket *sock, int 
> backlog)
>   return ret;
>  }
>  
> +int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int 
> flags)
> +{
> + struct pvcalls_bedata *bedata;
> + struct sock_mapping *map;
> + struct sock_mapping *map2 = NULL;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret, evtchn;
> +
> + if (!pvcalls_front_dev)
> + return -ENOTCONN;
> + bedata = dev_get_drvdata(_front_dev->dev);
> +
> + map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
> + if (!map)
> + return -ENOTSOCK;
> +
> + if (map->passive.status != PVCALLS_STATUS_LISTEN)
> + return -EINVAL;
> +
> + /*
> +  * Backend only supports 1 inflight accept request, will return
> +  * errors for the others
> +  */
> + if (test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
> +  (void *)>passive.flags)) {
> + if (wait_event_interruptible(map->passive.inflight_accept_req,
> + !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
> +   (void *)>passive.flags))
> + != 0)
> + return -EINTR;
> + }
> +
> +
> + newsock->sk = kzalloc(sizeof(*newsock->sk), GFP_KERNEL);
> + if (newsock->sk == NULL)
> + return -ENOMEM;
> +
> + spin_lock(>pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
> + BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);

BUG_ON()?

> + if (RING_FULL(>ring) ||
> + READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
> + spin_unlock(>pvcallss_lock);
> + return -EAGAIN;

Leaking newsock->sk?


Juergen

> + }
> +
> + map2 = create_active();
> +
> + req = RING_GET_REQUEST(>ring, req_id);
> + req->req_id = req_id;
> + req->cmd = PVCALLS_ACCEPT;
> + req->u.accept.id = (uint64_t) sock;
> + req->u.accept.ref = map2->active.ref;
> + req->u.accept.id_new = (uint64_t) newsock;
> + req->u.accept.evtchn = evtchn;
> +
> + list_add_tail(>list, >socket_mappings);
> + WRITE_ONCE(newsock->sk->sk_send_head, (void *)map2);
> + map2->sock = newsock;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
> + spin_unlock(>pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + wait_event(bedata->inflight_req,
> +READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
> +
> + clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)>passive.flags);
> + wake_up(>passive.inflight_accept_req);
> +
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> + return ret;
> +}
> +
>  static const struct xenbus_device_id pvcalls_front_ids[] = {
>   { "pvcalls" },
>   { "" }
> diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
> index aa8fe10..ab4f1da 100644
> --- a/drivers/xen/pvcalls-front.h
> +++ b/drivers/xen/pvcalls-front.h
> @@ -10,5 +10,8 @@ int pvcalls_front_bind(struct socket *sock,
>  struct sockaddr *addr,
>  int addr_len);
>  int pvcalls_front_listen(struct socket *sock, int backlog);
> +int pvcalls_front_accept(struct socket *sock,
> +  struct socket *newsock,
> +  int flags);
>  
>  #endif
> 



Re: [PATCH] HID: rmi: Make sure the HID device is opened on resume

2017-07-24 Thread Lyude Paul
Yeah I noticed that, sorry if my response wasn't very clear! Should
probably wait to have my morning coffee before responding to these
messages :P

On Mon, 2017-07-24 at 21:28 +0200, Jiri Kosina wrote:
> On Mon, 24 Jul 2017, Lyude Paul wrote:
> 
> > > > So, call hid_hw_open() in rmi_post_resume() so we make sure
> > > > that
> > > > the
> > > > device is alive before we try talking to it.
> > > > 
> > > > This fixes RMI device suspend/resume over HID.
> > > > -   int ret;
> > > > +   int ret = 0;
> > > 
> > > What's the point?
> > 
> > So that we can use the same out: label at the end of the function
> > that
> > calls hid_hw_close() to return success. This being said though I
> > just
> > realized that setting ret will initialize it to 0 anyway, so I
> > guess
> > this can be dropped
> 
> Andy's point was that hid_hw_open() is obviously re-initializing the
> ret 
> before its first use as a return value, so there is no need to
> initialize 
> it at a declaration time.
> 


Re: [PATCH] HID: rmi: Make sure the HID device is opened on resume

2017-07-24 Thread Lyude Paul
Yeah I noticed that, sorry if my response wasn't very clear! Should
probably wait to have my morning coffee before responding to these
messages :P

On Mon, 2017-07-24 at 21:28 +0200, Jiri Kosina wrote:
> On Mon, 24 Jul 2017, Lyude Paul wrote:
> 
> > > > So, call hid_hw_open() in rmi_post_resume() so we make sure
> > > > that
> > > > the
> > > > device is alive before we try talking to it.
> > > > 
> > > > This fixes RMI device suspend/resume over HID.
> > > > -   int ret;
> > > > +   int ret = 0;
> > > 
> > > What's the point?
> > 
> > So that we can use the same out: label at the end of the function
> > that
> > calls hid_hw_close() to return success. This being said though I
> > just
> > realized that setting ret will initialize it to 0 anyway, so I
> > guess
> > this can be dropped
> 
> Andy's point was that hid_hw_open() is obviously re-initializing the
> ret 
> before its first use as a return value, so there is no need to
> initialize 
> it at a declaration time.
> 


Re: [PATCH v1 06/13] xen/pvcalls: implement listen command

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send PVCALLS_LISTEN to the backend.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 49 
> +
>  drivers/xen/pvcalls-front.h |  1 +
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 71619bc..80fd5fb 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -361,6 +361,55 @@ int pvcalls_front_bind(struct socket *sock, struct 
> sockaddr *addr, int addr_len)
>   return 0;
>  }
>  
> +int pvcalls_front_listen(struct socket *sock, int backlog)
> +{
> + struct pvcalls_bedata *bedata;
> + struct sock_mapping *map;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret;
> +
> + if (!pvcalls_front_dev)
> + return -ENOTCONN;
> + bedata = dev_get_drvdata(_front_dev->dev);
> +
> + map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
> + if (!map)
> + return -ENOTSOCK;
> +
> + if (map->passive.status != PVCALLS_STATUS_BIND)
> + return -EOPNOTSUPP;
> +
> + spin_lock(>pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
> + BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);

BUG_ON() again!


Juergen

> + if (RING_FULL(>ring) ||
> + bedata->rsp[req_id].req_id != PVCALLS_INVALID_ID) {
> + spin_unlock(>pvcallss_lock);
> + return -EAGAIN;
> + }
> + req = RING_GET_REQUEST(>ring, req_id);
> + req->req_id = req_id;
> + req->cmd = PVCALLS_LISTEN;
> + req->u.listen.id = (uint64_t) sock;
> + req->u.listen.backlog = backlog;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
> + spin_unlock(>pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + wait_event(bedata->inflight_req,
> +READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
> +
> + map->passive.status = PVCALLS_STATUS_LISTEN;
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> + return ret;
> +}
> +
>  static const struct xenbus_device_id pvcalls_front_ids[] = {
>   { "pvcalls" },
>   { "" }
> diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
> index 8b0a274..aa8fe10 100644
> --- a/drivers/xen/pvcalls-front.h
> +++ b/drivers/xen/pvcalls-front.h
> @@ -9,5 +9,6 @@ int pvcalls_front_connect(struct socket *sock, struct 
> sockaddr *addr,
>  int pvcalls_front_bind(struct socket *sock,
>  struct sockaddr *addr,
>  int addr_len);
> +int pvcalls_front_listen(struct socket *sock, int backlog);
>  
>  #endif
> 



Re: [PATCH v1 06/13] xen/pvcalls: implement listen command

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send PVCALLS_LISTEN to the backend.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 49 
> +
>  drivers/xen/pvcalls-front.h |  1 +
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 71619bc..80fd5fb 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -361,6 +361,55 @@ int pvcalls_front_bind(struct socket *sock, struct 
> sockaddr *addr, int addr_len)
>   return 0;
>  }
>  
> +int pvcalls_front_listen(struct socket *sock, int backlog)
> +{
> + struct pvcalls_bedata *bedata;
> + struct sock_mapping *map;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret;
> +
> + if (!pvcalls_front_dev)
> + return -ENOTCONN;
> + bedata = dev_get_drvdata(_front_dev->dev);
> +
> + map = (struct sock_mapping *) READ_ONCE(sock->sk->sk_send_head);
> + if (!map)
> + return -ENOTSOCK;
> +
> + if (map->passive.status != PVCALLS_STATUS_BIND)
> + return -EOPNOTSUPP;
> +
> + spin_lock(>pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
> + BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);

BUG_ON() again!


Juergen

> + if (RING_FULL(>ring) ||
> + bedata->rsp[req_id].req_id != PVCALLS_INVALID_ID) {
> + spin_unlock(>pvcallss_lock);
> + return -EAGAIN;
> + }
> + req = RING_GET_REQUEST(>ring, req_id);
> + req->req_id = req_id;
> + req->cmd = PVCALLS_LISTEN;
> + req->u.listen.id = (uint64_t) sock;
> + req->u.listen.backlog = backlog;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
> + spin_unlock(>pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + wait_event(bedata->inflight_req,
> +READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
> +
> + map->passive.status = PVCALLS_STATUS_LISTEN;
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> + return ret;
> +}
> +
>  static const struct xenbus_device_id pvcalls_front_ids[] = {
>   { "pvcalls" },
>   { "" }
> diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
> index 8b0a274..aa8fe10 100644
> --- a/drivers/xen/pvcalls-front.h
> +++ b/drivers/xen/pvcalls-front.h
> @@ -9,5 +9,6 @@ int pvcalls_front_connect(struct socket *sock, struct 
> sockaddr *addr,
>  int pvcalls_front_bind(struct socket *sock,
>  struct sockaddr *addr,
>  int addr_len);
> +int pvcalls_front_listen(struct socket *sock, int backlog);
>  
>  #endif
> 



Re: [PATCH v1 05/13] xen/pvcalls: implement bind command

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send PVCALLS_BIND to the backend. Introduce a new structure, part of
> struct sock_mapping, to store information specific to passive sockets.
> 
> Introduce a status field to keep track of the status of the passive
> socket.
> 
> Introduce a waitqueue for the "accept" command (see the accept command
> implementation): it is used to allow only one outstanding accept
> command at any given time and to implement polling on the passive
> socket. Introduce a flags field to keep track of in-flight accept and
> poll commands.
> 
> sock->sk->sk_send_head is not used for ip sockets: reuse the field to
> store a pointer to the struct sock_mapping corresponding to the socket.
> 
> Convert the struct socket pointer into an uint64_t and use it as id for
> the socket to pass to the backend.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 74 
> +
>  drivers/xen/pvcalls-front.h |  3 ++
>  2 files changed, 77 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 0d305e0..71619bc 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -57,6 +57,23 @@ struct sock_mapping {
>  
>   wait_queue_head_t inflight_conn_req;
>   } active;
> + struct {
> + /* Socket status */
> +#define PVCALLS_STATUS_UNINITALIZED  0
> +#define PVCALLS_STATUS_BIND  1
> +#define PVCALLS_STATUS_LISTEN2
> + uint8_t status;
> + /*
> +  * Internal state-machine flags.
> +  * Only one accept operation can be inflight for a socket.
> +  * Only one poll operation can be inflight for a given socket.
> +  */
> +#define PVCALLS_FLAG_ACCEPT_INFLIGHT 0
> +#define PVCALLS_FLAG_POLL_INFLIGHT   1
> +#define PVCALLS_FLAG_POLL_RET2
> + uint8_t flags;
> + wait_queue_head_t inflight_accept_req;
> + } passive;
>   };
>  };
>  
> @@ -287,6 +304,63 @@ int pvcalls_front_connect(struct socket *sock, struct 
> sockaddr *addr,
>   return ret;
>  }
>  
> +int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int 
> addr_len)
> +{
> + struct pvcalls_bedata *bedata;
> + struct sock_mapping *map = NULL;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret;
> +
> + if (!pvcalls_front_dev)
> + return -ENOTCONN;
> + if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM)
> + return -ENOTSUPP;
> + bedata = dev_get_drvdata(_front_dev->dev);
> +
> + map = kzalloc(sizeof(*map), GFP_KERNEL);
> + if (map == NULL)
> + return -ENOMEM;
> +
> + spin_lock(>pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
> + BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);

BUG_ON() isn't appropriate here. The system can still be used.


Juergen

> + if (RING_FULL(>ring) ||
> + READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
> + kfree(map);
> + spin_unlock(>pvcallss_lock);
> + return -EAGAIN;
> + }
> + req = RING_GET_REQUEST(>ring, req_id);
> + req->req_id = req_id;
> + map->sock = sock;
> + req->cmd = PVCALLS_BIND;
> + req->u.bind.id = (uint64_t) sock;
> + memcpy(req->u.bind.addr, addr, sizeof(*addr));
> + req->u.bind.len = addr_len;
> +
> + init_waitqueue_head(>passive.inflight_accept_req);
> +
> + list_add_tail(>list, >socketpass_mappings);
> + WRITE_ONCE(sock->sk->sk_send_head, (void *)map);
> + map->active_socket = false;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
> + spin_unlock(>pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + wait_event(bedata->inflight_req,
> +READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
> +
> + map->passive.status = PVCALLS_STATUS_BIND;
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> + return 0;
> +}
> +
>  static const struct xenbus_device_id pvcalls_front_ids[] = {
>   { "pvcalls" },
>   { "" }
> diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
> index 63b0417..8b0a274 100644
> --- a/drivers/xen/pvcalls-front.h
> +++ b/drivers/xen/pvcalls-front.h
> @@ -6,5 +6,8 @@
>  int pvcalls_front_socket(struct socket *sock);
>  int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr,
> int addr_len, int flags);
> +int pvcalls_front_bind(struct socket *sock,
> +struct sockaddr *addr,
> +

Re: [PATCH v1 05/13] xen/pvcalls: implement bind command

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send PVCALLS_BIND to the backend. Introduce a new structure, part of
> struct sock_mapping, to store information specific to passive sockets.
> 
> Introduce a status field to keep track of the status of the passive
> socket.
> 
> Introduce a waitqueue for the "accept" command (see the accept command
> implementation): it is used to allow only one outstanding accept
> command at any given time and to implement polling on the passive
> socket. Introduce a flags field to keep track of in-flight accept and
> poll commands.
> 
> sock->sk->sk_send_head is not used for ip sockets: reuse the field to
> store a pointer to the struct sock_mapping corresponding to the socket.
> 
> Convert the struct socket pointer into an uint64_t and use it as id for
> the socket to pass to the backend.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 74 
> +
>  drivers/xen/pvcalls-front.h |  3 ++
>  2 files changed, 77 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 0d305e0..71619bc 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -57,6 +57,23 @@ struct sock_mapping {
>  
>   wait_queue_head_t inflight_conn_req;
>   } active;
> + struct {
> + /* Socket status */
> +#define PVCALLS_STATUS_UNINITALIZED  0
> +#define PVCALLS_STATUS_BIND  1
> +#define PVCALLS_STATUS_LISTEN2
> + uint8_t status;
> + /*
> +  * Internal state-machine flags.
> +  * Only one accept operation can be inflight for a socket.
> +  * Only one poll operation can be inflight for a given socket.
> +  */
> +#define PVCALLS_FLAG_ACCEPT_INFLIGHT 0
> +#define PVCALLS_FLAG_POLL_INFLIGHT   1
> +#define PVCALLS_FLAG_POLL_RET2
> + uint8_t flags;
> + wait_queue_head_t inflight_accept_req;
> + } passive;
>   };
>  };
>  
> @@ -287,6 +304,63 @@ int pvcalls_front_connect(struct socket *sock, struct 
> sockaddr *addr,
>   return ret;
>  }
>  
> +int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int 
> addr_len)
> +{
> + struct pvcalls_bedata *bedata;
> + struct sock_mapping *map = NULL;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret;
> +
> + if (!pvcalls_front_dev)
> + return -ENOTCONN;
> + if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM)
> + return -ENOTSUPP;
> + bedata = dev_get_drvdata(_front_dev->dev);
> +
> + map = kzalloc(sizeof(*map), GFP_KERNEL);
> + if (map == NULL)
> + return -ENOMEM;
> +
> + spin_lock(>pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
> + BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);

BUG_ON() isn't appropriate here. The system can still be used.


Juergen

> + if (RING_FULL(>ring) ||
> + READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
> + kfree(map);
> + spin_unlock(>pvcallss_lock);
> + return -EAGAIN;
> + }
> + req = RING_GET_REQUEST(>ring, req_id);
> + req->req_id = req_id;
> + map->sock = sock;
> + req->cmd = PVCALLS_BIND;
> + req->u.bind.id = (uint64_t) sock;
> + memcpy(req->u.bind.addr, addr, sizeof(*addr));
> + req->u.bind.len = addr_len;
> +
> + init_waitqueue_head(>passive.inflight_accept_req);
> +
> + list_add_tail(>list, >socketpass_mappings);
> + WRITE_ONCE(sock->sk->sk_send_head, (void *)map);
> + map->active_socket = false;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
> + spin_unlock(>pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + wait_event(bedata->inflight_req,
> +READ_ONCE(bedata->rsp[req_id].req_id) == req_id);
> +
> + map->passive.status = PVCALLS_STATUS_BIND;
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> + return 0;
> +}
> +
>  static const struct xenbus_device_id pvcalls_front_ids[] = {
>   { "pvcalls" },
>   { "" }
> diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
> index 63b0417..8b0a274 100644
> --- a/drivers/xen/pvcalls-front.h
> +++ b/drivers/xen/pvcalls-front.h
> @@ -6,5 +6,8 @@
>  int pvcalls_front_socket(struct socket *sock);
>  int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr,
> int addr_len, int flags);
> +int pvcalls_front_bind(struct socket *sock,
> +struct sockaddr *addr,
> +int addr_len);
>  
>  

Re: [PATCH v1 04/13] xen/pvcalls: implement connect command

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send PVCALLS_CONNECT to the backend. Allocate a new ring and evtchn for
> the active socket.
> 
> Introduce a data structure to keep track of sockets. Introduce a
> waitqueue to allow the frontend to wait on data coming from the backend
> on the active socket (recvmsg command).
> 
> Two mutexes (one of reads and one for writes) will be used to protect
> the active socket in and out rings from concurrent accesses.
> 
> sock->sk->sk_send_head is not used for ip sockets: reuse the field to
> store a pointer to the struct sock_mapping corresponding to the socket.
> This way, we can easily get the struct sock_mapping from the struct
> socket.
> 
> Convert the struct socket pointer into an uint64_t and use it as id for
> the new socket to pass to the backend.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 153 
> 
>  drivers/xen/pvcalls-front.h |   2 +
>  2 files changed, 155 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 7933c73..0d305e0 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -13,6 +13,8 @@
>   */
>  
>  #include 
> +#include 
> +#include 
>  
>  #include 
>  #include 
> @@ -20,6 +22,8 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  #define PVCALLS_INVALID_ID (UINT_MAX)
>  #define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
>  #define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
> @@ -38,6 +42,24 @@ struct pvcalls_bedata {
>  };
>  struct xenbus_device *pvcalls_front_dev;
>  
> +struct sock_mapping {
> + bool active_socket;
> + struct list_head list;
> + struct socket *sock;
> + union {
> + struct {
> + int irq;
> + grant_ref_t ref;
> + struct pvcalls_data_intf *ring;
> + struct pvcalls_data data;
> + struct mutex in_mutex;
> + struct mutex out_mutex;
> +
> + wait_queue_head_t inflight_conn_req;
> + } active;
> + };
> +};
> +
>  static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
>  {
>   struct xenbus_device *dev = dev_id;
> @@ -80,6 +102,18 @@ static irqreturn_t pvcalls_front_event_handler(int irq, 
> void *dev_id)
>   return IRQ_HANDLED;
>  }
>  
> +static irqreturn_t pvcalls_front_conn_handler(int irq, void *sock_map)
> +{
> + struct sock_mapping *map = sock_map;
> +
> + if (map == NULL)
> + return IRQ_HANDLED;
> +
> + wake_up_interruptible(>active.inflight_conn_req);
> +
> + return IRQ_HANDLED;
> +}
> +
>  int pvcalls_front_socket(struct socket *sock)
>  {
>   struct pvcalls_bedata *bedata;
> @@ -134,6 +168,125 @@ int pvcalls_front_socket(struct socket *sock)
>   return ret;
>  }
>  
> +static struct sock_mapping *create_active(int *evtchn)
> +{
> + struct sock_mapping *map = NULL;
> + void *bytes;
> + int ret, irq = -1, i;
> +
> + map = kzalloc(sizeof(*map), GFP_KERNEL);
> + if (map == NULL)
> + return NULL;
> +
> + init_waitqueue_head(>active.inflight_conn_req);
> +
> + map->active.ring = (struct pvcalls_data_intf *)
> + __get_free_page(GFP_KERNEL | __GFP_ZERO);
> + if (map->active.ring == NULL)
> + goto out_error;
> + memset(map->active.ring, 0, XEN_PAGE_SIZE);
> + map->active.ring->ring_order = RING_ORDER;
> + bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
> + map->active.ring->ring_order);
> + if (bytes == NULL)
> + goto out_error;
> + for (i = 0; i < (1 << map->active.ring->ring_order); i++)
> + map->active.ring->ref[i] = gnttab_grant_foreign_access(
> + pvcalls_front_dev->otherend_id,
> + pfn_to_gfn(virt_to_pfn(bytes) + i), 0);
> +
> + map->active.ref = gnttab_grant_foreign_access(
> + pvcalls_front_dev->otherend_id,
> + pfn_to_gfn(virt_to_pfn((void *)map->active.ring)), 0);
> +
> + ret = xenbus_alloc_evtchn(pvcalls_front_dev, evtchn);
> + if (ret)
> + goto out_error;

You are leaking bytes here in case of error.

> + map->active.data.in = bytes;
> + map->active.data.out = bytes +
> + XEN_FLEX_RING_SIZE(map->active.ring->ring_order);
> + irq = bind_evtchn_to_irqhandler(*evtchn, pvcalls_front_conn_handler,
> + 0, "pvcalls-frontend", map);
> + if (irq < 0)
> + goto out_error;
> +
> + map->active.irq = irq;
> + map->active_socket = true;
> + mutex_init(>active.in_mutex);
> + mutex_init(>active.out_mutex);
> +
> + return map;
> +
> +out_error:
> + if (irq >= 0)
> + unbind_from_irqhandler(irq, 

Re: [PATCH v1 04/13] xen/pvcalls: implement connect command

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send PVCALLS_CONNECT to the backend. Allocate a new ring and evtchn for
> the active socket.
> 
> Introduce a data structure to keep track of sockets. Introduce a
> waitqueue to allow the frontend to wait on data coming from the backend
> on the active socket (recvmsg command).
> 
> Two mutexes (one of reads and one for writes) will be used to protect
> the active socket in and out rings from concurrent accesses.
> 
> sock->sk->sk_send_head is not used for ip sockets: reuse the field to
> store a pointer to the struct sock_mapping corresponding to the socket.
> This way, we can easily get the struct sock_mapping from the struct
> socket.
> 
> Convert the struct socket pointer into an uint64_t and use it as id for
> the new socket to pass to the backend.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 153 
> 
>  drivers/xen/pvcalls-front.h |   2 +
>  2 files changed, 155 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 7933c73..0d305e0 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -13,6 +13,8 @@
>   */
>  
>  #include 
> +#include 
> +#include 
>  
>  #include 
>  #include 
> @@ -20,6 +22,8 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  #define PVCALLS_INVALID_ID (UINT_MAX)
>  #define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
>  #define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
> @@ -38,6 +42,24 @@ struct pvcalls_bedata {
>  };
>  struct xenbus_device *pvcalls_front_dev;
>  
> +struct sock_mapping {
> + bool active_socket;
> + struct list_head list;
> + struct socket *sock;
> + union {
> + struct {
> + int irq;
> + grant_ref_t ref;
> + struct pvcalls_data_intf *ring;
> + struct pvcalls_data data;
> + struct mutex in_mutex;
> + struct mutex out_mutex;
> +
> + wait_queue_head_t inflight_conn_req;
> + } active;
> + };
> +};
> +
>  static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
>  {
>   struct xenbus_device *dev = dev_id;
> @@ -80,6 +102,18 @@ static irqreturn_t pvcalls_front_event_handler(int irq, 
> void *dev_id)
>   return IRQ_HANDLED;
>  }
>  
> +static irqreturn_t pvcalls_front_conn_handler(int irq, void *sock_map)
> +{
> + struct sock_mapping *map = sock_map;
> +
> + if (map == NULL)
> + return IRQ_HANDLED;
> +
> + wake_up_interruptible(>active.inflight_conn_req);
> +
> + return IRQ_HANDLED;
> +}
> +
>  int pvcalls_front_socket(struct socket *sock)
>  {
>   struct pvcalls_bedata *bedata;
> @@ -134,6 +168,125 @@ int pvcalls_front_socket(struct socket *sock)
>   return ret;
>  }
>  
> +static struct sock_mapping *create_active(int *evtchn)
> +{
> + struct sock_mapping *map = NULL;
> + void *bytes;
> + int ret, irq = -1, i;
> +
> + map = kzalloc(sizeof(*map), GFP_KERNEL);
> + if (map == NULL)
> + return NULL;
> +
> + init_waitqueue_head(>active.inflight_conn_req);
> +
> + map->active.ring = (struct pvcalls_data_intf *)
> + __get_free_page(GFP_KERNEL | __GFP_ZERO);
> + if (map->active.ring == NULL)
> + goto out_error;
> + memset(map->active.ring, 0, XEN_PAGE_SIZE);
> + map->active.ring->ring_order = RING_ORDER;
> + bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
> + map->active.ring->ring_order);
> + if (bytes == NULL)
> + goto out_error;
> + for (i = 0; i < (1 << map->active.ring->ring_order); i++)
> + map->active.ring->ref[i] = gnttab_grant_foreign_access(
> + pvcalls_front_dev->otherend_id,
> + pfn_to_gfn(virt_to_pfn(bytes) + i), 0);
> +
> + map->active.ref = gnttab_grant_foreign_access(
> + pvcalls_front_dev->otherend_id,
> + pfn_to_gfn(virt_to_pfn((void *)map->active.ring)), 0);
> +
> + ret = xenbus_alloc_evtchn(pvcalls_front_dev, evtchn);
> + if (ret)
> + goto out_error;

You are leaking bytes here in case of error.

> + map->active.data.in = bytes;
> + map->active.data.out = bytes +
> + XEN_FLEX_RING_SIZE(map->active.ring->ring_order);
> + irq = bind_evtchn_to_irqhandler(*evtchn, pvcalls_front_conn_handler,
> + 0, "pvcalls-frontend", map);
> + if (irq < 0)
> + goto out_error;
> +
> + map->active.irq = irq;
> + map->active_socket = true;
> + mutex_init(>active.in_mutex);
> + mutex_init(>active.out_mutex);
> +
> + return map;
> +
> +out_error:
> + if (irq >= 0)
> + unbind_from_irqhandler(irq, map);
> + else if 

[PATCH v2] hwmon: (it87) Reapply probe path chip registers settings after resume

2017-07-24 Thread Maciej S. Szmigiero
After a suspend / resume cycle we possibly need to reapply chip registers
settings that we had set or fixed in a probe path, since they might have
been reset to default values or set incorrectly by a BIOS again.

Tested on a Gigabyte M720-US3 board, which requires routing internal VCCH5V
to in7 (and had it wrong again on resume from S3).

Signed-off-by: Maciej S. Szmigiero 
---
Changes from v1: Move code of common probe / resume steps to new functions
so we don't need to make large parts of probe function conditional on a
newly added 'resume' parameter.

 drivers/hwmon/it87.c | 214 +++
 1 file changed, 163 insertions(+), 51 deletions(-)

diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 4dfc7238313e..b565e29c405c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -497,6 +497,7 @@ static const struct it87_devices it87_devices[] = {
 #define has_vin3_5v(data)  ((data)->features & FEAT_VIN3_5V)
 
 struct it87_sio_data {
+   int sioaddr;
enum chips type;
/* Values read from Super-I/O config space */
u8 revision;
@@ -517,6 +518,7 @@ struct it87_sio_data {
  */
 struct it87_data {
const struct attribute_group *groups[7];
+   int sioaddr;
enum chips type;
u32 features;
u8 peci_mask;
@@ -2389,10 +2391,11 @@ static const struct attribute_group it87_group_auto_pwm 
= {
 };
 
 /* SuperIO detection - will change isa_address if a chip is found */
-static int __init it87_find(int sioaddr, unsigned short *address,
+static int __init it87_find(unsigned short *address,
struct it87_sio_data *sio_data)
 {
int err;
+   int sioaddr = sio_data->sioaddr;
u16 chip_type;
const char *board_vendor, *board_name;
const struct it87_devices *config;
@@ -2828,13 +2831,89 @@ static int __init it87_find(int sioaddr, unsigned short 
*address,
return err;
 }
 
+/*
+ * Some chips seem to have default value 0xff for all limit
+ * registers. For low voltage limits it makes no sense and triggers
+ * alarms, so change to 0 instead. For high temperature limits, it
+ * means -1 degree C, which surprisingly doesn't trigger an alarm,
+ * but is still confusing, so change to 127 degrees C.
+ */
+static void it87_check_limit_regs(struct it87_data *data)
+{
+   int i, reg;
+
+   for (i = 0; i < NUM_VIN_LIMIT; i++) {
+   reg = it87_read_value(data, IT87_REG_VIN_MIN(i));
+   if (reg == 0xff)
+   it87_write_value(data, IT87_REG_VIN_MIN(i), 0);
+   }
+   for (i = 0; i < NUM_TEMP_LIMIT; i++) {
+   reg = it87_read_value(data, IT87_REG_TEMP_HIGH(i));
+   if (reg == 0xff)
+   it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
+   }
+}
+
+/* Check if voltage monitors are reset manually or by some reason */
+static void it87_check_voltage_monitors_reset(struct it87_data *data)
+{
+   int reg;
+
+   reg = it87_read_value(data, IT87_REG_VIN_ENABLE);
+   if ((reg & 0xff) == 0) {
+   /* Enable all voltage monitors */
+   it87_write_value(data, IT87_REG_VIN_ENABLE, 0xff);
+   }
+}
+
+/* Check if tachometers are reset manually or by some reason */
+static void it87_check_tachometers_reset(struct platform_device *pdev)
+{
+   struct it87_sio_data *sio_data = dev_get_platdata(>dev);
+   struct it87_data *data = platform_get_drvdata(pdev);
+   u8 mask, fan_main_ctrl;
+
+   mask = 0x70 & ~(sio_data->skip_fan << 4);
+   fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
+   if ((fan_main_ctrl & mask) == 0) {
+   /* Enable all fan tachometers */
+   fan_main_ctrl |= mask;
+   it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+fan_main_ctrl);
+   }
+}
+
+/* Set tachometers to 16-bit mode if needed */
+static void it87_check_tachometers_16bit_mode(struct platform_device *pdev)
+{
+   struct it87_data *data = platform_get_drvdata(pdev);
+   int reg;
+
+   if (!has_fan16_config(data))
+   return;
+
+   reg = it87_read_value(data, IT87_REG_FAN_16BIT);
+   if (~reg & 0x07 & data->has_fan) {
+   dev_dbg(>dev,
+   "Setting fan1-3 to 16-bit mode\n");
+   it87_write_value(data, IT87_REG_FAN_16BIT,
+reg | 0x07);
+   }
+}
+
+static void it87_start_monitoring(struct it87_data *data)
+{
+   it87_write_value(data, IT87_REG_CONFIG,
+(it87_read_value(data, IT87_REG_CONFIG) & 0x3e)
+| (update_vbat ? 0x41 : 0x01));
+}
+
 /* Called when we have found a new IT87. */
 static void it87_init_device(struct platform_device *pdev)
 {
struct it87_sio_data *sio_data = dev_get_platdata(>dev);
struct it87_data *data = 

[PATCH v2] hwmon: (it87) Reapply probe path chip registers settings after resume

2017-07-24 Thread Maciej S. Szmigiero
After a suspend / resume cycle we possibly need to reapply chip registers
settings that we had set or fixed in a probe path, since they might have
been reset to default values or set incorrectly by a BIOS again.

Tested on a Gigabyte M720-US3 board, which requires routing internal VCCH5V
to in7 (and had it wrong again on resume from S3).

Signed-off-by: Maciej S. Szmigiero 
---
Changes from v1: Move code of common probe / resume steps to new functions
so we don't need to make large parts of probe function conditional on a
newly added 'resume' parameter.

 drivers/hwmon/it87.c | 214 +++
 1 file changed, 163 insertions(+), 51 deletions(-)

diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 4dfc7238313e..b565e29c405c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -497,6 +497,7 @@ static const struct it87_devices it87_devices[] = {
 #define has_vin3_5v(data)  ((data)->features & FEAT_VIN3_5V)
 
 struct it87_sio_data {
+   int sioaddr;
enum chips type;
/* Values read from Super-I/O config space */
u8 revision;
@@ -517,6 +518,7 @@ struct it87_sio_data {
  */
 struct it87_data {
const struct attribute_group *groups[7];
+   int sioaddr;
enum chips type;
u32 features;
u8 peci_mask;
@@ -2389,10 +2391,11 @@ static const struct attribute_group it87_group_auto_pwm 
= {
 };
 
 /* SuperIO detection - will change isa_address if a chip is found */
-static int __init it87_find(int sioaddr, unsigned short *address,
+static int __init it87_find(unsigned short *address,
struct it87_sio_data *sio_data)
 {
int err;
+   int sioaddr = sio_data->sioaddr;
u16 chip_type;
const char *board_vendor, *board_name;
const struct it87_devices *config;
@@ -2828,13 +2831,89 @@ static int __init it87_find(int sioaddr, unsigned short 
*address,
return err;
 }
 
+/*
+ * Some chips seem to have default value 0xff for all limit
+ * registers. For low voltage limits it makes no sense and triggers
+ * alarms, so change to 0 instead. For high temperature limits, it
+ * means -1 degree C, which surprisingly doesn't trigger an alarm,
+ * but is still confusing, so change to 127 degrees C.
+ */
+static void it87_check_limit_regs(struct it87_data *data)
+{
+   int i, reg;
+
+   for (i = 0; i < NUM_VIN_LIMIT; i++) {
+   reg = it87_read_value(data, IT87_REG_VIN_MIN(i));
+   if (reg == 0xff)
+   it87_write_value(data, IT87_REG_VIN_MIN(i), 0);
+   }
+   for (i = 0; i < NUM_TEMP_LIMIT; i++) {
+   reg = it87_read_value(data, IT87_REG_TEMP_HIGH(i));
+   if (reg == 0xff)
+   it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
+   }
+}
+
+/* Check if voltage monitors are reset manually or by some reason */
+static void it87_check_voltage_monitors_reset(struct it87_data *data)
+{
+   int reg;
+
+   reg = it87_read_value(data, IT87_REG_VIN_ENABLE);
+   if ((reg & 0xff) == 0) {
+   /* Enable all voltage monitors */
+   it87_write_value(data, IT87_REG_VIN_ENABLE, 0xff);
+   }
+}
+
+/* Check if tachometers are reset manually or by some reason */
+static void it87_check_tachometers_reset(struct platform_device *pdev)
+{
+   struct it87_sio_data *sio_data = dev_get_platdata(>dev);
+   struct it87_data *data = platform_get_drvdata(pdev);
+   u8 mask, fan_main_ctrl;
+
+   mask = 0x70 & ~(sio_data->skip_fan << 4);
+   fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
+   if ((fan_main_ctrl & mask) == 0) {
+   /* Enable all fan tachometers */
+   fan_main_ctrl |= mask;
+   it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+fan_main_ctrl);
+   }
+}
+
+/* Set tachometers to 16-bit mode if needed */
+static void it87_check_tachometers_16bit_mode(struct platform_device *pdev)
+{
+   struct it87_data *data = platform_get_drvdata(pdev);
+   int reg;
+
+   if (!has_fan16_config(data))
+   return;
+
+   reg = it87_read_value(data, IT87_REG_FAN_16BIT);
+   if (~reg & 0x07 & data->has_fan) {
+   dev_dbg(>dev,
+   "Setting fan1-3 to 16-bit mode\n");
+   it87_write_value(data, IT87_REG_FAN_16BIT,
+reg | 0x07);
+   }
+}
+
+static void it87_start_monitoring(struct it87_data *data)
+{
+   it87_write_value(data, IT87_REG_CONFIG,
+(it87_read_value(data, IT87_REG_CONFIG) & 0x3e)
+| (update_vbat ? 0x41 : 0x01));
+}
+
 /* Called when we have found a new IT87. */
 static void it87_init_device(struct platform_device *pdev)
 {
struct it87_sio_data *sio_data = dev_get_platdata(>dev);
struct it87_data *data = platform_get_drvdata(pdev);
int tmp, i;
-   

Re: [PATCH v3 2/2] dt-bindings: mfd: Add bindings for ZII RAVE devices

2017-07-24 Thread Andrey Smirnov
On Mon, Jul 24, 2017 at 9:23 AM, Rob Herring  wrote:
> On Mon, Jul 24, 2017 at 08:09:15AM -0700, Andrey Smirnov wrote:
>> Cc: cphe...@gmail.com
>> Cc: Lucas Stach 
>> Cc: Nikita Yushchenko 
>> Cc: Rob Herring 
>> Cc: Mark Rutland 
>> Cc: devicet...@vger.kernel.org
>> Acked-for-MFD-by: Lee Jones 
>> Signed-off-by: Andrey Smirnov 
>> ---
>>  .../devicetree/bindings/mfd/zii,rave-sp.txt| 39 
>> ++
>>  1 file changed, 39 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mfd/zii,rave-sp.txt
>
> What happened to my ack?

Somehow I lost it, sorry about that. Will put it back in v4.

Thanks,
Andrey Smirnov


Re: [PATCH v3 2/2] dt-bindings: mfd: Add bindings for ZII RAVE devices

2017-07-24 Thread Andrey Smirnov
On Mon, Jul 24, 2017 at 9:23 AM, Rob Herring  wrote:
> On Mon, Jul 24, 2017 at 08:09:15AM -0700, Andrey Smirnov wrote:
>> Cc: cphe...@gmail.com
>> Cc: Lucas Stach 
>> Cc: Nikita Yushchenko 
>> Cc: Rob Herring 
>> Cc: Mark Rutland 
>> Cc: devicet...@vger.kernel.org
>> Acked-for-MFD-by: Lee Jones 
>> Signed-off-by: Andrey Smirnov 
>> ---
>>  .../devicetree/bindings/mfd/zii,rave-sp.txt| 39 
>> ++
>>  1 file changed, 39 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mfd/zii,rave-sp.txt
>
> What happened to my ack?

Somehow I lost it, sorry about that. Will put it back in v4.

Thanks,
Andrey Smirnov


Re: [PATCH v1 03/13] xen/pvcalls: implement socket command and handle events

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send a PVCALLS_SOCKET command to the backend, use the masked
> req_prod_pvt as req_id. This way, req_id is guaranteed to be between 0
> and PVCALLS_NR_REQ_PER_RING. We already have a slot in the rsp array
> ready for the response, and there cannot be two outstanding responses
> with the same req_id.
> 
> Wait for the response by waiting on the inflight_req waitqueue and
> check for the req_id field in rsp[req_id]. Use atomic accesses to
> read the field. Once a response is received, clear the corresponding rsp
> slot by setting req_id to PVCALLS_INVALID_ID. Note that
> PVCALLS_INVALID_ID is invalid only from the frontend point of view. It
> is not part of the PVCalls protocol.
> 
> pvcalls_front_event_handler is in charge of copying responses from the
> ring to the appropriate rsp slot. It is done by copying the body of the
> response first, then by copying req_id atomically. After the copies,
> wake up anybody waiting on waitqueue.
> 
> pvcallss_lock protects accesses to the ring.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 91 
> +
>  drivers/xen/pvcalls-front.h |  8 
>  2 files changed, 99 insertions(+)
>  create mode 100644 drivers/xen/pvcalls-front.h
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index fb08ebf..7933c73 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c

Shouldn't you include pvcalls-front.h?

> @@ -40,9 +40,100 @@ struct pvcalls_bedata {
>  
>  static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
>  {
> + struct xenbus_device *dev = dev_id;
> + struct pvcalls_bedata *bedata;
> + struct xen_pvcalls_response *rsp;
> + uint8_t *src, *dst;
> + int req_id = 0, more = 0;
> +
> + if (dev == NULL)
> + return IRQ_HANDLED;
> +
> + bedata = dev_get_drvdata(>dev);
> + if (bedata == NULL)
> + return IRQ_HANDLED;
> +
> +again:
> + while (RING_HAS_UNCONSUMED_RESPONSES(>ring)) {
> + rsp = RING_GET_RESPONSE(>ring, bedata->ring.rsp_cons);
> +
> + req_id = rsp->req_id;
> + src = (uint8_t *)>rsp[req_id];
> + src += sizeof(rsp->req_id);
> + dst = (uint8_t *)rsp;
> + dst += sizeof(rsp->req_id);
> + memcpy(dst, src, sizeof(*rsp) - sizeof(rsp->req_id));
> + /*
> +  * First copy the rest of the data, then req_id. It is
> +  * paired with the barrier when accessing bedata->rsp.
> +  */
> + smp_wmb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, rsp->req_id);
> +
> + bedata->ring.rsp_cons++;
> + wake_up(>inflight_req);
> + }
> +
> + RING_FINAL_CHECK_FOR_RESPONSES(>ring, more);
> + if (more)
> + goto again;

Wouldn't it make more sense to use wake_up() just once if there is any
response pending and do the consuming loop outside the irq handler?


Juergen

>   return IRQ_HANDLED;
>  }
>  
> +int pvcalls_front_socket(struct socket *sock)
> +{
> + struct pvcalls_bedata *bedata;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret;
> +
> + if (!pvcalls_front_dev)
> + return -EACCES;
> + /*
> +  * PVCalls only supports domain AF_INET,
> +  * type SOCK_STREAM and protocol 0 sockets for now.
> +  *
> +  * Check socket type here, AF_INET and protocol checks are done
> +  * by the caller.
> +  */
> + if (sock->type != SOCK_STREAM)
> + return -ENOTSUPP;
> +
> + bedata = dev_get_drvdata(_front_dev->dev);
> +
> + spin_lock(>pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
> + BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
> + if (RING_FULL(>ring) ||
> + READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
> + spin_unlock(>pvcallss_lock);
> + return -EAGAIN;
> + }
> + req = RING_GET_REQUEST(>ring, req_id);
> + req->req_id = req_id;
> + req->cmd = PVCALLS_SOCKET;
> + req->u.socket.id = (uint64_t) sock;
> + req->u.socket.domain = AF_INET;
> + req->u.socket.type = SOCK_STREAM;
> + req->u.socket.protocol = 0;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
> + spin_unlock(>pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + if (wait_event_interruptible(bedata->inflight_req,
> + READ_ONCE(bedata->rsp[req_id].req_id) == req_id) != 0)
> + return -EINTR;
> +
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> +
> + return ret;
> +}
> 

Re: [PATCH v1 03/13] xen/pvcalls: implement socket command and handle events

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Send a PVCALLS_SOCKET command to the backend, use the masked
> req_prod_pvt as req_id. This way, req_id is guaranteed to be between 0
> and PVCALLS_NR_REQ_PER_RING. We already have a slot in the rsp array
> ready for the response, and there cannot be two outstanding responses
> with the same req_id.
> 
> Wait for the response by waiting on the inflight_req waitqueue and
> check for the req_id field in rsp[req_id]. Use atomic accesses to
> read the field. Once a response is received, clear the corresponding rsp
> slot by setting req_id to PVCALLS_INVALID_ID. Note that
> PVCALLS_INVALID_ID is invalid only from the frontend point of view. It
> is not part of the PVCalls protocol.
> 
> pvcalls_front_event_handler is in charge of copying responses from the
> ring to the appropriate rsp slot. It is done by copying the body of the
> response first, then by copying req_id atomically. After the copies,
> wake up anybody waiting on waitqueue.
> 
> pvcallss_lock protects accesses to the ring.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 91 
> +
>  drivers/xen/pvcalls-front.h |  8 
>  2 files changed, 99 insertions(+)
>  create mode 100644 drivers/xen/pvcalls-front.h
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index fb08ebf..7933c73 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c

Shouldn't you include pvcalls-front.h?

> @@ -40,9 +40,100 @@ struct pvcalls_bedata {
>  
>  static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
>  {
> + struct xenbus_device *dev = dev_id;
> + struct pvcalls_bedata *bedata;
> + struct xen_pvcalls_response *rsp;
> + uint8_t *src, *dst;
> + int req_id = 0, more = 0;
> +
> + if (dev == NULL)
> + return IRQ_HANDLED;
> +
> + bedata = dev_get_drvdata(>dev);
> + if (bedata == NULL)
> + return IRQ_HANDLED;
> +
> +again:
> + while (RING_HAS_UNCONSUMED_RESPONSES(>ring)) {
> + rsp = RING_GET_RESPONSE(>ring, bedata->ring.rsp_cons);
> +
> + req_id = rsp->req_id;
> + src = (uint8_t *)>rsp[req_id];
> + src += sizeof(rsp->req_id);
> + dst = (uint8_t *)rsp;
> + dst += sizeof(rsp->req_id);
> + memcpy(dst, src, sizeof(*rsp) - sizeof(rsp->req_id));
> + /*
> +  * First copy the rest of the data, then req_id. It is
> +  * paired with the barrier when accessing bedata->rsp.
> +  */
> + smp_wmb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, rsp->req_id);
> +
> + bedata->ring.rsp_cons++;
> + wake_up(>inflight_req);
> + }
> +
> + RING_FINAL_CHECK_FOR_RESPONSES(>ring, more);
> + if (more)
> + goto again;

Wouldn't it make more sense to use wake_up() just once if there is any
response pending and do the consuming loop outside the irq handler?


Juergen

>   return IRQ_HANDLED;
>  }
>  
> +int pvcalls_front_socket(struct socket *sock)
> +{
> + struct pvcalls_bedata *bedata;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret;
> +
> + if (!pvcalls_front_dev)
> + return -EACCES;
> + /*
> +  * PVCalls only supports domain AF_INET,
> +  * type SOCK_STREAM and protocol 0 sockets for now.
> +  *
> +  * Check socket type here, AF_INET and protocol checks are done
> +  * by the caller.
> +  */
> + if (sock->type != SOCK_STREAM)
> + return -ENOTSUPP;
> +
> + bedata = dev_get_drvdata(_front_dev->dev);
> +
> + spin_lock(>pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(>ring) - 1);
> + BUG_ON(req_id >= PVCALLS_NR_REQ_PER_RING);
> + if (RING_FULL(>ring) ||
> + READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
> + spin_unlock(>pvcallss_lock);
> + return -EAGAIN;
> + }
> + req = RING_GET_REQUEST(>ring, req_id);
> + req->req_id = req_id;
> + req->cmd = PVCALLS_SOCKET;
> + req->u.socket.id = (uint64_t) sock;
> + req->u.socket.domain = AF_INET;
> + req->u.socket.type = SOCK_STREAM;
> + req->u.socket.protocol = 0;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(>ring, notify);
> + spin_unlock(>pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + if (wait_event_interruptible(bedata->inflight_req,
> + READ_ONCE(bedata->rsp[req_id].req_id) == req_id) != 0)
> + return -EINTR;
> +
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> +
> + return ret;
> +}
> +
>  static const 

Re: [PATCH] HID: rmi: Make sure the HID device is opened on resume

2017-07-24 Thread Jiri Kosina
On Mon, 24 Jul 2017, Lyude Paul wrote:

> > > So, call hid_hw_open() in rmi_post_resume() so we make sure that
> > > the
> > > device is alive before we try talking to it.
> > > 
> > > This fixes RMI device suspend/resume over HID.
> > > -   int ret;
> > > +   int ret = 0;
> > 
> > What's the point?
> So that we can use the same out: label at the end of the function that
> calls hid_hw_close() to return success. This being said though I just
> realized that setting ret will initialize it to 0 anyway, so I guess
> this can be dropped

Andy's point was that hid_hw_open() is obviously re-initializing the ret 
before its first use as a return value, so there is no need to initialize 
it at a declaration time.

-- 
Jiri Kosina
SUSE Labs



Re: [PATCH] HID: rmi: Make sure the HID device is opened on resume

2017-07-24 Thread Jiri Kosina
On Mon, 24 Jul 2017, Lyude Paul wrote:

> > > So, call hid_hw_open() in rmi_post_resume() so we make sure that
> > > the
> > > device is alive before we try talking to it.
> > > 
> > > This fixes RMI device suspend/resume over HID.
> > > -   int ret;
> > > +   int ret = 0;
> > 
> > What's the point?
> So that we can use the same out: label at the end of the function that
> calls hid_hw_close() to return success. This being said though I just
> realized that setting ret will initialize it to 0 anyway, so I guess
> this can be dropped

Andy's point was that hid_hw_open() is obviously re-initializing the ret 
before its first use as a return value, so there is no need to initialize 
it at a declaration time.

-- 
Jiri Kosina
SUSE Labs



Re: bcache with existing ext4 filesystem

2017-07-24 Thread Reindl Harald



Am 24.07.2017 um 20:57 schrieb Pavel Machek:

Would it be feasible to run bcache (write-through) with existing ext4
filesystem?

I have 400GB of data I'd rather not move, and SSD I could use for
caching. Ok, SSD is connecte over USB2, but I guess it is still way
faster then seeking harddrive on random access


i doubt that seriously - USB2 has a terrible latency


Re: bcache with existing ext4 filesystem

2017-07-24 Thread Reindl Harald



Am 24.07.2017 um 20:57 schrieb Pavel Machek:

Would it be feasible to run bcache (write-through) with existing ext4
filesystem?

I have 400GB of data I'd rather not move, and SSD I could use for
caching. Ok, SSD is connecte over USB2, but I guess it is still way
faster then seeking harddrive on random access


i doubt that seriously - USB2 has a terrible latency


Re: bcache with existing ext4 filesystem

2017-07-24 Thread Theodore Ts'o
On Mon, Jul 24, 2017 at 09:15:48PM +0200, Pavel Machek wrote:
> > 
> > Am 24.07.2017 um 20:57 schrieb Pavel Machek:
> > >Would it be feasible to run bcache (write-through) with existing ext4
> > >filesystem?
> > >
> > >I have 400GB of data I'd rather not move, and SSD I could use for
> > >caching. Ok, SSD is connecte over USB2, but I guess it is still way
> > >faster then seeking harddrive on random access
> > 
> > i doubt that seriously - USB2 has a terrible latency
> 
> Well.. if that's too slow, I can get SSD M.2; plus bcache docs says
> that combination works.
> 
> And... if you ever tried to do git diff while git checkout is running
> on spinning rust... spinning rust has awful parameters when idle, and
> it only gets worse when loaded :-(.

So some hard numbers.  Max throughput of USB 2.0 is 53 MiB/s[1].  In
actual practice the max throughput you will see out of the USB 2.0
interface is 30-40 MiB/s.  In contrast, a HDD doing sequential reads
can easily do much more than that.

[1] 
https://superuser.com/questions/317217/whats-the-maximum-typical-speed-possible-with-a-usb2-0-drive

So a lot is going to depend on how bcache works.  If you can get large
sequential reads and writes to *bypass* the cache device, then I think
there's a good cache that bcache on a USB 2.0 device won't hurt.  It
might not help as much as you like, but that's a function of the
overhead of populating the cache and whether the cache can keep the
useful bits in the cache device.

Cheers,

- Ted


Re: bcache with existing ext4 filesystem

2017-07-24 Thread Theodore Ts'o
On Mon, Jul 24, 2017 at 09:15:48PM +0200, Pavel Machek wrote:
> > 
> > Am 24.07.2017 um 20:57 schrieb Pavel Machek:
> > >Would it be feasible to run bcache (write-through) with existing ext4
> > >filesystem?
> > >
> > >I have 400GB of data I'd rather not move, and SSD I could use for
> > >caching. Ok, SSD is connecte over USB2, but I guess it is still way
> > >faster then seeking harddrive on random access
> > 
> > i doubt that seriously - USB2 has a terrible latency
> 
> Well.. if that's too slow, I can get SSD M.2; plus bcache docs says
> that combination works.
> 
> And... if you ever tried to do git diff while git checkout is running
> on spinning rust... spinning rust has awful parameters when idle, and
> it only gets worse when loaded :-(.

So some hard numbers.  Max throughput of USB 2.0 is 53 MiB/s[1].  In
actual practice the max throughput you will see out of the USB 2.0
interface is 30-40 MiB/s.  In contrast, a HDD doing sequential reads
can easily do much more than that.

[1] 
https://superuser.com/questions/317217/whats-the-maximum-typical-speed-possible-with-a-usb2-0-drive

So a lot is going to depend on how bcache works.  If you can get large
sequential reads and writes to *bypass* the cache device, then I think
there's a good cache that bcache on a USB 2.0 device won't hurt.  It
might not help as much as you like, but that's a function of the
overhead of populating the cache and whether the cache can keep the
useful bits in the cache device.

Cheers,

- Ted


Re: [PATCH v1 02/13] xen/pvcalls: connect to the backend

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Implement the probe function for the pvcalls frontend. Read the
> supported versions, max-page-order and function-calls nodes from
> xenstore.
> 
> Introduce a data structure named pvcalls_bedata. It contains pointers to
> the command ring, the event channel, a list of active sockets and a list
> of passive sockets. Lists accesses are protected by a spin_lock.
> 
> Introduce a waitqueue to allow waiting for a response on commands sent
> to the backend.
> 
> Introduce an array of struct xen_pvcalls_response to store commands
> responses.
> 
> Only one frontend<->backend connection is supported at any given time
> for a guest. Store the active frontend device to a static pointer.
> 
> Introduce a stub functions for the event handler.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 153 
> 
>  1 file changed, 153 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 173e204..fb08ebf 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -20,6 +20,29 @@
>  #include 
>  #include 
>  
> +#define PVCALLS_INVALID_ID (UINT_MAX)
> +#define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
> +#define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
> +
> +struct pvcalls_bedata {
> + struct xen_pvcalls_front_ring ring;
> + grant_ref_t ref;
> + int irq;
> +
> + struct list_head socket_mappings;
> + struct list_head socketpass_mappings;
> + spinlock_t pvcallss_lock;
> +
> + wait_queue_head_t inflight_req;
> + struct xen_pvcalls_response rsp[PVCALLS_NR_REQ_PER_RING];
> +};
> +struct xenbus_device *pvcalls_front_dev;
> +
> +static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
> +{
> + return IRQ_HANDLED;
> +}
> +
>  static const struct xenbus_device_id pvcalls_front_ids[] = {
>   { "pvcalls" },
>   { "" }
> @@ -33,7 +56,114 @@ static int pvcalls_front_remove(struct xenbus_device *dev)
>  static int pvcalls_front_probe(struct xenbus_device *dev,
> const struct xenbus_device_id *id)
>  {
> + int ret = -EFAULT, evtchn, ref = -1, i;
> + unsigned int max_page_order, function_calls, len;
> + char *versions;
> + grant_ref_t gref_head = 0;
> + struct xenbus_transaction xbt;
> + struct pvcalls_bedata *bedata = NULL;
> + struct xen_pvcalls_sring *sring;
> +
> + if (pvcalls_front_dev != NULL) {
> + dev_err(>dev, "only one PV Calls connection supported\n");
> + return -EINVAL;
> + }
> +
> + versions = xenbus_read(XBT_NIL, dev->otherend, "versions", );
> + if (!len)
> + return -EINVAL;
> + if (strcmp(versions, "1")) {
> + kfree(versions);
> + return -EINVAL;
> + }
> + kfree(versions);
> + ret = xenbus_scanf(XBT_NIL, dev->otherend,
> +"max-page-order", "%u", _page_order);

Use xenbus_read_unsigned() instead?

> + if (ret <= 0)
> + return -ENODEV;
> + if (max_page_order < RING_ORDER)
> + return -ENODEV;
> + ret = xenbus_scanf(XBT_NIL, dev->otherend,
> +"function-calls", "%u", _calls);

xenbus_read_unsigned() again?

> + if (ret <= 0 || function_calls != 1)
> + return -ENODEV;
> + pr_info("%s max-page-order is %u\n", __func__, max_page_order);
> +
> + bedata = kzalloc(sizeof(struct pvcalls_bedata), GFP_KERNEL);
> + if (!bedata)
> + return -ENOMEM;
> +

You should call dev_set_drvdata() here already, otherwise entering the
error path will dereference a NULL pointer instead of bedata.

> + init_waitqueue_head(>inflight_req);
> + for (i = 0; i < PVCALLS_NR_REQ_PER_RING; i++)
> + bedata->rsp[i].req_id = PVCALLS_INVALID_ID;
> +
> + sring = (struct xen_pvcalls_sring *) __get_free_page(GFP_KERNEL |
> +  __GFP_ZERO);
> + if (!sring)
> + goto error;

ret will be 1 here. Shouldn't you set it to -ENOMEM?

> + SHARED_RING_INIT(sring);
> + FRONT_RING_INIT(>ring, sring, XEN_PAGE_SIZE);
> +
> + ret = xenbus_alloc_evtchn(dev, );
> + if (ret)
> + goto error;
> +
> + bedata->irq = bind_evtchn_to_irqhandler(evtchn,
> + pvcalls_front_event_handler,
> + 0, "pvcalls-frontend", dev);
> + if (bedata->irq < 0) {
> + ret = bedata->irq;
> + goto error;
> + }
> +
> + ret = gnttab_alloc_grant_references(1, _head);
> + if (ret < 0)
> + goto error;
> + bedata->ref = ref = gnttab_claim_grant_reference(_head);
> + if (ref < 0)
> + goto error;

Setting ret?


Juergen

> + 

Re: [PATCH v1 02/13] xen/pvcalls: connect to the backend

2017-07-24 Thread Juergen Gross
On 22/07/17 02:11, Stefano Stabellini wrote:
> Implement the probe function for the pvcalls frontend. Read the
> supported versions, max-page-order and function-calls nodes from
> xenstore.
> 
> Introduce a data structure named pvcalls_bedata. It contains pointers to
> the command ring, the event channel, a list of active sockets and a list
> of passive sockets. Lists accesses are protected by a spin_lock.
> 
> Introduce a waitqueue to allow waiting for a response on commands sent
> to the backend.
> 
> Introduce an array of struct xen_pvcalls_response to store commands
> responses.
> 
> Only one frontend<->backend connection is supported at any given time
> for a guest. Store the active frontend device to a static pointer.
> 
> Introduce a stub functions for the event handler.
> 
> Signed-off-by: Stefano Stabellini 
> CC: boris.ostrov...@oracle.com
> CC: jgr...@suse.com
> ---
>  drivers/xen/pvcalls-front.c | 153 
> 
>  1 file changed, 153 insertions(+)
> 
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 173e204..fb08ebf 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -20,6 +20,29 @@
>  #include 
>  #include 
>  
> +#define PVCALLS_INVALID_ID (UINT_MAX)
> +#define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
> +#define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
> +
> +struct pvcalls_bedata {
> + struct xen_pvcalls_front_ring ring;
> + grant_ref_t ref;
> + int irq;
> +
> + struct list_head socket_mappings;
> + struct list_head socketpass_mappings;
> + spinlock_t pvcallss_lock;
> +
> + wait_queue_head_t inflight_req;
> + struct xen_pvcalls_response rsp[PVCALLS_NR_REQ_PER_RING];
> +};
> +struct xenbus_device *pvcalls_front_dev;
> +
> +static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
> +{
> + return IRQ_HANDLED;
> +}
> +
>  static const struct xenbus_device_id pvcalls_front_ids[] = {
>   { "pvcalls" },
>   { "" }
> @@ -33,7 +56,114 @@ static int pvcalls_front_remove(struct xenbus_device *dev)
>  static int pvcalls_front_probe(struct xenbus_device *dev,
> const struct xenbus_device_id *id)
>  {
> + int ret = -EFAULT, evtchn, ref = -1, i;
> + unsigned int max_page_order, function_calls, len;
> + char *versions;
> + grant_ref_t gref_head = 0;
> + struct xenbus_transaction xbt;
> + struct pvcalls_bedata *bedata = NULL;
> + struct xen_pvcalls_sring *sring;
> +
> + if (pvcalls_front_dev != NULL) {
> + dev_err(>dev, "only one PV Calls connection supported\n");
> + return -EINVAL;
> + }
> +
> + versions = xenbus_read(XBT_NIL, dev->otherend, "versions", );
> + if (!len)
> + return -EINVAL;
> + if (strcmp(versions, "1")) {
> + kfree(versions);
> + return -EINVAL;
> + }
> + kfree(versions);
> + ret = xenbus_scanf(XBT_NIL, dev->otherend,
> +"max-page-order", "%u", _page_order);

Use xenbus_read_unsigned() instead?

> + if (ret <= 0)
> + return -ENODEV;
> + if (max_page_order < RING_ORDER)
> + return -ENODEV;
> + ret = xenbus_scanf(XBT_NIL, dev->otherend,
> +"function-calls", "%u", _calls);

xenbus_read_unsigned() again?

> + if (ret <= 0 || function_calls != 1)
> + return -ENODEV;
> + pr_info("%s max-page-order is %u\n", __func__, max_page_order);
> +
> + bedata = kzalloc(sizeof(struct pvcalls_bedata), GFP_KERNEL);
> + if (!bedata)
> + return -ENOMEM;
> +

You should call dev_set_drvdata() here already, otherwise entering the
error path will dereference a NULL pointer instead of bedata.

> + init_waitqueue_head(>inflight_req);
> + for (i = 0; i < PVCALLS_NR_REQ_PER_RING; i++)
> + bedata->rsp[i].req_id = PVCALLS_INVALID_ID;
> +
> + sring = (struct xen_pvcalls_sring *) __get_free_page(GFP_KERNEL |
> +  __GFP_ZERO);
> + if (!sring)
> + goto error;

ret will be 1 here. Shouldn't you set it to -ENOMEM?

> + SHARED_RING_INIT(sring);
> + FRONT_RING_INIT(>ring, sring, XEN_PAGE_SIZE);
> +
> + ret = xenbus_alloc_evtchn(dev, );
> + if (ret)
> + goto error;
> +
> + bedata->irq = bind_evtchn_to_irqhandler(evtchn,
> + pvcalls_front_event_handler,
> + 0, "pvcalls-frontend", dev);
> + if (bedata->irq < 0) {
> + ret = bedata->irq;
> + goto error;
> + }
> +
> + ret = gnttab_alloc_grant_references(1, _head);
> + if (ret < 0)
> + goto error;
> + bedata->ref = ref = gnttab_claim_grant_reference(_head);
> + if (ref < 0)
> + goto error;

Setting ret?


Juergen

> + 

Re: [PATCH 2/3] can: m_can: Update documentation to indicate that hclk may be optional

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 06:09:25PM -0500, Franklin S Cooper Jr wrote:
> Update the documentation to reflect that hclk is now an optional clock.
> 
> Signed-off-by: Franklin S Cooper Jr 
> ---
>  Documentation/devicetree/bindings/net/can/m_can.txt | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Acked-by: Rob Herring 


Re: [PATCH 2/3] can: m_can: Update documentation to indicate that hclk may be optional

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 06:09:25PM -0500, Franklin S Cooper Jr wrote:
> Update the documentation to reflect that hclk is now an optional clock.
> 
> Signed-off-by: Franklin S Cooper Jr 
> ---
>  Documentation/devicetree/bindings/net/can/m_can.txt | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Acked-by: Rob Herring 


Re: [PATCH 2/7] memory: atmel-ebi: Simplify SMC config code

2017-07-24 Thread Boris Brezillon
Hi Alexander,

Le Mon, 24 Jul 2017 11:12:18 +0200,
Alexander Dahl  a écrit :

> Hello Boris,
> 
> while testing v4.13-rc2 on an at91sam9g20 baed platform I'm coming back 
> to this topic. Meanwhile the whole new SMC and NAND below EBI stuff is 
> in mainline, this TDF bug however is still in there. See below (all 
> quoted code parts from v4.13-rc2):
> 
> Am Donnerstag, 2. März 2017, 13:30:13 schrieb Boris Brezillon:
> > Alexander Dahl  wrote:  
> > > #define ATMEL_SMC_MODE_TDF(x)   (((x) - 1) << 16)  
> 
> […]
> 
> > > The hardware manual (AT91SAM9G20) says values from 0 to 15 (4bit,
> > > 0x0 to 0xF) are possible and I guess the goal is to set it to a
> > > value corresponding to the value in ns from the dts or to 15 if
> > > it's greater (or -EINVAL in the new version).
> > > 
> > > However how can one set it to zero? Put in zero to the div you get
> > > zero for ncycles or val and that goes as x into (((x) - 1) << 16)
> > > which results in 0xF ending up as TDF_CYCLES in the mode register,
> > > right?  
> > 
> > Indeed.
> >   
> > > I can of course set a slightly greater value, which ends up in a
> > > calculated register value of zero, but that seems more a hack to me
> > > and is not obvious if I just look at the DTS.  
> > 
> > No, we should fix the bug.
> >   
> > > If I'm right this might be topic of another bugfix patch, or should
> > > it be done right in a v2 of this one?  
> > 
> > It should be done right in a v2. Something like:
> > 
> > if (ncycles < ATMEL_SMC_MODE_TDF_MIN)
> > ncycles = ATMEL_SMC_MODE_TDF_MIN;
> > 
> > with
> > 
> > #define ATMEL_SMC_MODE_TDF_MIN 1  
> 
> I checked the SAMA5D3x datasheet today and it has the same mode register 
> layout regarding the TDF parts. So allowed are register values from 0 to 
> 15 ending up in 0 to 15 clock cycles of Data Float Time.
> 
> The code in include/linux/mfd/syscon/atmel-smc.h is this:
> 
> #define ATMEL_SMC_MODE_TDF_MASK   GENMASK(19, 16)
> #define ATMEL_SMC_MODE_TDF(x) (((x) - 1) << 16)
> #define ATMEL_SMC_MODE_TDF_MAX16
> #define ATMEL_SMC_MODE_TDF_MIN1
> #define ATMEL_SMC_MODE_TDFMODE_OPTIMIZED  BIT(20)
> 
> This ATMEL_SMC_MODE_TDF() is used in drivers/memory/atmel-ebi.c to setup 
> the external memory interface with timings from dts. A line there inside 
> an ebi node may look like this (see for example 
> arch/arm/boot/dts/sama5d3xcm.dtsi):
> 
> atmel,smc-tdf-ns = <0>;
> 
> The value is expected in nanoseconds and I would expect a direct mapping 
> from 0ns to a register value of 0. This is not the case in code 
> (drivers/memory/atmel-ebi.c):
> 
>   if (ncycles > ATMEL_SMC_MODE_TDF_MAX ||
>   ncycles < ATMEL_SMC_MODE_TDF_MIN) {
>   ret = -EINVAL;
>   goto out;
>   }
> 
> ATMEL_SMC_MODE_TDF_MIN is 1, so a possible 0 value from dts is not 
> allowed in here and atmel_ebi_xslate_smc_timings() fails. In fact to get 
> a register value of 0 for 0 TDF clock cycles I would have to set e.g. 
> 8ns in dts. So this didn't make it in some v2 and is still broken.

Yep, sorry about that.

> 
> I could fix this and provide a patch, but I'm not sure about the second 
> place where ATMEL_SMC_MODE_TDF() is used which is the NAND driver in 
> drivers/mtd/nand/atmel/nand-controller.c. I'm not familiar enough with 
> NAND to judge if this "min = 1, max = 16, decrease by 1 for applying to 
> register" approach is needed there. I would say no, because it also is a 
> counterintuitive offset, but I would prefer a explanation why the code 
> is like this, before touching and breaking anything. ;-)

There is a good reason for this "- 1": the doc says the exact number of
tDF cycles is TDF_CYCLES + 1. When you are expressing timings in ns it does
matter, because you don't want to wait more than necessary. Say the master
clk period is X ns and you want a tDF of X ns. If you divide tDF_ns by the
clk period you get one, and you only want to wait 1 cycle, not two.

The NAND driver seems to do the right thing already [1].

Below is my suggestion below to fix the problem. Did you have something else
in mind? In any case, can you send a patch to fix it (either using my
suggestion or something else if you prefer).

Regards,

Boris


[1]http://elixir.free-electrons.com/linux/v4.13-rc1/source/drivers/mtd/nand/atmel/nand-controller.c#L1309

--->8---
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
index 99e644cda4d1..d94604590d02 100644
--- a/drivers/memory/atmel-ebi.c
+++ b/drivers/memory/atmel-ebi.c
@@ -120,12 +120,14 @@ static int atmel_ebi_xslate_smc_timings(struct 
atmel_ebi_dev *ebid,
if (!ret) {
required = true;
ncycles = DIV_ROUND_UP(val, clk_period_ns);
-   if (ncycles > ATMEL_SMC_MODE_TDF_MAX ||
-   ncycles < 

Re: [PATCH 2/7] memory: atmel-ebi: Simplify SMC config code

2017-07-24 Thread Boris Brezillon
Hi Alexander,

Le Mon, 24 Jul 2017 11:12:18 +0200,
Alexander Dahl  a écrit :

> Hello Boris,
> 
> while testing v4.13-rc2 on an at91sam9g20 baed platform I'm coming back 
> to this topic. Meanwhile the whole new SMC and NAND below EBI stuff is 
> in mainline, this TDF bug however is still in there. See below (all 
> quoted code parts from v4.13-rc2):
> 
> Am Donnerstag, 2. März 2017, 13:30:13 schrieb Boris Brezillon:
> > Alexander Dahl  wrote:  
> > > #define ATMEL_SMC_MODE_TDF(x)   (((x) - 1) << 16)  
> 
> […]
> 
> > > The hardware manual (AT91SAM9G20) says values from 0 to 15 (4bit,
> > > 0x0 to 0xF) are possible and I guess the goal is to set it to a
> > > value corresponding to the value in ns from the dts or to 15 if
> > > it's greater (or -EINVAL in the new version).
> > > 
> > > However how can one set it to zero? Put in zero to the div you get
> > > zero for ncycles or val and that goes as x into (((x) - 1) << 16)
> > > which results in 0xF ending up as TDF_CYCLES in the mode register,
> > > right?  
> > 
> > Indeed.
> >   
> > > I can of course set a slightly greater value, which ends up in a
> > > calculated register value of zero, but that seems more a hack to me
> > > and is not obvious if I just look at the DTS.  
> > 
> > No, we should fix the bug.
> >   
> > > If I'm right this might be topic of another bugfix patch, or should
> > > it be done right in a v2 of this one?  
> > 
> > It should be done right in a v2. Something like:
> > 
> > if (ncycles < ATMEL_SMC_MODE_TDF_MIN)
> > ncycles = ATMEL_SMC_MODE_TDF_MIN;
> > 
> > with
> > 
> > #define ATMEL_SMC_MODE_TDF_MIN 1  
> 
> I checked the SAMA5D3x datasheet today and it has the same mode register 
> layout regarding the TDF parts. So allowed are register values from 0 to 
> 15 ending up in 0 to 15 clock cycles of Data Float Time.
> 
> The code in include/linux/mfd/syscon/atmel-smc.h is this:
> 
> #define ATMEL_SMC_MODE_TDF_MASK   GENMASK(19, 16)
> #define ATMEL_SMC_MODE_TDF(x) (((x) - 1) << 16)
> #define ATMEL_SMC_MODE_TDF_MAX16
> #define ATMEL_SMC_MODE_TDF_MIN1
> #define ATMEL_SMC_MODE_TDFMODE_OPTIMIZED  BIT(20)
> 
> This ATMEL_SMC_MODE_TDF() is used in drivers/memory/atmel-ebi.c to setup 
> the external memory interface with timings from dts. A line there inside 
> an ebi node may look like this (see for example 
> arch/arm/boot/dts/sama5d3xcm.dtsi):
> 
> atmel,smc-tdf-ns = <0>;
> 
> The value is expected in nanoseconds and I would expect a direct mapping 
> from 0ns to a register value of 0. This is not the case in code 
> (drivers/memory/atmel-ebi.c):
> 
>   if (ncycles > ATMEL_SMC_MODE_TDF_MAX ||
>   ncycles < ATMEL_SMC_MODE_TDF_MIN) {
>   ret = -EINVAL;
>   goto out;
>   }
> 
> ATMEL_SMC_MODE_TDF_MIN is 1, so a possible 0 value from dts is not 
> allowed in here and atmel_ebi_xslate_smc_timings() fails. In fact to get 
> a register value of 0 for 0 TDF clock cycles I would have to set e.g. 
> 8ns in dts. So this didn't make it in some v2 and is still broken.

Yep, sorry about that.

> 
> I could fix this and provide a patch, but I'm not sure about the second 
> place where ATMEL_SMC_MODE_TDF() is used which is the NAND driver in 
> drivers/mtd/nand/atmel/nand-controller.c. I'm not familiar enough with 
> NAND to judge if this "min = 1, max = 16, decrease by 1 for applying to 
> register" approach is needed there. I would say no, because it also is a 
> counterintuitive offset, but I would prefer a explanation why the code 
> is like this, before touching and breaking anything. ;-)

There is a good reason for this "- 1": the doc says the exact number of
tDF cycles is TDF_CYCLES + 1. When you are expressing timings in ns it does
matter, because you don't want to wait more than necessary. Say the master
clk period is X ns and you want a tDF of X ns. If you divide tDF_ns by the
clk period you get one, and you only want to wait 1 cycle, not two.

The NAND driver seems to do the right thing already [1].

Below is my suggestion below to fix the problem. Did you have something else
in mind? In any case, can you send a patch to fix it (either using my
suggestion or something else if you prefer).

Regards,

Boris


[1]http://elixir.free-electrons.com/linux/v4.13-rc1/source/drivers/mtd/nand/atmel/nand-controller.c#L1309

--->8---
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
index 99e644cda4d1..d94604590d02 100644
--- a/drivers/memory/atmel-ebi.c
+++ b/drivers/memory/atmel-ebi.c
@@ -120,12 +120,14 @@ static int atmel_ebi_xslate_smc_timings(struct 
atmel_ebi_dev *ebid,
if (!ret) {
required = true;
ncycles = DIV_ROUND_UP(val, clk_period_ns);
-   if (ncycles > ATMEL_SMC_MODE_TDF_MAX ||
-   ncycles < ATMEL_SMC_MODE_TDF_MIN) {
+   if (ncycles > 

Re: [PATCHv4 1/3] dt-bindings: input: add pwm-vibrator

2017-07-24 Thread Pavel Machek
On Fri 2017-07-14 12:01:49, Sebastian Reichel wrote:
> Add DT binding document for PWM controlled vibrator devices.
> 
> Signed-off-by: Sebastian Reichel 

Acked-by: Pavel Machek 

> index ..09145d18491d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/pwm-vibrator.txt
> @@ -0,0 +1,66 @@
> +* PWM vibrator device tree bindings
> +
> +Registers a PWM device as vibrator. It is expected, that the vibrator's
> +strength increases based on the duty cycle of the enable PWM channel
> +(100% duty cycle meaning strongest vibration, 0% meaning no vibration).
> +
> +The binding supports an optional direction PWM channel, that can be
> +driven at fixed duty cycle. If available this is can be used to increase
> +the vibration effect of some devices.

Actually what "direction" does would be nice to explain, because I
don't know. Does it make the motor turn the other way around?

> +Required properties:
> +- compatible: should contain "pwm-vibrator"

should->Should.

> +- pwm-names: Should contain "enable" and optionally "direction"
> +- pwms: Should contain a PWM handle for each entry in pwm-names
> +
> +Optional properties:
> +- vcc-supply: Phandle for the regulator supplying power
> +- direction-duty-cycle-ns: Duty cycle of the direction PWM channel in
> +   nanoseconds, defaults to 50% of the channel's
> +period.

Is nanoseconds right unit here? It drives a motor...

Thanks,
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCHv4 1/3] dt-bindings: input: add pwm-vibrator

2017-07-24 Thread Pavel Machek
On Fri 2017-07-14 12:01:49, Sebastian Reichel wrote:
> Add DT binding document for PWM controlled vibrator devices.
> 
> Signed-off-by: Sebastian Reichel 

Acked-by: Pavel Machek 

> index ..09145d18491d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/pwm-vibrator.txt
> @@ -0,0 +1,66 @@
> +* PWM vibrator device tree bindings
> +
> +Registers a PWM device as vibrator. It is expected, that the vibrator's
> +strength increases based on the duty cycle of the enable PWM channel
> +(100% duty cycle meaning strongest vibration, 0% meaning no vibration).
> +
> +The binding supports an optional direction PWM channel, that can be
> +driven at fixed duty cycle. If available this is can be used to increase
> +the vibration effect of some devices.

Actually what "direction" does would be nice to explain, because I
don't know. Does it make the motor turn the other way around?

> +Required properties:
> +- compatible: should contain "pwm-vibrator"

should->Should.

> +- pwm-names: Should contain "enable" and optionally "direction"
> +- pwms: Should contain a PWM handle for each entry in pwm-names
> +
> +Optional properties:
> +- vcc-supply: Phandle for the regulator supplying power
> +- direction-duty-cycle-ns: Duty cycle of the direction PWM channel in
> +   nanoseconds, defaults to 50% of the channel's
> +period.

Is nanoseconds right unit here? It drives a motor...

Thanks,
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH 07/11] mfd: Drop unnecessary static

2017-07-24 Thread Pavel Machek
Hi!

> > > Drop static on a local variable, when the variable is initialized before
> > > any possible use.  Thus, the static has no benefit.

Actually... it has possible other benefit -- saving stack space. I've
used static for that purpose before. So ... careful with the
automation.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH 3/3] ARM: dts: omap4-droid4: add soundcard

2017-07-24 Thread Pavel Machek
On Mon 2017-07-10 13:26:02, Mark Brown wrote:
> On Fri, Jul 07, 2017 at 06:42:29PM +0200, Sebastian Reichel wrote:
> 
> > +   soundcard {
> > +   compatible = "simple-audio-card";
> > +   simple-audio-card,name = "Droid 4 Audio";
> 
> New systems should be using the of-graph card which is more flexible and
> extensible than simple-card.

Well, if simple-card does what is needed here, and dts looks
reasonable, is there reason for anything more complex?

Anyway, congratulations for getting the sound to work!

Pavel


-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH 07/11] mfd: Drop unnecessary static

2017-07-24 Thread Pavel Machek
Hi!

> > > Drop static on a local variable, when the variable is initialized before
> > > any possible use.  Thus, the static has no benefit.

Actually... it has possible other benefit -- saving stack space. I've
used static for that purpose before. So ... careful with the
automation.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH 3/3] ARM: dts: omap4-droid4: add soundcard

2017-07-24 Thread Pavel Machek
On Mon 2017-07-10 13:26:02, Mark Brown wrote:
> On Fri, Jul 07, 2017 at 06:42:29PM +0200, Sebastian Reichel wrote:
> 
> > +   soundcard {
> > +   compatible = "simple-audio-card";
> > +   simple-audio-card,name = "Droid 4 Audio";
> 
> New systems should be using the of-graph card which is more flexible and
> extensible than simple-card.

Well, if simple-card does what is needed here, and dts looks
reasonable, is there reason for anything more complex?

Anyway, congratulations for getting the sound to work!

Pavel


-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [GIT PULL] MFD for v4.13

2017-07-24 Thread Pavel Machek
Hi!

> > > >  include/linux/mfd/madera/registers.h   | 8832 
> > > > 
> > > 
> > > So I've pulled everything but this, because honestly, that file looks
> > > like utter garbage.
> > > 
> > > Why are there all those _hundreds_ of odd defines for
> > > 
> > >   MADERA_WSEQ_SEQUENCE_xx
> > > 
> > > when it looks like you could just do one single one:
> > > 
> > >   // The sequence is one-based because somebody doesn't
> > >   // know that indices start at 0. Thus the "-2".
> > >   #define MADERA_WSEQ_SEQUENCE(x) (0x3000 + (x)*2 - 2)
...
> > >  (a) probably closer to 200x too many lines
> > >  (b) less flexible than doing it right
> > > 
> > > Honestly, tell me why would I want to merge something monstrous like that?
> > 
> > I'm inclined to agree and had my reservations.  However based on
> > a previous conversation [0], I was convinced that it's actually the
> > right thing to do. 
> > 
> > https://lkml.org/lkml/2017/4/7/229
...
> We really quite like to keep all the registers defined because it
> makes the source highly greppable, which is extremely useful. A
> type of question which is often asked is "what does the driver
> do with register bits XYZ" or "where does it use register
> bits XYZ". Eliminating definitions into generator macros or
> block-indexing code makes these questions more difficult to
> answer. Another convenience is that it makes it easier for people
> to translate raw hardware configurations (which are a list
> of register values) into ALSA and pdata settings if they can

Well, easy grep is a nice thing, but not worth the cost of 8000 lines
vs. 40 lines. I'm sure you can write the required regexps in less than
7960 lines.

Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [GIT PULL] MFD for v4.13

2017-07-24 Thread Pavel Machek
Hi!

> > > >  include/linux/mfd/madera/registers.h   | 8832 
> > > > 
> > > 
> > > So I've pulled everything but this, because honestly, that file looks
> > > like utter garbage.
> > > 
> > > Why are there all those _hundreds_ of odd defines for
> > > 
> > >   MADERA_WSEQ_SEQUENCE_xx
> > > 
> > > when it looks like you could just do one single one:
> > > 
> > >   // The sequence is one-based because somebody doesn't
> > >   // know that indices start at 0. Thus the "-2".
> > >   #define MADERA_WSEQ_SEQUENCE(x) (0x3000 + (x)*2 - 2)
...
> > >  (a) probably closer to 200x too many lines
> > >  (b) less flexible than doing it right
> > > 
> > > Honestly, tell me why would I want to merge something monstrous like that?
> > 
> > I'm inclined to agree and had my reservations.  However based on
> > a previous conversation [0], I was convinced that it's actually the
> > right thing to do. 
> > 
> > https://lkml.org/lkml/2017/4/7/229
...
> We really quite like to keep all the registers defined because it
> makes the source highly greppable, which is extremely useful. A
> type of question which is often asked is "what does the driver
> do with register bits XYZ" or "where does it use register
> bits XYZ". Eliminating definitions into generator macros or
> block-indexing code makes these questions more difficult to
> answer. Another convenience is that it makes it easier for people
> to translate raw hardware configurations (which are a list
> of register values) into ALSA and pdata settings if they can

Well, easy grep is a nice thing, but not worth the cost of 8000 lines
vs. 40 lines. I'm sure you can write the required regexps in less than
7960 lines.

Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH v4 2/5] dt-bindings: pwm-backlight: add PWM delay proprieties.

2017-07-24 Thread Pavel Machek
On Mon 2017-07-24 16:21:44, Daniel Thompson wrote:
> On 21/07/17 11:48, Enric Balletbo i Serra wrote:
> >Hardware needs a delay between setting an initial (non-zero) PWM and
> >enabling the backlight using GPIO. The post-pwm-on-delay-ms specifies
> >this delay in milli seconds. Hardware also needs a delay between disabing
> >the backlight using GPIO and setting PWM value to 0. The pwm-off-delay-ms
> >is this delay in milli seconds.
> >
> >Signed-off-by: Enric Balletbo i Serra 
> >Acked-by: Pavel Machek 
> >---
> >Based on the original Huang Lin  work.
> >
> >Changes since v3:
> >  - Replace us for ms.
> >  - Add Acked-by: Pavel Machek 
> >Changes since v2:
> >  - Use separate properties (Rob Herring)
> >Changes since v1:
> >  - As suggested by Daniel Thompson
> >- Do not assume power-on delay and power-off delay will be the same
> >
> >  Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt | 6 
> > ++
> >  1 file changed, 6 insertions(+)
> >
> >diff --git 
> >a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt 
> >b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> >index 764db86..3108109 100644
> >--- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> >+++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> >@@ -17,6 +17,10 @@ Optional properties:
> > "pwms" property (see PWM binding[0])
> >- enable-gpios: contains a single GPIO specifier for the GPIO which 
> > enables
> >and disables the backlight (see GPIO binding[1])
> >+  - post-pwm-on-delay-ms: Delay in ms between setting an initial (non-zero) 
> >PWM
> >+  and enabling the backlight using GPIO.
> >+  - pwm-off-delay-ms: Delay in ms between disabling the backlight using GPIO
> >+  and setting PWM value to 0.
> 
> Whilst it is strictly true that the delay you added to the driver is
> currently between disabling the backlight and setting PWM value to 0 I don't
> think the action should be described at this level of detail in the DT
> bindings.
> 
> The semantic action that is being performed is "stopping the PWM". This is
> currently implemented by setting the duty cycle to 0 and then calling
> disable but that could change (especially so since the current behavior
> looks asymmetric versus the enable sequence).

Well, datasheet say the delay is required between given actions, so
yes, I'd say that belongs in the device tree at this level of detail.

Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH V2 2/9] dt-bindings: usb: bdc: Add Device Tree binding for Broadcom UDC driver

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 03:11:41PM -0400, Al Cooper wrote:
> Add Device Tree binding document for Broadcom USB Device
> Controller (BDC).
> 
> Signed-off-by: Al Cooper 
> ---
>  Documentation/devicetree/bindings/usb/brcm,bdc.txt | 29 
> ++
>  1 file changed, 29 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/brcm,bdc.txt

Acked-by: Rob Herring 


Re: [PATCH v4 2/5] dt-bindings: pwm-backlight: add PWM delay proprieties.

2017-07-24 Thread Pavel Machek
On Mon 2017-07-24 16:21:44, Daniel Thompson wrote:
> On 21/07/17 11:48, Enric Balletbo i Serra wrote:
> >Hardware needs a delay between setting an initial (non-zero) PWM and
> >enabling the backlight using GPIO. The post-pwm-on-delay-ms specifies
> >this delay in milli seconds. Hardware also needs a delay between disabing
> >the backlight using GPIO and setting PWM value to 0. The pwm-off-delay-ms
> >is this delay in milli seconds.
> >
> >Signed-off-by: Enric Balletbo i Serra 
> >Acked-by: Pavel Machek 
> >---
> >Based on the original Huang Lin  work.
> >
> >Changes since v3:
> >  - Replace us for ms.
> >  - Add Acked-by: Pavel Machek 
> >Changes since v2:
> >  - Use separate properties (Rob Herring)
> >Changes since v1:
> >  - As suggested by Daniel Thompson
> >- Do not assume power-on delay and power-off delay will be the same
> >
> >  Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt | 6 
> > ++
> >  1 file changed, 6 insertions(+)
> >
> >diff --git 
> >a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt 
> >b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> >index 764db86..3108109 100644
> >--- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> >+++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> >@@ -17,6 +17,10 @@ Optional properties:
> > "pwms" property (see PWM binding[0])
> >- enable-gpios: contains a single GPIO specifier for the GPIO which 
> > enables
> >and disables the backlight (see GPIO binding[1])
> >+  - post-pwm-on-delay-ms: Delay in ms between setting an initial (non-zero) 
> >PWM
> >+  and enabling the backlight using GPIO.
> >+  - pwm-off-delay-ms: Delay in ms between disabling the backlight using GPIO
> >+  and setting PWM value to 0.
> 
> Whilst it is strictly true that the delay you added to the driver is
> currently between disabling the backlight and setting PWM value to 0 I don't
> think the action should be described at this level of detail in the DT
> bindings.
> 
> The semantic action that is being performed is "stopping the PWM". This is
> currently implemented by setting the duty cycle to 0 and then calling
> disable but that could change (especially so since the current behavior
> looks asymmetric versus the enable sequence).

Well, datasheet say the delay is required between given actions, so
yes, I'd say that belongs in the device tree at this level of detail.

Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH V2 2/9] dt-bindings: usb: bdc: Add Device Tree binding for Broadcom UDC driver

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 03:11:41PM -0400, Al Cooper wrote:
> Add Device Tree binding document for Broadcom USB Device
> Controller (BDC).
> 
> Signed-off-by: Al Cooper 
> ---
>  Documentation/devicetree/bindings/usb/brcm,bdc.txt | 29 
> ++
>  1 file changed, 29 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/brcm,bdc.txt

Acked-by: Rob Herring 


Re: [PATCH v2 12/25] dt-bindings: qcom_nandc: QPIC NAND documentation

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 05:18:00PM +0530, Abhishek Sahu wrote:
> 1. QPIC NAND will use compatible string "qcom,qpic-nandc-v1.4.0"
> 2. QPIC NAND will 3 BAM channels: command, data tx and data rx
>while EBI2 NAND uses only single ADM channel.
> 3. CRCI is only required for ADM DMA and its not required for
>QPIC NAND.
> 
> Signed-off-by: Abhishek Sahu 
> ---
>  .../devicetree/bindings/mtd/qcom_nandc.txt | 54 
> --
>  1 file changed, 51 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt 
> b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> index b24adfe..8efaeb0 100644
> --- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> +++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> @@ -1,13 +1,15 @@
>  * Qualcomm NAND controller
>  
>  Required properties:
> -- compatible:should be "qcom,ebi2-nandc" - EBI2 NAND which 
> uses ADM
> - DMA like IPQ8064.
> -
> +- compatible:must be one of the following:
> + * "qcom,ebi2-nandc" - EBI2 NAND which uses ADM DMA like IPQ8064.
> + * "qcom,qpic-nandc-v1.4.0" - QPIC NAND v1.4.0 which uses BAM DMA like 
> IPQ4019.

Looks like you have 2 SoCs and 2 versions of h/w. Use SoC specific 
compatible strings.

Rob


Re: [PATCH v2 12/25] dt-bindings: qcom_nandc: QPIC NAND documentation

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 05:18:00PM +0530, Abhishek Sahu wrote:
> 1. QPIC NAND will use compatible string "qcom,qpic-nandc-v1.4.0"
> 2. QPIC NAND will 3 BAM channels: command, data tx and data rx
>while EBI2 NAND uses only single ADM channel.
> 3. CRCI is only required for ADM DMA and its not required for
>QPIC NAND.
> 
> Signed-off-by: Abhishek Sahu 
> ---
>  .../devicetree/bindings/mtd/qcom_nandc.txt | 54 
> --
>  1 file changed, 51 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt 
> b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> index b24adfe..8efaeb0 100644
> --- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> +++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> @@ -1,13 +1,15 @@
>  * Qualcomm NAND controller
>  
>  Required properties:
> -- compatible:should be "qcom,ebi2-nandc" - EBI2 NAND which 
> uses ADM
> - DMA like IPQ8064.
> -
> +- compatible:must be one of the following:
> + * "qcom,ebi2-nandc" - EBI2 NAND which uses ADM DMA like IPQ8064.
> + * "qcom,qpic-nandc-v1.4.0" - QPIC NAND v1.4.0 which uses BAM DMA like 
> IPQ4019.

Looks like you have 2 SoCs and 2 versions of h/w. Use SoC specific 
compatible strings.

Rob


Re: bcache with existing ext4 filesystem

2017-07-24 Thread Pavel Machek
On Mon 2017-07-24 21:08:16, Reindl Harald wrote:
> 
> 
> Am 24.07.2017 um 20:57 schrieb Pavel Machek:
> >Would it be feasible to run bcache (write-through) with existing ext4
> >filesystem?
> >
> >I have 400GB of data I'd rather not move, and SSD I could use for
> >caching. Ok, SSD is connecte over USB2, but I guess it is still way
> >faster then seeking harddrive on random access
> 
> i doubt that seriously - USB2 has a terrible latency

Well.. if that's too slow, I can get SSD M.2; plus bcache docs says
that combination works.

And... if you ever tried to do git diff while git checkout is running
on spinning rust... spinning rust has awful parameters when idle, and
it only gets worse when loaded :-(.

Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: bcache with existing ext4 filesystem

2017-07-24 Thread Pavel Machek
On Mon 2017-07-24 21:08:16, Reindl Harald wrote:
> 
> 
> Am 24.07.2017 um 20:57 schrieb Pavel Machek:
> >Would it be feasible to run bcache (write-through) with existing ext4
> >filesystem?
> >
> >I have 400GB of data I'd rather not move, and SSD I could use for
> >caching. Ok, SSD is connecte over USB2, but I guess it is still way
> >faster then seeking harddrive on random access
> 
> i doubt that seriously - USB2 has a terrible latency

Well.. if that's too slow, I can get SSD M.2; plus bcache docs says
that combination works.

And... if you ever tried to do git diff while git checkout is running
on spinning rust... spinning rust has awful parameters when idle, and
it only gets worse when loaded :-(.

Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH] cgroup: remove unnecessary empty check when enabling threaded mode

2017-07-24 Thread Waiman Long
On 07/23/2017 08:18 AM, Tejun Heo wrote:
> cgroup_enable_threaded() checks that the cgroup doesn't have any tasks
> or children and fails the operation if so.  This test is unnecessary
> because the first part is already checked by
> cgroup_can_be_thread_root() and the latter is unnecessary.  The latter
> actually cause a behavioral oddity.  Please consider the following
> hierarchy.  All cgroups are domains.
>
> A
>/ \
>   B   C
>\
> D
>
> If B is made threaded, C and D becomes invalid domains.  Due to the no
> children restriction, threaded mode can't be enabled on C.  For C and
> D, the only thing the user can do is removal.
>
> There is no reason for this restriction.  Remove it.
>
> Signed-off-by: Tejun Heo 
> Cc: Waiman Long 
> ---
> Hello,
>
> So, the only thing inconsistent there was the extra restriction when
> enabling threaded mode when all the necessary conditions are already
> checked by when verifying the parent's domain.
>
> Thanks.
>
>  Documentation/cgroup-v2.txt |5 +++--
>  kernel/cgroup/cgroup.c  |7 ---
>  2 files changed, 3 insertions(+), 9 deletions(-)
>
> --- a/Documentation/cgroup-v2.txt
> +++ b/Documentation/cgroup-v2.txt
> @@ -274,8 +274,9 @@ thread mode, the following conditions mu
>  - As the cgroup will join the parent's resource domain.  The parent
>must either be a valid (threaded) domain or a threaded cgroup.
>  
> -- The cgroup must be empty.  No enabled controllers, child cgroups or
> -  processes.
> +- When the parent is an unthreaded domain, it must not have any domain
> +  controllers enabled or populated domain children.  The root is
> +  exempt from this requirement.
>  
>  Topology-wise, a cgroup can be in an invalid state.  Please consider
>  the following toplogy::
> --- a/kernel/cgroup/cgroup.c
> +++ b/kernel/cgroup/cgroup.c
> @@ -3147,13 +3147,6 @@ static int cgroup_enable_threaded(struct
>   return -EOPNOTSUPP;
>  
>   /*
> -  * Allow enabling thread mode only on empty cgroups to avoid
> -  * implicit migrations and recursive operations.
> -  */
> - if (cgroup_has_tasks(cgrp) || css_has_online_children(>self))
> - return -EBUSY;
> -
> - /*
>* The following shouldn't cause actual migrations and should
>* always succeed.
>*/

Acked-by: Waiman Long 

While you are at it, the one comment that I have with
cgroup_enable_threaded() is that it does not check to see if the cgroup
parent exists. I thought for a while the first time I saw it, but then
realized that cgroup.type wasn't show in root. I think a comment about
this will make the code less puzzling to causal reader.

Cheers,
Longman



Re: [PATCH] cgroup: remove unnecessary empty check when enabling threaded mode

2017-07-24 Thread Waiman Long
On 07/23/2017 08:18 AM, Tejun Heo wrote:
> cgroup_enable_threaded() checks that the cgroup doesn't have any tasks
> or children and fails the operation if so.  This test is unnecessary
> because the first part is already checked by
> cgroup_can_be_thread_root() and the latter is unnecessary.  The latter
> actually cause a behavioral oddity.  Please consider the following
> hierarchy.  All cgroups are domains.
>
> A
>/ \
>   B   C
>\
> D
>
> If B is made threaded, C and D becomes invalid domains.  Due to the no
> children restriction, threaded mode can't be enabled on C.  For C and
> D, the only thing the user can do is removal.
>
> There is no reason for this restriction.  Remove it.
>
> Signed-off-by: Tejun Heo 
> Cc: Waiman Long 
> ---
> Hello,
>
> So, the only thing inconsistent there was the extra restriction when
> enabling threaded mode when all the necessary conditions are already
> checked by when verifying the parent's domain.
>
> Thanks.
>
>  Documentation/cgroup-v2.txt |5 +++--
>  kernel/cgroup/cgroup.c  |7 ---
>  2 files changed, 3 insertions(+), 9 deletions(-)
>
> --- a/Documentation/cgroup-v2.txt
> +++ b/Documentation/cgroup-v2.txt
> @@ -274,8 +274,9 @@ thread mode, the following conditions mu
>  - As the cgroup will join the parent's resource domain.  The parent
>must either be a valid (threaded) domain or a threaded cgroup.
>  
> -- The cgroup must be empty.  No enabled controllers, child cgroups or
> -  processes.
> +- When the parent is an unthreaded domain, it must not have any domain
> +  controllers enabled or populated domain children.  The root is
> +  exempt from this requirement.
>  
>  Topology-wise, a cgroup can be in an invalid state.  Please consider
>  the following toplogy::
> --- a/kernel/cgroup/cgroup.c
> +++ b/kernel/cgroup/cgroup.c
> @@ -3147,13 +3147,6 @@ static int cgroup_enable_threaded(struct
>   return -EOPNOTSUPP;
>  
>   /*
> -  * Allow enabling thread mode only on empty cgroups to avoid
> -  * implicit migrations and recursive operations.
> -  */
> - if (cgroup_has_tasks(cgrp) || css_has_online_children(>self))
> - return -EBUSY;
> -
> - /*
>* The following shouldn't cause actual migrations and should
>* always succeed.
>*/

Acked-by: Waiman Long 

While you are at it, the one comment that I have with
cgroup_enable_threaded() is that it does not check to see if the cgroup
parent exists. I thought for a while the first time I saw it, but then
realized that cgroup.type wasn't show in root. I think a comment about
this will make the code less puzzling to causal reader.

Cheers,
Longman



Re: [PATCH v2 04/25] dt-bindings: qcom_nandc: change compatible string for EBI2 NANDC

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 05:17:52PM +0530, Abhishek Sahu wrote:
> The current compatible string “qcom,ipq806x-nand" implies that
> the driver is specific to IPQ806x. This driver can be used by
> any chip which uses EBI2 NAND controller so changed the
> compatible string to “qcom,ebi2-nandc” to give it more generic
> name.
> 
> Since there is no user for this driver currently in so
> changing compatible string is safe.
> 
> Signed-off-by: Abhishek Sahu 
> ---
>  Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt 
> b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> index 70dd511..4511918 100644
> --- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> +++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> @@ -1,7 +1,9 @@
>  * Qualcomm NAND controller
>  
>  Required properties:
> -- compatible:should be "qcom,ipq806x-nand"
> +- compatible:should be "qcom,ebi2-nandc" - EBI2 NAND which 
> uses ADM
> + DMA like IPQ8064.

Compatible strings are supposed to be specific to the SoC. The old one 
wasn't quite and the new one moves in the wrong direction.

Rob


Re: [PATCH v2 04/25] dt-bindings: qcom_nandc: change compatible string for EBI2 NANDC

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 05:17:52PM +0530, Abhishek Sahu wrote:
> The current compatible string “qcom,ipq806x-nand" implies that
> the driver is specific to IPQ806x. This driver can be used by
> any chip which uses EBI2 NAND controller so changed the
> compatible string to “qcom,ebi2-nandc” to give it more generic
> name.
> 
> Since there is no user for this driver currently in so
> changing compatible string is safe.
> 
> Signed-off-by: Abhishek Sahu 
> ---
>  Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt 
> b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> index 70dd511..4511918 100644
> --- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> +++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> @@ -1,7 +1,9 @@
>  * Qualcomm NAND controller
>  
>  Required properties:
> -- compatible:should be "qcom,ipq806x-nand"
> +- compatible:should be "qcom,ebi2-nandc" - EBI2 NAND which 
> uses ADM
> + DMA like IPQ8064.

Compatible strings are supposed to be specific to the SoC. The old one 
wasn't quite and the new one moves in the wrong direction.

Rob


Re: [PATCH v2 06/25] dt-bindings: qcom_nandc: remove chip select compatible string

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 05:17:54PM +0530, Abhishek Sahu wrote:
> Currently the compatible “qcom,nandcs” is being used for each
> connected NAND device to support for multiple NAND devices in the
> same bus. The same thing can be achieved by looking reg property
> for each sub nodes which contains the chip select number so this
> patch removes the use of “qcom,nandcs” for specifying NAND device
> sub nodes.
> 
> Since there is no user for this driver currently in so
> changing compatible string is safe.
> 
> Signed-off-by: Abhishek Sahu 
> ---
>  Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 2 --
>  1 file changed, 2 deletions(-)

Acked-by: Rob Herring 


Re: [PATCH v2 06/25] dt-bindings: qcom_nandc: remove chip select compatible string

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 05:17:54PM +0530, Abhishek Sahu wrote:
> Currently the compatible “qcom,nandcs” is being used for each
> connected NAND device to support for multiple NAND devices in the
> same bus. The same thing can be achieved by looking reg property
> for each sub nodes which contains the chip select number so this
> patch removes the use of “qcom,nandcs” for specifying NAND device
> sub nodes.
> 
> Since there is no user for this driver currently in so
> changing compatible string is safe.
> 
> Signed-off-by: Abhishek Sahu 
> ---
>  Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 2 --
>  1 file changed, 2 deletions(-)

Acked-by: Rob Herring 


[RFC Part1 PATCH v3 13/17] x86/io: Unroll string I/O when SEV is active

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

Secure Encrypted Virtualization (SEV) does not support string I/O, so
unroll the string I/O operation into a loop operating on one element at
a time.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/include/asm/io.h | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index e080a39..2f3c002 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -327,14 +327,32 @@ static inline unsigned type in##bwl##_p(int port) 
\
\
 static inline void outs##bwl(int port, const void *addr, unsigned long count) \
 {  \
-   asm volatile("rep; outs" #bwl   \
-: "+S"(addr), "+c"(count) : "d"(port));\
+   if (sev_active()) { \
+   unsigned type *value = (unsigned type *)addr;   \
+   while (count) { \
+   out##bwl(*value, port); \
+   value++;\
+   count--;\
+   }   \
+   } else {\
+   asm volatile("rep; outs" #bwl   \
+: "+S"(addr), "+c"(count) : "d"(port));\
+   }   \
 }  \
\
 static inline void ins##bwl(int port, void *addr, unsigned long count) \
 {  \
-   asm volatile("rep; ins" #bwl\
-: "+D"(addr), "+c"(count) : "d"(port));\
+   if (sev_active()) { \
+   unsigned type *value = (unsigned type *)addr;   \
+   while (count) { \
+   *value = in##bwl(port); \
+   value++;\
+   count--;\
+   }   \
+   } else {\
+   asm volatile("rep; ins" #bwl\
+: "+D"(addr), "+c"(count) : "d"(port));\
+   }   \
 }
 
 BUILDIO(b, b, char)
-- 
2.9.4



[RFC Part1 PATCH v3 13/17] x86/io: Unroll string I/O when SEV is active

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

Secure Encrypted Virtualization (SEV) does not support string I/O, so
unroll the string I/O operation into a loop operating on one element at
a time.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/include/asm/io.h | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index e080a39..2f3c002 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -327,14 +327,32 @@ static inline unsigned type in##bwl##_p(int port) 
\
\
 static inline void outs##bwl(int port, const void *addr, unsigned long count) \
 {  \
-   asm volatile("rep; outs" #bwl   \
-: "+S"(addr), "+c"(count) : "d"(port));\
+   if (sev_active()) { \
+   unsigned type *value = (unsigned type *)addr;   \
+   while (count) { \
+   out##bwl(*value, port); \
+   value++;\
+   count--;\
+   }   \
+   } else {\
+   asm volatile("rep; outs" #bwl   \
+: "+S"(addr), "+c"(count) : "d"(port));\
+   }   \
 }  \
\
 static inline void ins##bwl(int port, void *addr, unsigned long count) \
 {  \
-   asm volatile("rep; ins" #bwl\
-: "+D"(addr), "+c"(count) : "d"(port));\
+   if (sev_active()) { \
+   unsigned type *value = (unsigned type *)addr;   \
+   while (count) { \
+   *value = in##bwl(port); \
+   value++;\
+   count--;\
+   }   \
+   } else {\
+   asm volatile("rep; ins" #bwl\
+: "+D"(addr), "+c"(count) : "d"(port));\
+   }   \
 }
 
 BUILDIO(b, b, char)
-- 
2.9.4



[RFC Part1 PATCH v3 14/17] x86/boot: Add early boot support when running with SEV active

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

Early in the boot process, add checks to determine if the kernel is
running with Secure Encrypted Virtualization (SEV) active.

Checking for SEV requires checking that the kernel is running under a
hypervisor (CPUID 0x0001, bit 31), that the SEV feature is available
(CPUID 0x801f, bit 1) and then check a non-interceptable SEV MSR
(0xc0010131, bit 0).

This check is required so that during early compressed kernel booting the
pagetables (both the boot pagetables and KASLR pagetables (if enabled) are
updated to include the encryption mask so that when the kernel is
decompressed into encrypted memory.

After the kernel is decompressed and continues booting the same logic is
used to check if SEV is active and set a flag indicating so.  This allows
us to distinguish between SME and SEV, each of which have unique
differences in how certain things are handled: e.g. DMA (always bounce
buffered with SEV) or EFI tables (always access decrypted with SME).

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/boot/compressed/Makefile  |   2 +
 arch/x86/boot/compressed/head_64.S |  16 +
 arch/x86/boot/compressed/mem_encrypt.S | 103 +
 arch/x86/boot/compressed/misc.h|   2 +
 arch/x86/boot/compressed/pagetable.c   |   8 ++-
 arch/x86/include/asm/mem_encrypt.h |   3 +
 arch/x86/include/asm/msr-index.h   |   3 +
 arch/x86/include/uapi/asm/kvm_para.h   |   1 -
 arch/x86/mm/mem_encrypt.c  |  42 +++---
 9 files changed, 169 insertions(+), 11 deletions(-)
 create mode 100644 arch/x86/boot/compressed/mem_encrypt.S

diff --git a/arch/x86/boot/compressed/Makefile 
b/arch/x86/boot/compressed/Makefile
index 2c860ad..d2fe901 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -72,6 +72,8 @@ vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/head_$(BITS).o 
$(obj)/misc.o \
$(obj)/string.o $(obj)/cmdline.o $(obj)/error.o \
$(obj)/piggy.o $(obj)/cpuflags.o
 
+vmlinux-objs-$(CONFIG_X86_64) += $(obj)/mem_encrypt.o
+
 vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $(obj)/early_serial_console.o
 vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o
 ifdef CONFIG_X86_64
diff --git a/arch/x86/boot/compressed/head_64.S 
b/arch/x86/boot/compressed/head_64.S
index fbf4c32..6179d43 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -130,6 +130,19 @@ ENTRY(startup_32)
  /*
   * Build early 4G boot pagetable
   */
+   /*
+* If SEV is active then set the encryption mask in the page tables.
+* This will insure that when the kernel is copied and decompressed
+* it will be done so encrypted.
+*/
+   callget_sev_encryption_bit
+   xorl%edx, %edx
+   testl   %eax, %eax
+   jz  1f
+   subl$32, %eax   /* Encryption bit is always above bit 31 */
+   bts %eax, %edx  /* Set encryption mask for page tables */
+1:
+
/* Initialize Page tables to 0 */
lealpgtable(%ebx), %edi
xorl%eax, %eax
@@ -140,12 +153,14 @@ ENTRY(startup_32)
lealpgtable + 0(%ebx), %edi
leal0x1007 (%edi), %eax
movl%eax, 0(%edi)
+   addl%edx, 4(%edi)
 
/* Build Level 3 */
lealpgtable + 0x1000(%ebx), %edi
leal0x1007(%edi), %eax
movl$4, %ecx
 1: movl%eax, 0x00(%edi)
+   addl%edx, 0x04(%edi)
addl$0x1000, %eax
addl$8, %edi
decl%ecx
@@ -156,6 +171,7 @@ ENTRY(startup_32)
movl$0x0183, %eax
movl$2048, %ecx
 1: movl%eax, 0(%edi)
+   addl%edx, 4(%edi)
addl$0x0020, %eax
addl$8, %edi
decl%ecx
diff --git a/arch/x86/boot/compressed/mem_encrypt.S 
b/arch/x86/boot/compressed/mem_encrypt.S
new file mode 100644
index 000..696716e
--- /dev/null
+++ b/arch/x86/boot/compressed/mem_encrypt.S
@@ -0,0 +1,103 @@
+/*
+ * AMD Memory Encryption Support
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+   .text
+   .code32
+ENTRY(get_sev_encryption_bit)
+   xor %eax, %eax
+
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+   push%ebx
+   push%ecx
+   push%edx
+
+   /* Check if running under a hypervisor */
+   movl$1, %eax
+   cpuid
+   bt  $31, %ecx   /* Check the hypervisor bit */
+   jnc .Lno_sev
+
+   movl$0x8000, %eax   /* CPUID to check the highest leaf */
+   cpuid
+   cmpl$0x801f, %eax

[RFC Part1 PATCH v3 14/17] x86/boot: Add early boot support when running with SEV active

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

Early in the boot process, add checks to determine if the kernel is
running with Secure Encrypted Virtualization (SEV) active.

Checking for SEV requires checking that the kernel is running under a
hypervisor (CPUID 0x0001, bit 31), that the SEV feature is available
(CPUID 0x801f, bit 1) and then check a non-interceptable SEV MSR
(0xc0010131, bit 0).

This check is required so that during early compressed kernel booting the
pagetables (both the boot pagetables and KASLR pagetables (if enabled) are
updated to include the encryption mask so that when the kernel is
decompressed into encrypted memory.

After the kernel is decompressed and continues booting the same logic is
used to check if SEV is active and set a flag indicating so.  This allows
us to distinguish between SME and SEV, each of which have unique
differences in how certain things are handled: e.g. DMA (always bounce
buffered with SEV) or EFI tables (always access decrypted with SME).

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/boot/compressed/Makefile  |   2 +
 arch/x86/boot/compressed/head_64.S |  16 +
 arch/x86/boot/compressed/mem_encrypt.S | 103 +
 arch/x86/boot/compressed/misc.h|   2 +
 arch/x86/boot/compressed/pagetable.c   |   8 ++-
 arch/x86/include/asm/mem_encrypt.h |   3 +
 arch/x86/include/asm/msr-index.h   |   3 +
 arch/x86/include/uapi/asm/kvm_para.h   |   1 -
 arch/x86/mm/mem_encrypt.c  |  42 +++---
 9 files changed, 169 insertions(+), 11 deletions(-)
 create mode 100644 arch/x86/boot/compressed/mem_encrypt.S

diff --git a/arch/x86/boot/compressed/Makefile 
b/arch/x86/boot/compressed/Makefile
index 2c860ad..d2fe901 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -72,6 +72,8 @@ vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/head_$(BITS).o 
$(obj)/misc.o \
$(obj)/string.o $(obj)/cmdline.o $(obj)/error.o \
$(obj)/piggy.o $(obj)/cpuflags.o
 
+vmlinux-objs-$(CONFIG_X86_64) += $(obj)/mem_encrypt.o
+
 vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $(obj)/early_serial_console.o
 vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o
 ifdef CONFIG_X86_64
diff --git a/arch/x86/boot/compressed/head_64.S 
b/arch/x86/boot/compressed/head_64.S
index fbf4c32..6179d43 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -130,6 +130,19 @@ ENTRY(startup_32)
  /*
   * Build early 4G boot pagetable
   */
+   /*
+* If SEV is active then set the encryption mask in the page tables.
+* This will insure that when the kernel is copied and decompressed
+* it will be done so encrypted.
+*/
+   callget_sev_encryption_bit
+   xorl%edx, %edx
+   testl   %eax, %eax
+   jz  1f
+   subl$32, %eax   /* Encryption bit is always above bit 31 */
+   bts %eax, %edx  /* Set encryption mask for page tables */
+1:
+
/* Initialize Page tables to 0 */
lealpgtable(%ebx), %edi
xorl%eax, %eax
@@ -140,12 +153,14 @@ ENTRY(startup_32)
lealpgtable + 0(%ebx), %edi
leal0x1007 (%edi), %eax
movl%eax, 0(%edi)
+   addl%edx, 4(%edi)
 
/* Build Level 3 */
lealpgtable + 0x1000(%ebx), %edi
leal0x1007(%edi), %eax
movl$4, %ecx
 1: movl%eax, 0x00(%edi)
+   addl%edx, 0x04(%edi)
addl$0x1000, %eax
addl$8, %edi
decl%ecx
@@ -156,6 +171,7 @@ ENTRY(startup_32)
movl$0x0183, %eax
movl$2048, %ecx
 1: movl%eax, 0(%edi)
+   addl%edx, 4(%edi)
addl$0x0020, %eax
addl$8, %edi
decl%ecx
diff --git a/arch/x86/boot/compressed/mem_encrypt.S 
b/arch/x86/boot/compressed/mem_encrypt.S
new file mode 100644
index 000..696716e
--- /dev/null
+++ b/arch/x86/boot/compressed/mem_encrypt.S
@@ -0,0 +1,103 @@
+/*
+ * AMD Memory Encryption Support
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+   .text
+   .code32
+ENTRY(get_sev_encryption_bit)
+   xor %eax, %eax
+
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+   push%ebx
+   push%ecx
+   push%edx
+
+   /* Check if running under a hypervisor */
+   movl$1, %eax
+   cpuid
+   bt  $31, %ecx   /* Check the hypervisor bit */
+   jnc .Lno_sev
+
+   movl$0x8000, %eax   /* CPUID to check the highest leaf */
+   cpuid
+   cmpl$0x801f, %eax   /* See if 0x801f is available */
+   jb  .Lno_sev
+
+   /*
+* Check 

[RFC Part1 PATCH v3 15/17] x86: Add support for changing memory encryption attribute in early boot

2017-07-24 Thread Brijesh Singh
Some KVM-specific custom MSRs shares the guest physical address with
hypervisor. When SEV is active, the shared physical address must be mapped
with encryption attribute cleared so that both hypervsior and guest can
access the data.

Add APIs to change memory encryption attribute in early boot code.

Signed-off-by: Brijesh Singh 
---
 arch/x86/include/asm/mem_encrypt.h |  17 ++
 arch/x86/mm/mem_encrypt.c  | 117 +
 2 files changed, 134 insertions(+)

diff --git a/arch/x86/include/asm/mem_encrypt.h 
b/arch/x86/include/asm/mem_encrypt.h
index 9cb6472..30b539e 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -46,6 +46,11 @@ void __init sme_early_init(void);
 void __init sme_encrypt_kernel(void);
 void __init sme_enable(struct boot_params *bp);
 
+int __init early_set_memory_decrypted(resource_size_t paddr,
+ unsigned long size);
+int __init early_set_memory_encrypted(resource_size_t paddr,
+ unsigned long size);
+
 /* Architecture __weak replacement functions */
 void __init mem_encrypt_init(void);
 
@@ -69,6 +74,18 @@ static inline void __init sme_early_init(void) { }
 static inline void __init sme_encrypt_kernel(void) { }
 static inline void __init sme_enable(struct boot_params *bp) { }
 
+static inline int __init early_set_memory_decrypted(resource_size_t paddr,
+   unsigned long size)
+{
+   return 0;
+}
+
+static inline int __init early_set_memory_encrypted(resource_size_t paddr,
+   unsigned long size)
+{
+   return 0;
+}
+
 #endif /* CONFIG_AMD_MEM_ENCRYPT */
 
 /*
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index ed8780e..d174b1c 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -28,6 +28,8 @@
 #include 
 #include 
 
+#include "mm_internal.h"
+
 static char sme_cmdline_arg[] __initdata = "mem_encrypt";
 static char sme_cmdline_on[]  __initdata = "on";
 static char sme_cmdline_off[] __initdata = "off";
@@ -257,6 +259,121 @@ static void sme_free(struct device *dev, size_t size, 
void *vaddr,
swiotlb_free_coherent(dev, size, vaddr, dma_handle);
 }
 
+static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
+{
+   pgprot_t old_prot, new_prot;
+   unsigned long pfn;
+   pte_t new_pte;
+
+   switch (level) {
+   case PG_LEVEL_4K:
+   pfn = pte_pfn(*kpte);
+   old_prot = pte_pgprot(*kpte);
+   break;
+   case PG_LEVEL_2M:
+   pfn = pmd_pfn(*(pmd_t *)kpte);
+   old_prot = pmd_pgprot(*(pmd_t *)kpte);
+   break;
+   case PG_LEVEL_1G:
+   pfn = pud_pfn(*(pud_t *)kpte);
+   old_prot = pud_pgprot(*(pud_t *)kpte);
+   break;
+   default:
+   return;
+   }
+
+   new_prot = old_prot;
+   if (enc)
+   pgprot_val(new_prot) |= _PAGE_ENC;
+   else
+   pgprot_val(new_prot) &= ~_PAGE_ENC;
+
+   /* if prot is same then do nothing */
+   if (pgprot_val(old_prot) == pgprot_val(new_prot))
+   return;
+
+   new_pte = pfn_pte(pfn, new_prot);
+   set_pte_atomic(kpte, new_pte);
+}
+
+static int __init early_set_memory_enc_dec(resource_size_t paddr,
+  unsigned long size, bool enc)
+{
+   unsigned long vaddr, vaddr_end, vaddr_next;
+   unsigned long psize, pmask;
+   int split_page_size_mask;
+   pte_t *kpte;
+   int level;
+
+   vaddr = (unsigned long)__va(paddr);
+   vaddr_next = vaddr;
+   vaddr_end = vaddr + size;
+
+   /*
+* We are going to change the physical page attribute from C=1 to C=0
+* or vice versa. Flush the caches to ensure that data is written into
+* memory with correct C-bit before we change attribute.
+*/
+   clflush_cache_range(__va(paddr), size);
+
+   for (; vaddr < vaddr_end; vaddr = vaddr_next) {
+   kpte = lookup_address(vaddr, );
+   if (!kpte || pte_none(*kpte))
+   return 1;
+
+   if (level == PG_LEVEL_4K) {
+   __set_clr_pte_enc(kpte, level, enc);
+   vaddr_next = (vaddr & PAGE_MASK) + PAGE_SIZE;
+   continue;
+   }
+
+   psize = page_level_size(level);
+   pmask = page_level_mask(level);
+
+   /*
+* Check, whether we can change the large page in one go.
+* We request a split, when the address is not aligned and
+* the number of pages to set/clear encryption bit is smaller
+* than the number of pages in the large page.
+*/
+   if (vaddr == (vaddr & pmask) &&
+   

[RFC Part1 PATCH v3 15/17] x86: Add support for changing memory encryption attribute in early boot

2017-07-24 Thread Brijesh Singh
Some KVM-specific custom MSRs shares the guest physical address with
hypervisor. When SEV is active, the shared physical address must be mapped
with encryption attribute cleared so that both hypervsior and guest can
access the data.

Add APIs to change memory encryption attribute in early boot code.

Signed-off-by: Brijesh Singh 
---
 arch/x86/include/asm/mem_encrypt.h |  17 ++
 arch/x86/mm/mem_encrypt.c  | 117 +
 2 files changed, 134 insertions(+)

diff --git a/arch/x86/include/asm/mem_encrypt.h 
b/arch/x86/include/asm/mem_encrypt.h
index 9cb6472..30b539e 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -46,6 +46,11 @@ void __init sme_early_init(void);
 void __init sme_encrypt_kernel(void);
 void __init sme_enable(struct boot_params *bp);
 
+int __init early_set_memory_decrypted(resource_size_t paddr,
+ unsigned long size);
+int __init early_set_memory_encrypted(resource_size_t paddr,
+ unsigned long size);
+
 /* Architecture __weak replacement functions */
 void __init mem_encrypt_init(void);
 
@@ -69,6 +74,18 @@ static inline void __init sme_early_init(void) { }
 static inline void __init sme_encrypt_kernel(void) { }
 static inline void __init sme_enable(struct boot_params *bp) { }
 
+static inline int __init early_set_memory_decrypted(resource_size_t paddr,
+   unsigned long size)
+{
+   return 0;
+}
+
+static inline int __init early_set_memory_encrypted(resource_size_t paddr,
+   unsigned long size)
+{
+   return 0;
+}
+
 #endif /* CONFIG_AMD_MEM_ENCRYPT */
 
 /*
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index ed8780e..d174b1c 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -28,6 +28,8 @@
 #include 
 #include 
 
+#include "mm_internal.h"
+
 static char sme_cmdline_arg[] __initdata = "mem_encrypt";
 static char sme_cmdline_on[]  __initdata = "on";
 static char sme_cmdline_off[] __initdata = "off";
@@ -257,6 +259,121 @@ static void sme_free(struct device *dev, size_t size, 
void *vaddr,
swiotlb_free_coherent(dev, size, vaddr, dma_handle);
 }
 
+static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
+{
+   pgprot_t old_prot, new_prot;
+   unsigned long pfn;
+   pte_t new_pte;
+
+   switch (level) {
+   case PG_LEVEL_4K:
+   pfn = pte_pfn(*kpte);
+   old_prot = pte_pgprot(*kpte);
+   break;
+   case PG_LEVEL_2M:
+   pfn = pmd_pfn(*(pmd_t *)kpte);
+   old_prot = pmd_pgprot(*(pmd_t *)kpte);
+   break;
+   case PG_LEVEL_1G:
+   pfn = pud_pfn(*(pud_t *)kpte);
+   old_prot = pud_pgprot(*(pud_t *)kpte);
+   break;
+   default:
+   return;
+   }
+
+   new_prot = old_prot;
+   if (enc)
+   pgprot_val(new_prot) |= _PAGE_ENC;
+   else
+   pgprot_val(new_prot) &= ~_PAGE_ENC;
+
+   /* if prot is same then do nothing */
+   if (pgprot_val(old_prot) == pgprot_val(new_prot))
+   return;
+
+   new_pte = pfn_pte(pfn, new_prot);
+   set_pte_atomic(kpte, new_pte);
+}
+
+static int __init early_set_memory_enc_dec(resource_size_t paddr,
+  unsigned long size, bool enc)
+{
+   unsigned long vaddr, vaddr_end, vaddr_next;
+   unsigned long psize, pmask;
+   int split_page_size_mask;
+   pte_t *kpte;
+   int level;
+
+   vaddr = (unsigned long)__va(paddr);
+   vaddr_next = vaddr;
+   vaddr_end = vaddr + size;
+
+   /*
+* We are going to change the physical page attribute from C=1 to C=0
+* or vice versa. Flush the caches to ensure that data is written into
+* memory with correct C-bit before we change attribute.
+*/
+   clflush_cache_range(__va(paddr), size);
+
+   for (; vaddr < vaddr_end; vaddr = vaddr_next) {
+   kpte = lookup_address(vaddr, );
+   if (!kpte || pte_none(*kpte))
+   return 1;
+
+   if (level == PG_LEVEL_4K) {
+   __set_clr_pte_enc(kpte, level, enc);
+   vaddr_next = (vaddr & PAGE_MASK) + PAGE_SIZE;
+   continue;
+   }
+
+   psize = page_level_size(level);
+   pmask = page_level_mask(level);
+
+   /*
+* Check, whether we can change the large page in one go.
+* We request a split, when the address is not aligned and
+* the number of pages to set/clear encryption bit is smaller
+* than the number of pages in the large page.
+*/
+   if (vaddr == (vaddr & pmask) &&
+   

[RFC Part1 PATCH v3 16/17] X86/KVM: Provide support to create Guest and HV shared per-CPU variables

2017-07-24 Thread Brijesh Singh
Some KVM specific MSR's (steal-time, asyncpf, avic_eio) allocates per-CPU
variable at compile time and share its physical address with hypervisor.
It presents a challege when SEV is active in guest OS, when SEV is active,
the guest memory is encrypted with guest key hence hypervisor will not
able to modify the guest memory. When SEV is active, we need to clear the
encryption attribute (aka C-bit) of shared physical addresses so that both
guest and hypervisor can access the data.

To solve this problem, I have tried these three options:

1) Convert the static per-CPU to dynamic per-CPU allocation and when SEV
is detected clear the C-bit from the page table. But while doing so I
found that per-CPU dynamic allocator was not ready when kvm_guest_cpu_init
was called.

2) Since the C-bit works on PAGE_SIZE hence add some extra padding to
'struct kvm-steal-time' to make it PAGE_SIZE and then at runtime
clear the encryption attribute of the full PAGE. The downside of this -
we need to modify structure which may break the compatibility.

3) Define a new per-CPU section (.data..percpu.hv_shared) which will be
used to hold the compile time shared per-CPU variables. When SEV is
detected we map this section without C-bit.

This patch implements #3. It introduces a new DEFINE_PER_CPU_HV_SHAHRED
macro to create a compile time per-CPU variable. When SEV is detected we
clear the C-bit from the shared per-CPU variable.

Signed-off-by: Brijesh Singh 
---
 arch/x86/kernel/kvm.c | 46 ---
 include/asm-generic/vmlinux.lds.h |  3 +++
 include/linux/percpu-defs.h   | 12 ++
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 71c17a5..1f6fec8 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -75,8 +75,8 @@ static int parse_no_kvmclock_vsyscall(char *arg)
 
 early_param("no-kvmclock-vsyscall", parse_no_kvmclock_vsyscall);
 
-static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64);
-static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);
+static DEFINE_PER_CPU_HV_SHARED(struct kvm_vcpu_pv_apf_data, apf_reason) 
__aligned(64);
+static DEFINE_PER_CPU_HV_SHARED(struct kvm_steal_time, steal_time) 
__aligned(64);
 static int has_steal_clock = 0;
 
 /*
@@ -303,7 +303,7 @@ static void kvm_register_steal_time(void)
cpu, (unsigned long long) slow_virt_to_phys(st));
 }
 
-static DEFINE_PER_CPU(unsigned long, kvm_apic_eoi) = KVM_PV_EOI_DISABLED;
+static DEFINE_PER_CPU_HV_SHARED(unsigned long, kvm_apic_eoi) = 
KVM_PV_EOI_DISABLED;
 
 static notrace void kvm_guest_apic_eoi_write(u32 reg, u32 val)
 {
@@ -319,11 +319,51 @@ static notrace void kvm_guest_apic_eoi_write(u32 reg, u32 
val)
apic->native_eoi_write(APIC_EOI, APIC_EOI_ACK);
 }
 
+/* NOTE: function is marked as __ref because it is used by __init functions */
+static int __ref kvm_map_hv_shared_decrypted(void)
+{
+   static int once, ret;
+   int cpu;
+
+   if (once)
+   return ret;
+
+   /*
+* Iterate through all possible CPU's and clear the C-bit from
+* percpu variables.
+*/
+   for_each_possible_cpu(cpu) {
+   struct kvm_vcpu_pv_apf_data *apf;
+   unsigned long pa;
+
+   apf = _cpu(apf_reason, cpu);
+   pa = slow_virt_to_phys(apf);
+   sme_early_decrypt(pa & PAGE_MASK, PAGE_SIZE);
+   ret = early_set_memory_decrypted(pa, PAGE_SIZE);
+   if (ret)
+   break;
+   }
+
+   once = 1;
+   return ret;
+}
+
 static void kvm_guest_cpu_init(void)
 {
if (!kvm_para_available())
return;
 
+   /*
+* When SEV is active, map the shared percpu as unencrypted so that
+* both guest and hypervsior can access the data.
+*/
+   if (sev_active()) {
+   if (kvm_map_hv_shared_decrypted()) {
+   printk(KERN_ERR "Failed to map percpu as 
unencrypted\n");
+   return;
+   }
+   }
+
if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) {
u64 pa = slow_virt_to_phys(this_cpu_ptr(_reason));
 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index da0be9a..52854cf 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -783,6 +783,9 @@
. = ALIGN(cacheline);   \
*(.data..percpu)\
*(.data..percpu..shared_aligned)\
+   . = ALIGN(PAGE_SIZE);   \
+   *(.data..percpu..hv_shared) \
+   . = ALIGN(PAGE_SIZE);   \
VMLINUX_SYMBOL(__per_cpu_end) = .;
 
 

[RFC Part1 PATCH v3 16/17] X86/KVM: Provide support to create Guest and HV shared per-CPU variables

2017-07-24 Thread Brijesh Singh
Some KVM specific MSR's (steal-time, asyncpf, avic_eio) allocates per-CPU
variable at compile time and share its physical address with hypervisor.
It presents a challege when SEV is active in guest OS, when SEV is active,
the guest memory is encrypted with guest key hence hypervisor will not
able to modify the guest memory. When SEV is active, we need to clear the
encryption attribute (aka C-bit) of shared physical addresses so that both
guest and hypervisor can access the data.

To solve this problem, I have tried these three options:

1) Convert the static per-CPU to dynamic per-CPU allocation and when SEV
is detected clear the C-bit from the page table. But while doing so I
found that per-CPU dynamic allocator was not ready when kvm_guest_cpu_init
was called.

2) Since the C-bit works on PAGE_SIZE hence add some extra padding to
'struct kvm-steal-time' to make it PAGE_SIZE and then at runtime
clear the encryption attribute of the full PAGE. The downside of this -
we need to modify structure which may break the compatibility.

3) Define a new per-CPU section (.data..percpu.hv_shared) which will be
used to hold the compile time shared per-CPU variables. When SEV is
detected we map this section without C-bit.

This patch implements #3. It introduces a new DEFINE_PER_CPU_HV_SHAHRED
macro to create a compile time per-CPU variable. When SEV is detected we
clear the C-bit from the shared per-CPU variable.

Signed-off-by: Brijesh Singh 
---
 arch/x86/kernel/kvm.c | 46 ---
 include/asm-generic/vmlinux.lds.h |  3 +++
 include/linux/percpu-defs.h   | 12 ++
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 71c17a5..1f6fec8 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -75,8 +75,8 @@ static int parse_no_kvmclock_vsyscall(char *arg)
 
 early_param("no-kvmclock-vsyscall", parse_no_kvmclock_vsyscall);
 
-static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64);
-static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);
+static DEFINE_PER_CPU_HV_SHARED(struct kvm_vcpu_pv_apf_data, apf_reason) 
__aligned(64);
+static DEFINE_PER_CPU_HV_SHARED(struct kvm_steal_time, steal_time) 
__aligned(64);
 static int has_steal_clock = 0;
 
 /*
@@ -303,7 +303,7 @@ static void kvm_register_steal_time(void)
cpu, (unsigned long long) slow_virt_to_phys(st));
 }
 
-static DEFINE_PER_CPU(unsigned long, kvm_apic_eoi) = KVM_PV_EOI_DISABLED;
+static DEFINE_PER_CPU_HV_SHARED(unsigned long, kvm_apic_eoi) = 
KVM_PV_EOI_DISABLED;
 
 static notrace void kvm_guest_apic_eoi_write(u32 reg, u32 val)
 {
@@ -319,11 +319,51 @@ static notrace void kvm_guest_apic_eoi_write(u32 reg, u32 
val)
apic->native_eoi_write(APIC_EOI, APIC_EOI_ACK);
 }
 
+/* NOTE: function is marked as __ref because it is used by __init functions */
+static int __ref kvm_map_hv_shared_decrypted(void)
+{
+   static int once, ret;
+   int cpu;
+
+   if (once)
+   return ret;
+
+   /*
+* Iterate through all possible CPU's and clear the C-bit from
+* percpu variables.
+*/
+   for_each_possible_cpu(cpu) {
+   struct kvm_vcpu_pv_apf_data *apf;
+   unsigned long pa;
+
+   apf = _cpu(apf_reason, cpu);
+   pa = slow_virt_to_phys(apf);
+   sme_early_decrypt(pa & PAGE_MASK, PAGE_SIZE);
+   ret = early_set_memory_decrypted(pa, PAGE_SIZE);
+   if (ret)
+   break;
+   }
+
+   once = 1;
+   return ret;
+}
+
 static void kvm_guest_cpu_init(void)
 {
if (!kvm_para_available())
return;
 
+   /*
+* When SEV is active, map the shared percpu as unencrypted so that
+* both guest and hypervsior can access the data.
+*/
+   if (sev_active()) {
+   if (kvm_map_hv_shared_decrypted()) {
+   printk(KERN_ERR "Failed to map percpu as 
unencrypted\n");
+   return;
+   }
+   }
+
if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) {
u64 pa = slow_virt_to_phys(this_cpu_ptr(_reason));
 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index da0be9a..52854cf 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -783,6 +783,9 @@
. = ALIGN(cacheline);   \
*(.data..percpu)\
*(.data..percpu..shared_aligned)\
+   . = ALIGN(PAGE_SIZE);   \
+   *(.data..percpu..hv_shared) \
+   . = ALIGN(PAGE_SIZE);   \
VMLINUX_SYMBOL(__per_cpu_end) = .;
 
 /**
diff --git 

[RFC Part1 PATCH v3 17/17] X86/KVM: Clear encryption attribute when SEV is active

2017-07-24 Thread Brijesh Singh
The guest physical memory area holding the struct pvclock_wall_clock and
struct pvclock_vcpu_time_info are shared with the hypervisor. Hypervisor
periodically updates the contents of the memory. When SEV is active, we
must clear the encryption attributes from the shared memory pages so that
both hypervisor and guest can access the data.

Signed-off-by: Brijesh Singh 
---
 arch/x86/entry/vdso/vma.c  |  5 ++--
 arch/x86/kernel/kvmclock.c | 64 +++---
 2 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 726355c..ff50251 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -114,10 +114,11 @@ static int vvar_fault(const struct vm_special_mapping *sm,
struct pvclock_vsyscall_time_info *pvti =
pvclock_pvti_cpu0_va();
if (pvti && vclock_was_used(VCLOCK_PVCLOCK)) {
-   ret = vm_insert_pfn(
+   ret = vm_insert_pfn_prot(
vma,
vmf->address,
-   __pa(pvti) >> PAGE_SHIFT);
+   __pa(pvti) >> PAGE_SHIFT,
+   pgprot_decrypted(vma->vm_page_prot));
}
} else if (sym_offset == image->sym_hvclock_page) {
struct ms_hyperv_tsc_page *tsc_pg = hv_get_tsc_page();
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index d889676..f3a8101 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -45,7 +46,7 @@ early_param("no-kvmclock", parse_no_kvmclock);
 
 /* The hypervisor will put information about time periodically here */
 static struct pvclock_vsyscall_time_info *hv_clock;
-static struct pvclock_wall_clock wall_clock;
+static struct pvclock_wall_clock *wall_clock;
 
 struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void)
 {
@@ -64,15 +65,18 @@ static void kvm_get_wallclock(struct timespec *now)
int low, high;
int cpu;
 
-   low = (int)__pa_symbol(_clock);
-   high = ((u64)__pa_symbol(_clock) >> 32);
+   if (!wall_clock)
+   return;
+
+   low = (int)slow_virt_to_phys(wall_clock);
+   high = ((u64)slow_virt_to_phys(wall_clock) >> 32);
 
native_write_msr(msr_kvm_wall_clock, low, high);
 
cpu = get_cpu();
 
vcpu_time = _clock[cpu].pvti;
-   pvclock_read_wallclock(_clock, vcpu_time, now);
+   pvclock_read_wallclock(wall_clock, vcpu_time, now);
 
put_cpu();
 }
@@ -249,11 +253,39 @@ static void kvm_shutdown(void)
native_machine_shutdown();
 }
 
+static phys_addr_t __init kvm_memblock_alloc(phys_addr_t size,
+phys_addr_t align)
+{
+   phys_addr_t mem;
+
+   mem = memblock_alloc(size, align);
+   if (!mem)
+   return 0;
+
+   if (sev_active()) {
+   if (early_set_memory_decrypted(mem, size))
+   goto e_free;
+   }
+
+   return mem;
+e_free:
+   memblock_free(mem, size);
+   return 0;
+}
+
+static void __init kvm_memblock_free(phys_addr_t addr, phys_addr_t size)
+{
+   if (sev_active())
+   early_set_memory_encrypted(addr, size);
+
+   memblock_free(addr, size);
+}
+
 void __init kvmclock_init(void)
 {
struct pvclock_vcpu_time_info *vcpu_time;
-   unsigned long mem;
-   int size, cpu;
+   unsigned long mem, mem_wall_clock;
+   int size, cpu, wall_clock_size;
u8 flags;
 
size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS);
@@ -270,15 +302,29 @@ void __init kvmclock_init(void)
printk(KERN_INFO "kvm-clock: Using msrs %x and %x",
msr_kvm_system_time, msr_kvm_wall_clock);
 
-   mem = memblock_alloc(size, PAGE_SIZE);
-   if (!mem)
+   wall_clock_size = PAGE_ALIGN(sizeof(struct pvclock_wall_clock));
+   mem_wall_clock = kvm_memblock_alloc(wall_clock_size, PAGE_SIZE);
+   if (!mem_wall_clock)
return;
+
+   wall_clock = __va(mem_wall_clock);
+   memset(wall_clock, 0, wall_clock_size);
+
+   mem = kvm_memblock_alloc(size, PAGE_SIZE);
+   if (!mem) {
+   kvm_memblock_free(mem_wall_clock, wall_clock_size);
+   wall_clock = NULL;
+   return;
+   }
+
hv_clock = __va(mem);
memset(hv_clock, 0, size);
 
if (kvm_register_clock("primary cpu clock")) {
hv_clock = NULL;
-   memblock_free(mem, size);
+   kvm_memblock_free(mem, size);
+   kvm_memblock_free(mem_wall_clock, wall_clock_size);
+   wall_clock = NULL;
return;
}
 
-- 
2.9.4



[RFC Part1 PATCH v3 17/17] X86/KVM: Clear encryption attribute when SEV is active

2017-07-24 Thread Brijesh Singh
The guest physical memory area holding the struct pvclock_wall_clock and
struct pvclock_vcpu_time_info are shared with the hypervisor. Hypervisor
periodically updates the contents of the memory. When SEV is active, we
must clear the encryption attributes from the shared memory pages so that
both hypervisor and guest can access the data.

Signed-off-by: Brijesh Singh 
---
 arch/x86/entry/vdso/vma.c  |  5 ++--
 arch/x86/kernel/kvmclock.c | 64 +++---
 2 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 726355c..ff50251 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -114,10 +114,11 @@ static int vvar_fault(const struct vm_special_mapping *sm,
struct pvclock_vsyscall_time_info *pvti =
pvclock_pvti_cpu0_va();
if (pvti && vclock_was_used(VCLOCK_PVCLOCK)) {
-   ret = vm_insert_pfn(
+   ret = vm_insert_pfn_prot(
vma,
vmf->address,
-   __pa(pvti) >> PAGE_SHIFT);
+   __pa(pvti) >> PAGE_SHIFT,
+   pgprot_decrypted(vma->vm_page_prot));
}
} else if (sym_offset == image->sym_hvclock_page) {
struct ms_hyperv_tsc_page *tsc_pg = hv_get_tsc_page();
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index d889676..f3a8101 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -45,7 +46,7 @@ early_param("no-kvmclock", parse_no_kvmclock);
 
 /* The hypervisor will put information about time periodically here */
 static struct pvclock_vsyscall_time_info *hv_clock;
-static struct pvclock_wall_clock wall_clock;
+static struct pvclock_wall_clock *wall_clock;
 
 struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void)
 {
@@ -64,15 +65,18 @@ static void kvm_get_wallclock(struct timespec *now)
int low, high;
int cpu;
 
-   low = (int)__pa_symbol(_clock);
-   high = ((u64)__pa_symbol(_clock) >> 32);
+   if (!wall_clock)
+   return;
+
+   low = (int)slow_virt_to_phys(wall_clock);
+   high = ((u64)slow_virt_to_phys(wall_clock) >> 32);
 
native_write_msr(msr_kvm_wall_clock, low, high);
 
cpu = get_cpu();
 
vcpu_time = _clock[cpu].pvti;
-   pvclock_read_wallclock(_clock, vcpu_time, now);
+   pvclock_read_wallclock(wall_clock, vcpu_time, now);
 
put_cpu();
 }
@@ -249,11 +253,39 @@ static void kvm_shutdown(void)
native_machine_shutdown();
 }
 
+static phys_addr_t __init kvm_memblock_alloc(phys_addr_t size,
+phys_addr_t align)
+{
+   phys_addr_t mem;
+
+   mem = memblock_alloc(size, align);
+   if (!mem)
+   return 0;
+
+   if (sev_active()) {
+   if (early_set_memory_decrypted(mem, size))
+   goto e_free;
+   }
+
+   return mem;
+e_free:
+   memblock_free(mem, size);
+   return 0;
+}
+
+static void __init kvm_memblock_free(phys_addr_t addr, phys_addr_t size)
+{
+   if (sev_active())
+   early_set_memory_encrypted(addr, size);
+
+   memblock_free(addr, size);
+}
+
 void __init kvmclock_init(void)
 {
struct pvclock_vcpu_time_info *vcpu_time;
-   unsigned long mem;
-   int size, cpu;
+   unsigned long mem, mem_wall_clock;
+   int size, cpu, wall_clock_size;
u8 flags;
 
size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS);
@@ -270,15 +302,29 @@ void __init kvmclock_init(void)
printk(KERN_INFO "kvm-clock: Using msrs %x and %x",
msr_kvm_system_time, msr_kvm_wall_clock);
 
-   mem = memblock_alloc(size, PAGE_SIZE);
-   if (!mem)
+   wall_clock_size = PAGE_ALIGN(sizeof(struct pvclock_wall_clock));
+   mem_wall_clock = kvm_memblock_alloc(wall_clock_size, PAGE_SIZE);
+   if (!mem_wall_clock)
return;
+
+   wall_clock = __va(mem_wall_clock);
+   memset(wall_clock, 0, wall_clock_size);
+
+   mem = kvm_memblock_alloc(size, PAGE_SIZE);
+   if (!mem) {
+   kvm_memblock_free(mem_wall_clock, wall_clock_size);
+   wall_clock = NULL;
+   return;
+   }
+
hv_clock = __va(mem);
memset(hv_clock, 0, size);
 
if (kvm_register_clock("primary cpu clock")) {
hv_clock = NULL;
-   memblock_free(mem, size);
+   kvm_memblock_free(mem, size);
+   kvm_memblock_free(mem_wall_clock, wall_clock_size);
+   wall_clock = NULL;
return;
}
 
-- 
2.9.4



[GIT PULL 3/5] arm64: dts: exynos: Updates for v4.14

2017-07-24 Thread Krzysztof Kozlowski

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-dt64-4.14

for you to fetch changes up to 10acba1293db5c28d1b81d673e75c2415cb96f62:

  arm64: dts: exynos: Remove num-slots from exynos platforms (2017-07-18 
07:16:14 +0200)


Samsung DTS ARM64 changes for v4.14

1. Remove deprecated and unneeded properties from Exynos boards.
2. Implement proper (working) support for USB On-The-Go on Exynos5433
   TM2/TM2E boards.


Dongwoo Lee (2):
  arm64: dts: exynos: Fix wrong label for USB 3.0 controller node
  arm64: dts: exynos: Add extcon property for TM2 and TM2E

Hoegeun Kwon (1):
  arm64: dts: exynos: Remove the OF graph from DSI node

Shawn Lin (1):
  arm64: dts: exynos: Remove num-slots from exynos platforms

 arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi | 19 ++-
 arch/arm64/boot/dts/exynos/exynos5433.dtsi|  4 ++--
 arch/arm64/boot/dts/exynos/exynos7-espresso.dts   |  2 --
 3 files changed, 4 insertions(+), 21 deletions(-)


[GIT PULL 3/5] arm64: dts: exynos: Updates for v4.14

2017-07-24 Thread Krzysztof Kozlowski

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-dt64-4.14

for you to fetch changes up to 10acba1293db5c28d1b81d673e75c2415cb96f62:

  arm64: dts: exynos: Remove num-slots from exynos platforms (2017-07-18 
07:16:14 +0200)


Samsung DTS ARM64 changes for v4.14

1. Remove deprecated and unneeded properties from Exynos boards.
2. Implement proper (working) support for USB On-The-Go on Exynos5433
   TM2/TM2E boards.


Dongwoo Lee (2):
  arm64: dts: exynos: Fix wrong label for USB 3.0 controller node
  arm64: dts: exynos: Add extcon property for TM2 and TM2E

Hoegeun Kwon (1):
  arm64: dts: exynos: Remove the OF graph from DSI node

Shawn Lin (1):
  arm64: dts: exynos: Remove num-slots from exynos platforms

 arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi | 19 ++-
 arch/arm64/boot/dts/exynos/exynos5433.dtsi|  4 ++--
 arch/arm64/boot/dts/exynos/exynos7-espresso.dts   |  2 --
 3 files changed, 4 insertions(+), 21 deletions(-)


[GIT PULL 4/5] ARM: defconfig: Exynos updates for v4.14

2017-07-24 Thread Krzysztof Kozlowski

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-defconfig-4.14

for you to fetch changes up to 57ee24144e57b762dc46f171e1f138ccfc464867:

  ARM: exynos_defconfig: Enable locking test options (2017-07-18 17:58:46 +0200)


Samsung defconfig changes for v4.14

1. Enable some drivers useful on our boards (communication: Bluetooth,
   WiFi, NFC, USB; codepages and crypto algorithms).
2. Enable debugging and lock testing options. These might have impact on
   performance but we use the exynos_defconfig a lot during development
   so they should bring benefits of detecting early locking issues.


Krzysztof Kozlowski (3):
  ARM: exynos_defconfig: Enable Bluetooth, mac80211, NFC and more USB 
drivers
  ARM: exynos_defconfig: Enable NLS_UTF8 and some crypto algorithms
  ARM: exynos_defconfig: Enable locking test options

 arch/arm/configs/exynos_defconfig | 79 ---
 1 file changed, 73 insertions(+), 6 deletions(-)


[GIT PULL 4/5] ARM: defconfig: Exynos updates for v4.14

2017-07-24 Thread Krzysztof Kozlowski

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-defconfig-4.14

for you to fetch changes up to 57ee24144e57b762dc46f171e1f138ccfc464867:

  ARM: exynos_defconfig: Enable locking test options (2017-07-18 17:58:46 +0200)


Samsung defconfig changes for v4.14

1. Enable some drivers useful on our boards (communication: Bluetooth,
   WiFi, NFC, USB; codepages and crypto algorithms).
2. Enable debugging and lock testing options. These might have impact on
   performance but we use the exynos_defconfig a lot during development
   so they should bring benefits of detecting early locking issues.


Krzysztof Kozlowski (3):
  ARM: exynos_defconfig: Enable Bluetooth, mac80211, NFC and more USB 
drivers
  ARM: exynos_defconfig: Enable NLS_UTF8 and some crypto algorithms
  ARM: exynos_defconfig: Enable locking test options

 arch/arm/configs/exynos_defconfig | 79 ---
 1 file changed, 73 insertions(+), 6 deletions(-)


Re: [PATCH V1] pinctrl: qcom: spmi-gpio: Add support for qcom,gpios-disallowed property

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 03:17:07PM +0800, fengl...@codeaurora.org wrote:
> From: Fenglin Wu 
> 
> Add support for qcom,gpios-disallowed property which is used to exclude
> PMIC GPIOs not owned by the APSS processor from the pinctrl device.
> 
> Signed-off-by: Fenglin Wu 
> ---
>  .../devicetree/bindings/pinctrl/qcom,pmic-gpio.txt |  12 ++
>  drivers/pinctrl/qcom/pinctrl-spmi-gpio.c   | 202 
> +
>  2 files changed, 176 insertions(+), 38 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt 
> b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
> index 8d893a8..435efe8 100644
> --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
> @@ -43,6 +43,17 @@ PMIC's from Qualcomm.
>   the first cell will be used to define gpio number and the
>   second denotes the flags for this gpio
>  
> +- qcom,gpios-disallowed:
> + Usage: optional
> + Value type: 
> + Definition: Array of the GPIO hardware numbers corresponding to GPIOs
> + which the APSS processor is not allowed to configure.
> + The hardware numbers are indexed from 1.
> + The interrupt resources for these GPIOs must not be defined
> + in "interrupts" and "interrupt-names" properties.
> + GPIOs defined in this array won't be registered as pins
> + in the pinctrl device or gpios in the gpio chip.

Isn't simply not assigning GPIOs to anything in the DT sufficient to not 
use GPIOs?

Rob



[GIT PULL 5/5] ARM: defconfig: Cleanups for v4.14

2017-07-24 Thread Krzysztof Kozlowski
Hi,

Non-Samsung cleanups for defconfigs


Best regards,
Krzysztof


The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-defconfig-arm-cleanups-4.14

for you to fetch changes up to c1bdf1b9a11416e183484df42616c0bab125204a:

  ARM: qcom_defconfig: Cleanup from non-existing options (2017-07-18 17:51:33 
+0200)


Bunch of ARM defconfig cleanups for v4.14

Cleanup ARMv7 defconfigs from options not existing anymore.


Krzysztof Kozlowski (5):
  ARM: multi_v7_defconfig: Cleanup from non-existing options
  ARM: ixp4xx_defconfig: Cleanup from non-existing options
  ARM: vexpress_defconfig: Cleanup from non-existing options
  ARM: ezx_defconfig: Cleanup from non-existing options
  ARM: qcom_defconfig: Cleanup from non-existing options

 arch/arm/configs/ezx_defconfig  | 1 -
 arch/arm/configs/ixp4xx_defconfig   | 4 
 arch/arm/configs/multi_v7_defconfig | 7 ---
 arch/arm/configs/qcom_defconfig | 1 -
 arch/arm/configs/vexpress_defconfig | 1 -
 5 files changed, 14 deletions(-)


Re: [PATCH V1] pinctrl: qcom: spmi-gpio: Add support for qcom,gpios-disallowed property

2017-07-24 Thread Rob Herring
On Wed, Jul 19, 2017 at 03:17:07PM +0800, fengl...@codeaurora.org wrote:
> From: Fenglin Wu 
> 
> Add support for qcom,gpios-disallowed property which is used to exclude
> PMIC GPIOs not owned by the APSS processor from the pinctrl device.
> 
> Signed-off-by: Fenglin Wu 
> ---
>  .../devicetree/bindings/pinctrl/qcom,pmic-gpio.txt |  12 ++
>  drivers/pinctrl/qcom/pinctrl-spmi-gpio.c   | 202 
> +
>  2 files changed, 176 insertions(+), 38 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt 
> b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
> index 8d893a8..435efe8 100644
> --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
> @@ -43,6 +43,17 @@ PMIC's from Qualcomm.
>   the first cell will be used to define gpio number and the
>   second denotes the flags for this gpio
>  
> +- qcom,gpios-disallowed:
> + Usage: optional
> + Value type: 
> + Definition: Array of the GPIO hardware numbers corresponding to GPIOs
> + which the APSS processor is not allowed to configure.
> + The hardware numbers are indexed from 1.
> + The interrupt resources for these GPIOs must not be defined
> + in "interrupts" and "interrupt-names" properties.
> + GPIOs defined in this array won't be registered as pins
> + in the pinctrl device or gpios in the gpio chip.

Isn't simply not assigning GPIOs to anything in the DT sufficient to not 
use GPIOs?

Rob



[GIT PULL 5/5] ARM: defconfig: Cleanups for v4.14

2017-07-24 Thread Krzysztof Kozlowski
Hi,

Non-Samsung cleanups for defconfigs


Best regards,
Krzysztof


The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-defconfig-arm-cleanups-4.14

for you to fetch changes up to c1bdf1b9a11416e183484df42616c0bab125204a:

  ARM: qcom_defconfig: Cleanup from non-existing options (2017-07-18 17:51:33 
+0200)


Bunch of ARM defconfig cleanups for v4.14

Cleanup ARMv7 defconfigs from options not existing anymore.


Krzysztof Kozlowski (5):
  ARM: multi_v7_defconfig: Cleanup from non-existing options
  ARM: ixp4xx_defconfig: Cleanup from non-existing options
  ARM: vexpress_defconfig: Cleanup from non-existing options
  ARM: ezx_defconfig: Cleanup from non-existing options
  ARM: qcom_defconfig: Cleanup from non-existing options

 arch/arm/configs/ezx_defconfig  | 1 -
 arch/arm/configs/ixp4xx_defconfig   | 4 
 arch/arm/configs/multi_v7_defconfig | 7 ---
 arch/arm/configs/qcom_defconfig | 1 -
 arch/arm/configs/vexpress_defconfig | 1 -
 5 files changed, 14 deletions(-)


[RFC Part1 PATCH v3 12/17] x86/mm: DMA support for SEV memory encryption

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

DMA access to memory mapped as encrypted while SEV is active can not be
encrypted during device write or decrypted during device read. In order
for DMA to properly work when SEV is active, the SWIOTLB bounce buffers
must be used.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/mm/mem_encrypt.c | 86 +++
 lib/swiotlb.c |  5 +--
 2 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index 1e4643e..5e5d460 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -191,8 +191,86 @@ void __init sme_early_init(void)
/* Update the protection map with memory encryption mask */
for (i = 0; i < ARRAY_SIZE(protection_map); i++)
protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+   if (sev_active())
+   swiotlb_force = SWIOTLB_FORCE;
+}
+
+static void *sme_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+  gfp_t gfp, unsigned long attrs)
+{
+   unsigned long dma_mask;
+   unsigned int order;
+   struct page *page;
+   void *vaddr = NULL;
+
+   dma_mask = dma_alloc_coherent_mask(dev, gfp);
+   order = get_order(size);
+
+   /*
+* Memory will be memset to zero after marking decrypted, so don't
+* bother clearing it before.
+*/
+   gfp &= ~__GFP_ZERO;
+
+   page = alloc_pages_node(dev_to_node(dev), gfp, order);
+   if (page) {
+   dma_addr_t addr;
+
+   /*
+* Since we will be clearing the encryption bit, check the
+* mask with it already cleared.
+*/
+   addr = __sme_clr(phys_to_dma(dev, page_to_phys(page)));
+   if ((addr + size) > dma_mask) {
+   __free_pages(page, get_order(size));
+   } else {
+   vaddr = page_address(page);
+   *dma_handle = addr;
+   }
+   }
+
+   if (!vaddr)
+   vaddr = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+
+   if (!vaddr)
+   return NULL;
+
+   /* Clear the SME encryption bit for DMA use if not swiotlb area */
+   if (!is_swiotlb_buffer(dma_to_phys(dev, *dma_handle))) {
+   set_memory_decrypted((unsigned long)vaddr, 1 << order);
+   memset(vaddr, 0, PAGE_SIZE << order);
+   *dma_handle = __sme_clr(*dma_handle);
+   }
+
+   return vaddr;
+}
+
+static void sme_free(struct device *dev, size_t size, void *vaddr,
+dma_addr_t dma_handle, unsigned long attrs)
+{
+   /* Set the SME encryption bit for re-use if not swiotlb area */
+   if (!is_swiotlb_buffer(dma_to_phys(dev, dma_handle)))
+   set_memory_encrypted((unsigned long)vaddr,
+1 << get_order(size));
+
+   swiotlb_free_coherent(dev, size, vaddr, dma_handle);
 }
 
+static const struct dma_map_ops sme_dma_ops = {
+   .alloc  = sme_alloc,
+   .free   = sme_free,
+   .map_page   = swiotlb_map_page,
+   .unmap_page = swiotlb_unmap_page,
+   .map_sg = swiotlb_map_sg_attrs,
+   .unmap_sg   = swiotlb_unmap_sg_attrs,
+   .sync_single_for_cpu= swiotlb_sync_single_for_cpu,
+   .sync_single_for_device = swiotlb_sync_single_for_device,
+   .sync_sg_for_cpu= swiotlb_sync_sg_for_cpu,
+   .sync_sg_for_device = swiotlb_sync_sg_for_device,
+   .mapping_error  = swiotlb_dma_mapping_error,
+};
+
 /* Architecture __weak replacement functions */
 void __init mem_encrypt_init(void)
 {
@@ -202,6 +280,14 @@ void __init mem_encrypt_init(void)
/* Call into SWIOTLB to update the SWIOTLB DMA buffers */
swiotlb_update_mem_attributes();
 
+   /*
+* With SEV, DMA operations cannot use encryption. New DMA ops
+* are required in order to mark the DMA areas as decrypted or
+* to use bounce buffers.
+*/
+   if (sev_active())
+   dma_ops = _dma_ops;
+
pr_info("AMD Secure Memory Encryption (SME) active\n");
 }
 
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 8c6c83e..85fed2f 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -507,8 +507,9 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
if (no_iotlb_memory)
panic("Can not allocate SWIOTLB buffer earlier and can't now 
provide you with the DMA bounce buffer");
 
-   if (sme_active())
-   pr_warn_once("SME is active and system is using DMA bounce 
buffers\n");
+   if (sme_active() || sev_active())
+   pr_warn_once("%s is active and system is using DMA bounce 
buffers\n",
+   

[RFC Part1 PATCH v3 11/17] x86/mm, resource: Use PAGE_KERNEL protection for ioremap of memory pages

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

In order for memory pages to be properly mapped when SEV is active, we
need to use the PAGE_KERNEL protection attribute as the base protection.
This will insure that memory mapping of, e.g. ACPI tables, receives the
proper mapping attributes.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/mm/ioremap.c  | 28 
 include/linux/ioport.h |  3 +++
 kernel/resource.c  | 17 +
 3 files changed, 48 insertions(+)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index c0be7cf..7b27332 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -69,6 +69,26 @@ static int __ioremap_check_ram(unsigned long start_pfn, 
unsigned long nr_pages,
return 0;
 }
 
+static int __ioremap_res_desc_other(struct resource *res, void *arg)
+{
+   return (res->desc != IORES_DESC_NONE);
+}
+
+/*
+ * This function returns true if the target memory is marked as
+ * IORESOURCE_MEM and IORESOURCE_BUSY and described as other than
+ * IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES).
+ */
+static bool __ioremap_check_if_mem(resource_size_t addr, unsigned long size)
+{
+   u64 start, end;
+
+   start = (u64)addr;
+   end = start + size - 1;
+
+   return (walk_mem_res(start, end, NULL, __ioremap_res_desc_other) == 1);
+}
+
 /*
  * Remap an arbitrary physical address space into the kernel virtual
  * address space. It transparently creates kernel huge I/O mapping when
@@ -146,7 +166,15 @@ static void __iomem *__ioremap_caller(resource_size_t 
phys_addr,
pcm = new_pcm;
}
 
+   /*
+* If the page being mapped is in memory and SEV is active then
+* make sure the memory encryption attribute is enabled in the
+* resulting mapping.
+*/
prot = PAGE_KERNEL_IO;
+   if (sev_active() && __ioremap_check_if_mem(phys_addr, size))
+   prot = pgprot_encrypted(prot);
+
switch (pcm) {
case _PAGE_CACHE_MODE_UC:
default:
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 1c66b9c..297f5b8 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -268,6 +268,9 @@ extern int
 walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
void *arg, int (*func)(unsigned long, unsigned long, void *));
 extern int
+walk_mem_res(u64 start, u64 end, void *arg,
+int (*func)(struct resource *, void *));
+extern int
 walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(struct resource *, void *));
 extern int
diff --git a/kernel/resource.c b/kernel/resource.c
index 5f9ee7bb0..ec3fa0c 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -468,6 +468,23 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
 arg, func);
 }
 
+/*
+ * This function calls the @func callback against all memory ranges, which
+ * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
+ */
+int walk_mem_res(u64 start, u64 end, void *arg,
+int (*func)(struct resource *, void *))
+{
+   struct resource res;
+
+   res.start = start;
+   res.end = end;
+   res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+   return __walk_iomem_res_desc(, IORES_DESC_NONE, true,
+arg, func);
+}
+
 #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
 
 /*
-- 
2.9.4



Re: Simplfying copy_siginfo_to_user

2017-07-24 Thread Eric W. Biederman
Linus Torvalds  writes:

> On Sat, Jul 22, 2017 at 1:25 PM, Eric W. Biederman
>  wrote:
>> I played with some clever changes such as limiting the copy to 48 bytes,
>> disabling the memset and the like but I could not get a strong enough
>> signal to say that any one change removed the extra or a clear part of
>> it 20ns.
>
> What CPU did you use? Because the SMAP bit in particular matters.
>
> The field-by-field copies are extremely slow on modern CPU's that
> implement SMAP, unless you also use the special "unsafe_put_user()"
> code (or the nasty old put_user_ex() code that some of the x86 signal
> code uses).
>
> So one of the advantages of just copy_to_user() ends up being visible
> only on Broadwell+ (or whatever the SMAP cutoff is).

Good point.

The cpu I was testing on was an AMD A10.  I don't actually have a cpu
that supports SMAP handy.

If you would like I can post the minimal patches and benckmark so anyone
who is interested could reproduce this for themselves.

I suspect that if it is down to only 20ns without SMAP this will
definitely be a performance improvement in the presence of SMAP.

Eric



[RFC Part1 PATCH v3 11/17] x86/mm, resource: Use PAGE_KERNEL protection for ioremap of memory pages

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

In order for memory pages to be properly mapped when SEV is active, we
need to use the PAGE_KERNEL protection attribute as the base protection.
This will insure that memory mapping of, e.g. ACPI tables, receives the
proper mapping attributes.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/mm/ioremap.c  | 28 
 include/linux/ioport.h |  3 +++
 kernel/resource.c  | 17 +
 3 files changed, 48 insertions(+)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index c0be7cf..7b27332 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -69,6 +69,26 @@ static int __ioremap_check_ram(unsigned long start_pfn, 
unsigned long nr_pages,
return 0;
 }
 
+static int __ioremap_res_desc_other(struct resource *res, void *arg)
+{
+   return (res->desc != IORES_DESC_NONE);
+}
+
+/*
+ * This function returns true if the target memory is marked as
+ * IORESOURCE_MEM and IORESOURCE_BUSY and described as other than
+ * IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES).
+ */
+static bool __ioremap_check_if_mem(resource_size_t addr, unsigned long size)
+{
+   u64 start, end;
+
+   start = (u64)addr;
+   end = start + size - 1;
+
+   return (walk_mem_res(start, end, NULL, __ioremap_res_desc_other) == 1);
+}
+
 /*
  * Remap an arbitrary physical address space into the kernel virtual
  * address space. It transparently creates kernel huge I/O mapping when
@@ -146,7 +166,15 @@ static void __iomem *__ioremap_caller(resource_size_t 
phys_addr,
pcm = new_pcm;
}
 
+   /*
+* If the page being mapped is in memory and SEV is active then
+* make sure the memory encryption attribute is enabled in the
+* resulting mapping.
+*/
prot = PAGE_KERNEL_IO;
+   if (sev_active() && __ioremap_check_if_mem(phys_addr, size))
+   prot = pgprot_encrypted(prot);
+
switch (pcm) {
case _PAGE_CACHE_MODE_UC:
default:
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 1c66b9c..297f5b8 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -268,6 +268,9 @@ extern int
 walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
void *arg, int (*func)(unsigned long, unsigned long, void *));
 extern int
+walk_mem_res(u64 start, u64 end, void *arg,
+int (*func)(struct resource *, void *));
+extern int
 walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(struct resource *, void *));
 extern int
diff --git a/kernel/resource.c b/kernel/resource.c
index 5f9ee7bb0..ec3fa0c 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -468,6 +468,23 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
 arg, func);
 }
 
+/*
+ * This function calls the @func callback against all memory ranges, which
+ * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
+ */
+int walk_mem_res(u64 start, u64 end, void *arg,
+int (*func)(struct resource *, void *))
+{
+   struct resource res;
+
+   res.start = start;
+   res.end = end;
+   res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+   return __walk_iomem_res_desc(, IORES_DESC_NONE, true,
+arg, func);
+}
+
 #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
 
 /*
-- 
2.9.4



Re: Simplfying copy_siginfo_to_user

2017-07-24 Thread Eric W. Biederman
Linus Torvalds  writes:

> On Sat, Jul 22, 2017 at 1:25 PM, Eric W. Biederman
>  wrote:
>> I played with some clever changes such as limiting the copy to 48 bytes,
>> disabling the memset and the like but I could not get a strong enough
>> signal to say that any one change removed the extra or a clear part of
>> it 20ns.
>
> What CPU did you use? Because the SMAP bit in particular matters.
>
> The field-by-field copies are extremely slow on modern CPU's that
> implement SMAP, unless you also use the special "unsafe_put_user()"
> code (or the nasty old put_user_ex() code that some of the x86 signal
> code uses).
>
> So one of the advantages of just copy_to_user() ends up being visible
> only on Broadwell+ (or whatever the SMAP cutoff is).

Good point.

The cpu I was testing on was an AMD A10.  I don't actually have a cpu
that supports SMAP handy.

If you would like I can post the minimal patches and benckmark so anyone
who is interested could reproduce this for themselves.

I suspect that if it is down to only 20ns without SMAP this will
definitely be a performance improvement in the presence of SMAP.

Eric



[RFC Part1 PATCH v3 12/17] x86/mm: DMA support for SEV memory encryption

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

DMA access to memory mapped as encrypted while SEV is active can not be
encrypted during device write or decrypted during device read. In order
for DMA to properly work when SEV is active, the SWIOTLB bounce buffers
must be used.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/mm/mem_encrypt.c | 86 +++
 lib/swiotlb.c |  5 +--
 2 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index 1e4643e..5e5d460 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -191,8 +191,86 @@ void __init sme_early_init(void)
/* Update the protection map with memory encryption mask */
for (i = 0; i < ARRAY_SIZE(protection_map); i++)
protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+   if (sev_active())
+   swiotlb_force = SWIOTLB_FORCE;
+}
+
+static void *sme_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+  gfp_t gfp, unsigned long attrs)
+{
+   unsigned long dma_mask;
+   unsigned int order;
+   struct page *page;
+   void *vaddr = NULL;
+
+   dma_mask = dma_alloc_coherent_mask(dev, gfp);
+   order = get_order(size);
+
+   /*
+* Memory will be memset to zero after marking decrypted, so don't
+* bother clearing it before.
+*/
+   gfp &= ~__GFP_ZERO;
+
+   page = alloc_pages_node(dev_to_node(dev), gfp, order);
+   if (page) {
+   dma_addr_t addr;
+
+   /*
+* Since we will be clearing the encryption bit, check the
+* mask with it already cleared.
+*/
+   addr = __sme_clr(phys_to_dma(dev, page_to_phys(page)));
+   if ((addr + size) > dma_mask) {
+   __free_pages(page, get_order(size));
+   } else {
+   vaddr = page_address(page);
+   *dma_handle = addr;
+   }
+   }
+
+   if (!vaddr)
+   vaddr = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+
+   if (!vaddr)
+   return NULL;
+
+   /* Clear the SME encryption bit for DMA use if not swiotlb area */
+   if (!is_swiotlb_buffer(dma_to_phys(dev, *dma_handle))) {
+   set_memory_decrypted((unsigned long)vaddr, 1 << order);
+   memset(vaddr, 0, PAGE_SIZE << order);
+   *dma_handle = __sme_clr(*dma_handle);
+   }
+
+   return vaddr;
+}
+
+static void sme_free(struct device *dev, size_t size, void *vaddr,
+dma_addr_t dma_handle, unsigned long attrs)
+{
+   /* Set the SME encryption bit for re-use if not swiotlb area */
+   if (!is_swiotlb_buffer(dma_to_phys(dev, dma_handle)))
+   set_memory_encrypted((unsigned long)vaddr,
+1 << get_order(size));
+
+   swiotlb_free_coherent(dev, size, vaddr, dma_handle);
 }
 
+static const struct dma_map_ops sme_dma_ops = {
+   .alloc  = sme_alloc,
+   .free   = sme_free,
+   .map_page   = swiotlb_map_page,
+   .unmap_page = swiotlb_unmap_page,
+   .map_sg = swiotlb_map_sg_attrs,
+   .unmap_sg   = swiotlb_unmap_sg_attrs,
+   .sync_single_for_cpu= swiotlb_sync_single_for_cpu,
+   .sync_single_for_device = swiotlb_sync_single_for_device,
+   .sync_sg_for_cpu= swiotlb_sync_sg_for_cpu,
+   .sync_sg_for_device = swiotlb_sync_sg_for_device,
+   .mapping_error  = swiotlb_dma_mapping_error,
+};
+
 /* Architecture __weak replacement functions */
 void __init mem_encrypt_init(void)
 {
@@ -202,6 +280,14 @@ void __init mem_encrypt_init(void)
/* Call into SWIOTLB to update the SWIOTLB DMA buffers */
swiotlb_update_mem_attributes();
 
+   /*
+* With SEV, DMA operations cannot use encryption. New DMA ops
+* are required in order to mark the DMA areas as decrypted or
+* to use bounce buffers.
+*/
+   if (sev_active())
+   dma_ops = _dma_ops;
+
pr_info("AMD Secure Memory Encryption (SME) active\n");
 }
 
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 8c6c83e..85fed2f 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -507,8 +507,9 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
if (no_iotlb_memory)
panic("Can not allocate SWIOTLB buffer earlier and can't now 
provide you with the DMA bounce buffer");
 
-   if (sme_active())
-   pr_warn_once("SME is active and system is using DMA bounce 
buffers\n");
+   if (sme_active() || sev_active())
+   pr_warn_once("%s is active and system is using DMA bounce 
buffers\n",
+sme_active() ? "SME" : "SEV");
 
mask = 

[GIT PULL 2/5] ARM: dts: exynos: Updates for v4.14

2017-07-24 Thread Krzysztof Kozlowski

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-dt-4.14

for you to fetch changes up to 9d2770b8e49a1726310e706ae23b52c83b33a986:

  ARM: dts: exynos: Remove num-slots from exynos platforms (2017-07-18 07:14:22 
+0200)


Samsung DTS ARM changes for v4.13

Remove deprecated and unneeded properties from Exynos boards.


Hoegeun Kwon (1):
  ARM: dts: exynos: Remove the OF graph from DSI node

Shawn Lin (1):
  ARM: dts: exynos: Remove num-slots from exynos platforms

 arch/arm/boot/dts/exynos3250-artik5-eval.dts|  1 -
 arch/arm/boot/dts/exynos3250-artik5.dtsi|  1 -
 arch/arm/boot/dts/exynos3250-monk.dts   |  1 -
 arch/arm/boot/dts/exynos3250-rinato.dts | 22 --
 arch/arm/boot/dts/exynos4210-trats.dts  | 21 -
 arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi |  1 -
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi |  1 -
 arch/arm/boot/dts/exynos4412-origen.dts |  1 -
 arch/arm/boot/dts/exynos4412-trats2.dts | 22 --
 arch/arm/boot/dts/exynos5250-arndale.dts|  2 --
 arch/arm/boot/dts/exynos5250-smdk5250.dts   |  2 --
 arch/arm/boot/dts/exynos5250-snow-common.dtsi   |  3 ---
 arch/arm/boot/dts/exynos5250-spring.dts |  2 --
 arch/arm/boot/dts/exynos5260-xyref5260.dts  |  2 --
 arch/arm/boot/dts/exynos5410-smdk5410.dts   |  2 --
 arch/arm/boot/dts/exynos5420-peach-pit.dts  |  3 ---
 arch/arm/boot/dts/exynos5800-peach-pi.dts   |  3 ---
 17 files changed, 90 deletions(-)


[RFC Part1 PATCH v3 10/17] resource: Provide resource struct in resource walk callback

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

In prep for a new function that will need additional resource information
during the resource walk, update the resource walk callback to pass the
resource structure.  Since the current callback start and end arguments
are pulled from the resource structure, the callback functions can obtain
them from the resource structure directly.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/powerpc/kernel/machine_kexec_file_64.c | 12 +---
 arch/x86/kernel/crash.c | 18 +-
 arch/x86/kernel/pmem.c  |  2 +-
 include/linux/ioport.h  |  4 ++--
 include/linux/kexec.h   |  2 +-
 kernel/kexec_file.c |  5 +++--
 kernel/resource.c   |  9 +
 7 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kernel/machine_kexec_file_64.c 
b/arch/powerpc/kernel/machine_kexec_file_64.c
index 992c0d2..e4395f9 100644
--- a/arch/powerpc/kernel/machine_kexec_file_64.c
+++ b/arch/powerpc/kernel/machine_kexec_file_64.c
@@ -91,11 +91,13 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
  * and that value will be returned. If all free regions are visited without
  * func returning non-zero, then zero will be returned.
  */
-int arch_kexec_walk_mem(struct kexec_buf *kbuf, int (*func)(u64, u64, void *))
+int arch_kexec_walk_mem(struct kexec_buf *kbuf,
+   int (*func)(struct resource *, void *))
 {
int ret = 0;
u64 i;
phys_addr_t mstart, mend;
+   struct resource res = { };
 
if (kbuf->top_down) {
for_each_free_mem_range_reverse(i, NUMA_NO_NODE, 0,
@@ -105,7 +107,9 @@ int arch_kexec_walk_mem(struct kexec_buf *kbuf, int 
(*func)(u64, u64, void *))
 * range while in kexec, end points to the last byte
 * in the range.
 */
-   ret = func(mstart, mend - 1, kbuf);
+   res.start = mstart;
+   res.end = mend - 1;
+   ret = func(, kbuf);
if (ret)
break;
}
@@ -117,7 +121,9 @@ int arch_kexec_walk_mem(struct kexec_buf *kbuf, int 
(*func)(u64, u64, void *))
 * range while in kexec, end points to the last byte
 * in the range.
 */
-   ret = func(mstart, mend - 1, kbuf);
+   res.start = mstart;
+   res.end = mend - 1;
+   ret = func(, kbuf);
if (ret)
break;
}
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 44404e2..815008c 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -209,7 +209,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 }
 
 #ifdef CONFIG_KEXEC_FILE
-static int get_nr_ram_ranges_callback(u64 start, u64 end, void *arg)
+static int get_nr_ram_ranges_callback(struct resource *res, void *arg)
 {
unsigned int *nr_ranges = arg;
 
@@ -342,7 +342,7 @@ static int elf_header_exclude_ranges(struct crash_elf_data 
*ced,
return ret;
 }
 
-static int prepare_elf64_ram_headers_callback(u64 start, u64 end, void *arg)
+static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg)
 {
struct crash_elf_data *ced = arg;
Elf64_Ehdr *ehdr;
@@ -355,7 +355,7 @@ static int prepare_elf64_ram_headers_callback(u64 start, 
u64 end, void *arg)
ehdr = ced->ehdr;
 
/* Exclude unwanted mem ranges */
-   ret = elf_header_exclude_ranges(ced, start, end);
+   ret = elf_header_exclude_ranges(ced, res->start, res->end);
if (ret)
return ret;
 
@@ -518,14 +518,14 @@ static int add_e820_entry(struct boot_params *params, 
struct e820_entry *entry)
return 0;
 }
 
-static int memmap_entry_callback(u64 start, u64 end, void *arg)
+static int memmap_entry_callback(struct resource *res, void *arg)
 {
struct crash_memmap_data *cmd = arg;
struct boot_params *params = cmd->params;
struct e820_entry ei;
 
-   ei.addr = start;
-   ei.size = end - start + 1;
+   ei.addr = res->start;
+   ei.size = res->end - res->start + 1;
ei.type = cmd->type;
add_e820_entry(params, );
 
@@ -619,12 +619,12 @@ int crash_setup_memmap_entries(struct kimage *image, 
struct boot_params *params)
return ret;
 }
 
-static int determine_backup_region(u64 start, u64 end, void *arg)
+static int determine_backup_region(struct resource *res, void *arg)
 {
struct kimage *image = arg;
 
-   image->arch.backup_src_start = start;
-   image->arch.backup_src_sz = end - start + 1;
+   

[GIT PULL 2/5] ARM: dts: exynos: Updates for v4.14

2017-07-24 Thread Krzysztof Kozlowski

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-dt-4.14

for you to fetch changes up to 9d2770b8e49a1726310e706ae23b52c83b33a986:

  ARM: dts: exynos: Remove num-slots from exynos platforms (2017-07-18 07:14:22 
+0200)


Samsung DTS ARM changes for v4.13

Remove deprecated and unneeded properties from Exynos boards.


Hoegeun Kwon (1):
  ARM: dts: exynos: Remove the OF graph from DSI node

Shawn Lin (1):
  ARM: dts: exynos: Remove num-slots from exynos platforms

 arch/arm/boot/dts/exynos3250-artik5-eval.dts|  1 -
 arch/arm/boot/dts/exynos3250-artik5.dtsi|  1 -
 arch/arm/boot/dts/exynos3250-monk.dts   |  1 -
 arch/arm/boot/dts/exynos3250-rinato.dts | 22 --
 arch/arm/boot/dts/exynos4210-trats.dts  | 21 -
 arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi |  1 -
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi |  1 -
 arch/arm/boot/dts/exynos4412-origen.dts |  1 -
 arch/arm/boot/dts/exynos4412-trats2.dts | 22 --
 arch/arm/boot/dts/exynos5250-arndale.dts|  2 --
 arch/arm/boot/dts/exynos5250-smdk5250.dts   |  2 --
 arch/arm/boot/dts/exynos5250-snow-common.dtsi   |  3 ---
 arch/arm/boot/dts/exynos5250-spring.dts |  2 --
 arch/arm/boot/dts/exynos5260-xyref5260.dts  |  2 --
 arch/arm/boot/dts/exynos5410-smdk5410.dts   |  2 --
 arch/arm/boot/dts/exynos5420-peach-pit.dts  |  3 ---
 arch/arm/boot/dts/exynos5800-peach-pi.dts   |  3 ---
 17 files changed, 90 deletions(-)


[RFC Part1 PATCH v3 10/17] resource: Provide resource struct in resource walk callback

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

In prep for a new function that will need additional resource information
during the resource walk, update the resource walk callback to pass the
resource structure.  Since the current callback start and end arguments
are pulled from the resource structure, the callback functions can obtain
them from the resource structure directly.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/powerpc/kernel/machine_kexec_file_64.c | 12 +---
 arch/x86/kernel/crash.c | 18 +-
 arch/x86/kernel/pmem.c  |  2 +-
 include/linux/ioport.h  |  4 ++--
 include/linux/kexec.h   |  2 +-
 kernel/kexec_file.c |  5 +++--
 kernel/resource.c   |  9 +
 7 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kernel/machine_kexec_file_64.c 
b/arch/powerpc/kernel/machine_kexec_file_64.c
index 992c0d2..e4395f9 100644
--- a/arch/powerpc/kernel/machine_kexec_file_64.c
+++ b/arch/powerpc/kernel/machine_kexec_file_64.c
@@ -91,11 +91,13 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
  * and that value will be returned. If all free regions are visited without
  * func returning non-zero, then zero will be returned.
  */
-int arch_kexec_walk_mem(struct kexec_buf *kbuf, int (*func)(u64, u64, void *))
+int arch_kexec_walk_mem(struct kexec_buf *kbuf,
+   int (*func)(struct resource *, void *))
 {
int ret = 0;
u64 i;
phys_addr_t mstart, mend;
+   struct resource res = { };
 
if (kbuf->top_down) {
for_each_free_mem_range_reverse(i, NUMA_NO_NODE, 0,
@@ -105,7 +107,9 @@ int arch_kexec_walk_mem(struct kexec_buf *kbuf, int 
(*func)(u64, u64, void *))
 * range while in kexec, end points to the last byte
 * in the range.
 */
-   ret = func(mstart, mend - 1, kbuf);
+   res.start = mstart;
+   res.end = mend - 1;
+   ret = func(, kbuf);
if (ret)
break;
}
@@ -117,7 +121,9 @@ int arch_kexec_walk_mem(struct kexec_buf *kbuf, int 
(*func)(u64, u64, void *))
 * range while in kexec, end points to the last byte
 * in the range.
 */
-   ret = func(mstart, mend - 1, kbuf);
+   res.start = mstart;
+   res.end = mend - 1;
+   ret = func(, kbuf);
if (ret)
break;
}
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 44404e2..815008c 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -209,7 +209,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 }
 
 #ifdef CONFIG_KEXEC_FILE
-static int get_nr_ram_ranges_callback(u64 start, u64 end, void *arg)
+static int get_nr_ram_ranges_callback(struct resource *res, void *arg)
 {
unsigned int *nr_ranges = arg;
 
@@ -342,7 +342,7 @@ static int elf_header_exclude_ranges(struct crash_elf_data 
*ced,
return ret;
 }
 
-static int prepare_elf64_ram_headers_callback(u64 start, u64 end, void *arg)
+static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg)
 {
struct crash_elf_data *ced = arg;
Elf64_Ehdr *ehdr;
@@ -355,7 +355,7 @@ static int prepare_elf64_ram_headers_callback(u64 start, 
u64 end, void *arg)
ehdr = ced->ehdr;
 
/* Exclude unwanted mem ranges */
-   ret = elf_header_exclude_ranges(ced, start, end);
+   ret = elf_header_exclude_ranges(ced, res->start, res->end);
if (ret)
return ret;
 
@@ -518,14 +518,14 @@ static int add_e820_entry(struct boot_params *params, 
struct e820_entry *entry)
return 0;
 }
 
-static int memmap_entry_callback(u64 start, u64 end, void *arg)
+static int memmap_entry_callback(struct resource *res, void *arg)
 {
struct crash_memmap_data *cmd = arg;
struct boot_params *params = cmd->params;
struct e820_entry ei;
 
-   ei.addr = start;
-   ei.size = end - start + 1;
+   ei.addr = res->start;
+   ei.size = res->end - res->start + 1;
ei.type = cmd->type;
add_e820_entry(params, );
 
@@ -619,12 +619,12 @@ int crash_setup_memmap_entries(struct kimage *image, 
struct boot_params *params)
return ret;
 }
 
-static int determine_backup_region(u64 start, u64 end, void *arg)
+static int determine_backup_region(struct resource *res, void *arg)
 {
struct kimage *image = arg;
 
-   image->arch.backup_src_start = start;
-   image->arch.backup_src_sz = end - start + 1;
+   image->arch.backup_src_start = res->start;
+   image->arch.backup_src_sz 

[GIT PULL 1/5] ARM: s3c24xx: Early stuff for v4.14

2017-07-24 Thread Krzysztof Kozlowski

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-soc-4.14

for you to fetch changes up to f991ce429a420dbb42b3e4b5a47490c84390d7e1:

  ARM: s3c24xx: make H1940BT depend on RFKILL (2017-07-20 20:26:24 +0200)


Samsung mach/soc changes for v4.14

Only for S3C24xx platform:
1. Cleanup from non-existent CONFIG entries.
2. Fix unmet NET dependency when H1940 bluetooth chip is selected..


Arnd Bergmann (1):
  ARM: s3c24xx: make H1940BT depend on RFKILL

Krzysztof Kozlowski (3):
  ARM: s3c24xx: Remove non-existing CONFIG_CPU_S3C2413
  ARM: s3c24xx: Remove non-existing SND_SOC_SMDK2443_WM9710
  ARM: s3c24xx: Do not confuse local define with Kconfig

 arch/arm/mach-s3c24xx/Kconfig   |  2 +-
 arch/arm/mach-s3c24xx/common.c  |  2 +-
 arch/arm/mach-s3c24xx/include/mach/regs-clock.h |  4 ++--
 arch/arm/mach-s3c24xx/mach-smdk2443.c   |  8 
 arch/arm/mach-s3c24xx/sleep.S   | 11 ++-
 arch/arm/plat-samsung/include/plat/map-s3c.h|  2 +-
 6 files changed, 11 insertions(+), 18 deletions(-)


[RFC Part1 PATCH v3 09/17] resource: Consolidate resource walking code

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

The walk_iomem_res_desc(), walk_system_ram_res() and walk_system_ram_range()
functions each have much of the same code.  Create a new function that
consolidates the common code from these functions in one place to reduce
the amount of duplicated code.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 kernel/resource.c | 53 ++---
 1 file changed, 26 insertions(+), 27 deletions(-)

diff --git a/kernel/resource.c b/kernel/resource.c
index 9b5f044..7b20b3e 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -397,9 +397,30 @@ static int find_next_iomem_res(struct resource *res, 
unsigned long desc,
res->start = p->start;
if (res->end > p->end)
res->end = p->end;
+   res->desc = p->desc;
return 0;
 }
 
+static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
+bool first_level_children_only,
+void *arg, int (*func)(u64, u64, void *))
+{
+   u64 orig_end = res->end;
+   int ret = -1;
+
+   while ((res->start < res->end) &&
+  !find_next_iomem_res(res, desc, first_level_children_only)) {
+   ret = (*func)(res->start, res->end, arg);
+   if (ret)
+   break;
+
+   res->start = res->end + 1;
+   res->end = orig_end;
+   }
+
+   return ret;
+}
+
 /*
  * Walks through iomem resources and calls func() with matching resource
  * ranges. This walks through whole tree and not just first level children.
@@ -418,26 +439,12 @@ int walk_iomem_res_desc(unsigned long desc, unsigned long 
flags, u64 start,
u64 end, void *arg, int (*func)(u64, u64, void *))
 {
struct resource res;
-   u64 orig_end;
-   int ret = -1;
 
res.start = start;
res.end = end;
res.flags = flags;
-   orig_end = res.end;
-
-   while ((res.start < res.end) &&
-   (!find_next_iomem_res(, desc, false))) {
-
-   ret = (*func)(res.start, res.end, arg);
-   if (ret)
-   break;
-
-   res.start = res.end + 1;
-   res.end = orig_end;
-   }
 
-   return ret;
+   return __walk_iomem_res_desc(, desc, false, arg, func);
 }
 
 /*
@@ -451,22 +458,13 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(u64, u64, void *))
 {
struct resource res;
-   u64 orig_end;
-   int ret = -1;
 
res.start = start;
res.end = end;
res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
-   orig_end = res.end;
-   while ((res.start < res.end) &&
-   (!find_next_iomem_res(, IORES_DESC_NONE, true))) {
-   ret = (*func)(res.start, res.end, arg);
-   if (ret)
-   break;
-   res.start = res.end + 1;
-   res.end = orig_end;
-   }
-   return ret;
+
+   return __walk_iomem_res_desc(, IORES_DESC_NONE, true,
+arg, func);
 }
 
 #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
@@ -508,6 +506,7 @@ static int __is_ram(unsigned long pfn, unsigned long 
nr_pages, void *arg)
 {
return 1;
 }
+
 /*
  * This generic page_is_ram() returns true if specified address is
  * registered as System RAM in iomem_resource list.
-- 
2.9.4



[GIT PULL 1/5] ARM: s3c24xx: Early stuff for v4.14

2017-07-24 Thread Krzysztof Kozlowski

The following changes since commit 5771a8c08880cdca3bfb4a3fc6d309d6bba20877:

  Linux v4.13-rc1 (2017-07-15 15:22:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git 
tags/samsung-soc-4.14

for you to fetch changes up to f991ce429a420dbb42b3e4b5a47490c84390d7e1:

  ARM: s3c24xx: make H1940BT depend on RFKILL (2017-07-20 20:26:24 +0200)


Samsung mach/soc changes for v4.14

Only for S3C24xx platform:
1. Cleanup from non-existent CONFIG entries.
2. Fix unmet NET dependency when H1940 bluetooth chip is selected..


Arnd Bergmann (1):
  ARM: s3c24xx: make H1940BT depend on RFKILL

Krzysztof Kozlowski (3):
  ARM: s3c24xx: Remove non-existing CONFIG_CPU_S3C2413
  ARM: s3c24xx: Remove non-existing SND_SOC_SMDK2443_WM9710
  ARM: s3c24xx: Do not confuse local define with Kconfig

 arch/arm/mach-s3c24xx/Kconfig   |  2 +-
 arch/arm/mach-s3c24xx/common.c  |  2 +-
 arch/arm/mach-s3c24xx/include/mach/regs-clock.h |  4 ++--
 arch/arm/mach-s3c24xx/mach-smdk2443.c   |  8 
 arch/arm/mach-s3c24xx/sleep.S   | 11 ++-
 arch/arm/plat-samsung/include/plat/map-s3c.h|  2 +-
 6 files changed, 11 insertions(+), 18 deletions(-)


[RFC Part1 PATCH v3 09/17] resource: Consolidate resource walking code

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

The walk_iomem_res_desc(), walk_system_ram_res() and walk_system_ram_range()
functions each have much of the same code.  Create a new function that
consolidates the common code from these functions in one place to reduce
the amount of duplicated code.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 kernel/resource.c | 53 ++---
 1 file changed, 26 insertions(+), 27 deletions(-)

diff --git a/kernel/resource.c b/kernel/resource.c
index 9b5f044..7b20b3e 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -397,9 +397,30 @@ static int find_next_iomem_res(struct resource *res, 
unsigned long desc,
res->start = p->start;
if (res->end > p->end)
res->end = p->end;
+   res->desc = p->desc;
return 0;
 }
 
+static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
+bool first_level_children_only,
+void *arg, int (*func)(u64, u64, void *))
+{
+   u64 orig_end = res->end;
+   int ret = -1;
+
+   while ((res->start < res->end) &&
+  !find_next_iomem_res(res, desc, first_level_children_only)) {
+   ret = (*func)(res->start, res->end, arg);
+   if (ret)
+   break;
+
+   res->start = res->end + 1;
+   res->end = orig_end;
+   }
+
+   return ret;
+}
+
 /*
  * Walks through iomem resources and calls func() with matching resource
  * ranges. This walks through whole tree and not just first level children.
@@ -418,26 +439,12 @@ int walk_iomem_res_desc(unsigned long desc, unsigned long 
flags, u64 start,
u64 end, void *arg, int (*func)(u64, u64, void *))
 {
struct resource res;
-   u64 orig_end;
-   int ret = -1;
 
res.start = start;
res.end = end;
res.flags = flags;
-   orig_end = res.end;
-
-   while ((res.start < res.end) &&
-   (!find_next_iomem_res(, desc, false))) {
-
-   ret = (*func)(res.start, res.end, arg);
-   if (ret)
-   break;
-
-   res.start = res.end + 1;
-   res.end = orig_end;
-   }
 
-   return ret;
+   return __walk_iomem_res_desc(, desc, false, arg, func);
 }
 
 /*
@@ -451,22 +458,13 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(u64, u64, void *))
 {
struct resource res;
-   u64 orig_end;
-   int ret = -1;
 
res.start = start;
res.end = end;
res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
-   orig_end = res.end;
-   while ((res.start < res.end) &&
-   (!find_next_iomem_res(, IORES_DESC_NONE, true))) {
-   ret = (*func)(res.start, res.end, arg);
-   if (ret)
-   break;
-   res.start = res.end + 1;
-   res.end = orig_end;
-   }
-   return ret;
+
+   return __walk_iomem_res_desc(, IORES_DESC_NONE, true,
+arg, func);
 }
 
 #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY)
@@ -508,6 +506,7 @@ static int __is_ram(unsigned long pfn, unsigned long 
nr_pages, void *arg)
 {
return 1;
 }
+
 /*
  * This generic page_is_ram() returns true if specified address is
  * registered as System RAM in iomem_resource list.
-- 
2.9.4



[RFC Part1 PATCH v3 05/17] x86, realmode: Don't decrypt trampoline area under SEV

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

When SEV is active the trampoline area will need to be in encrypted
memory so only mark the area decrypted if SME is active.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/realmode/init.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 1f71980..c7eeca7 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -63,9 +63,11 @@ static void __init setup_real_mode(void)
/*
 * If SME is active, the trampoline area will need to be in
 * decrypted memory in order to bring up other processors
-* successfully.
+* successfully. For SEV the trampoline area needs to be in
+* encrypted memory, so only do this for SME.
 */
-   set_memory_decrypted((unsigned long)base, size >> PAGE_SHIFT);
+   if (sme_active())
+   set_memory_decrypted((unsigned long)base, size >> PAGE_SHIFT);
 
memcpy(base, real_mode_blob, size);
 
-- 
2.9.4



[RFC Part1 PATCH v3 05/17] x86, realmode: Don't decrypt trampoline area under SEV

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

When SEV is active the trampoline area will need to be in encrypted
memory so only mark the area decrypted if SME is active.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/realmode/init.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 1f71980..c7eeca7 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -63,9 +63,11 @@ static void __init setup_real_mode(void)
/*
 * If SME is active, the trampoline area will need to be in
 * decrypted memory in order to bring up other processors
-* successfully.
+* successfully. For SEV the trampoline area needs to be in
+* encrypted memory, so only do this for SME.
 */
-   set_memory_decrypted((unsigned long)base, size >> PAGE_SHIFT);
+   if (sme_active())
+   set_memory_decrypted((unsigned long)base, size >> PAGE_SHIFT);
 
memcpy(base, real_mode_blob, size);
 
-- 
2.9.4



[RFC Part1 PATCH v3 06/17] x86/mm: Use encrypted access of boot related data with SEV

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

When Secure Encrypted Virtualization (SEV) is active, boot data (such as
EFI related data, setup data) is encrypted and needs to be accessed as
such when mapped. Update the architecture override in early_memremap to
keep the encryption attribute when mapping this data.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/mm/ioremap.c | 44 
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 34f0e18..c0be7cf 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -422,6 +422,9 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
  * areas should be mapped decrypted. And since the encryption key can
  * change across reboots, persistent memory should also be mapped
  * decrypted.
+ *
+ * If SEV is active, that implies that BIOS/UEFI also ran encrypted so
+ * only persistent memory should be mapped decrypted.
  */
 static bool memremap_should_map_decrypted(resource_size_t phys_addr,
  unsigned long size)
@@ -458,6 +461,11 @@ static bool memremap_should_map_decrypted(resource_size_t 
phys_addr,
case E820_TYPE_ACPI:
case E820_TYPE_NVS:
case E820_TYPE_UNUSABLE:
+   /* For SEV, these areas are encrypted */
+   if (sev_active())
+   break;
+   /* Fallthrough */
+
case E820_TYPE_PRAM:
return true;
default:
@@ -581,7 +589,7 @@ static bool __init 
early_memremap_is_setup_data(resource_size_t phys_addr,
 bool arch_memremap_can_ram_remap(resource_size_t phys_addr, unsigned long size,
 unsigned long flags)
 {
-   if (!sme_active())
+   if (!sme_active() && !sev_active())
return true;
 
if (flags & MEMREMAP_ENC)
@@ -590,10 +598,15 @@ bool arch_memremap_can_ram_remap(resource_size_t 
phys_addr, unsigned long size,
if (flags & MEMREMAP_DEC)
return false;
 
-   if (memremap_is_setup_data(phys_addr, size) ||
-   memremap_is_efi_data(phys_addr, size) ||
-   memremap_should_map_decrypted(phys_addr, size))
-   return false;
+   if (sme_active()) {
+   if (memremap_is_setup_data(phys_addr, size) ||
+   memremap_is_efi_data(phys_addr, size) ||
+   memremap_should_map_decrypted(phys_addr, size))
+   return false;
+   } else if (sev_active()) {
+   if (memremap_should_map_decrypted(phys_addr, size))
+   return false;
+   }
 
return true;
 }
@@ -608,15 +621,22 @@ pgprot_t __init 
early_memremap_pgprot_adjust(resource_size_t phys_addr,
 unsigned long size,
 pgprot_t prot)
 {
-   if (!sme_active())
+   if (!sme_active() && !sev_active())
return prot;
 
-   if (early_memremap_is_setup_data(phys_addr, size) ||
-   memremap_is_efi_data(phys_addr, size) ||
-   memremap_should_map_decrypted(phys_addr, size))
-   prot = pgprot_decrypted(prot);
-   else
-   prot = pgprot_encrypted(prot);
+   if (sme_active()) {
+   if (early_memremap_is_setup_data(phys_addr, size) ||
+   memremap_is_efi_data(phys_addr, size) ||
+   memremap_should_map_decrypted(phys_addr, size))
+   prot = pgprot_decrypted(prot);
+   else
+   prot = pgprot_encrypted(prot);
+   } else if (sev_active()) {
+   if (memremap_should_map_decrypted(phys_addr, size))
+   prot = pgprot_decrypted(prot);
+   else
+   prot = pgprot_encrypted(prot);
+   }
 
return prot;
 }
-- 
2.9.4



[RFC Part1 PATCH v3 06/17] x86/mm: Use encrypted access of boot related data with SEV

2017-07-24 Thread Brijesh Singh
From: Tom Lendacky 

When Secure Encrypted Virtualization (SEV) is active, boot data (such as
EFI related data, setup data) is encrypted and needs to be accessed as
such when mapped. Update the architecture override in early_memremap to
keep the encryption attribute when mapping this data.

Signed-off-by: Tom Lendacky 
Signed-off-by: Brijesh Singh 
---
 arch/x86/mm/ioremap.c | 44 
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 34f0e18..c0be7cf 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -422,6 +422,9 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
  * areas should be mapped decrypted. And since the encryption key can
  * change across reboots, persistent memory should also be mapped
  * decrypted.
+ *
+ * If SEV is active, that implies that BIOS/UEFI also ran encrypted so
+ * only persistent memory should be mapped decrypted.
  */
 static bool memremap_should_map_decrypted(resource_size_t phys_addr,
  unsigned long size)
@@ -458,6 +461,11 @@ static bool memremap_should_map_decrypted(resource_size_t 
phys_addr,
case E820_TYPE_ACPI:
case E820_TYPE_NVS:
case E820_TYPE_UNUSABLE:
+   /* For SEV, these areas are encrypted */
+   if (sev_active())
+   break;
+   /* Fallthrough */
+
case E820_TYPE_PRAM:
return true;
default:
@@ -581,7 +589,7 @@ static bool __init 
early_memremap_is_setup_data(resource_size_t phys_addr,
 bool arch_memremap_can_ram_remap(resource_size_t phys_addr, unsigned long size,
 unsigned long flags)
 {
-   if (!sme_active())
+   if (!sme_active() && !sev_active())
return true;
 
if (flags & MEMREMAP_ENC)
@@ -590,10 +598,15 @@ bool arch_memremap_can_ram_remap(resource_size_t 
phys_addr, unsigned long size,
if (flags & MEMREMAP_DEC)
return false;
 
-   if (memremap_is_setup_data(phys_addr, size) ||
-   memremap_is_efi_data(phys_addr, size) ||
-   memremap_should_map_decrypted(phys_addr, size))
-   return false;
+   if (sme_active()) {
+   if (memremap_is_setup_data(phys_addr, size) ||
+   memremap_is_efi_data(phys_addr, size) ||
+   memremap_should_map_decrypted(phys_addr, size))
+   return false;
+   } else if (sev_active()) {
+   if (memremap_should_map_decrypted(phys_addr, size))
+   return false;
+   }
 
return true;
 }
@@ -608,15 +621,22 @@ pgprot_t __init 
early_memremap_pgprot_adjust(resource_size_t phys_addr,
 unsigned long size,
 pgprot_t prot)
 {
-   if (!sme_active())
+   if (!sme_active() && !sev_active())
return prot;
 
-   if (early_memremap_is_setup_data(phys_addr, size) ||
-   memremap_is_efi_data(phys_addr, size) ||
-   memremap_should_map_decrypted(phys_addr, size))
-   prot = pgprot_decrypted(prot);
-   else
-   prot = pgprot_encrypted(prot);
+   if (sme_active()) {
+   if (early_memremap_is_setup_data(phys_addr, size) ||
+   memremap_is_efi_data(phys_addr, size) ||
+   memremap_should_map_decrypted(phys_addr, size))
+   prot = pgprot_decrypted(prot);
+   else
+   prot = pgprot_encrypted(prot);
+   } else if (sev_active()) {
+   if (memremap_should_map_decrypted(phys_addr, size))
+   prot = pgprot_decrypted(prot);
+   else
+   prot = pgprot_encrypted(prot);
+   }
 
return prot;
 }
-- 
2.9.4



<    4   5   6   7   8   9   10   11   12   13   >