* [PATCH 07/11] driver core: Respect all error codes from dev_pm_domain_attach()
From: Tony Lindgren @ 2018-05-14 15:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1524732790-2234-8-git-send-email-ulf.hansson@linaro.org>
Ulf,
* Ulf Hansson <ulf.hansson@linaro.org> [180426 09:01]:
> The limitation of being able to check only for -EPROBE_DEFER from
> dev_pm_domain_attach() has been removed. Hence let's respect all error
> codes and bail out accordingly.
>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
> drivers/base/platform.c | 17 ++++++++---------
> 1 file changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 8075ddc..9460139 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -572,17 +572,16 @@ static int platform_drv_probe(struct device *_dev)
> return ret;
>
> ret = dev_pm_domain_attach(_dev, true);
> - if (ret != -EPROBE_DEFER) {
> - if (drv->probe) {
> - ret = drv->probe(dev);
> - if (ret)
> - dev_pm_domain_detach(_dev, true);
> - } else {
> - /* don't fail if just dev_pm_domain_attach failed */
> - ret = 0;
> - }
> + if (ret)
> + goto out;
> +
> + if (drv->probe) {
> + ret = drv->probe(dev);
> + if (ret)
> + dev_pm_domain_detach(_dev, true);
> }
>
> +out:
> if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
> dev_warn(_dev, "probe deferral not supported\n");
> ret = -ENXIO;
> --
Looks like this causes Linux next to not boot for me with device
probes failing with error -17. So that's at least omaps, looks
like kernelci has others failing too.
Reverting for 8c123c14bbba ("driver core: Respect all error codes from
dev_pm_domain_attach()") fixes the issue for me.
Sounds like something is missing, any ideas?
Regards,
Tony
^ permalink raw reply
* [PATCH v3 4/4] drm/rockchip: support dp training outside dp firmware
From: Sean Paul @ 2018-05-14 15:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526291635-31122-4-git-send-email-hl@rock-chips.com>
On Mon, May 14, 2018 at 05:53:55PM +0800, Lin Huang wrote:
> DP firmware uses fixed phy config values to do training, but some
> boards need to adjust these values to fit for their unique hardware
> design. So if the phy is using custom config values, do software
> link training instead of relying on firmware, if software training
> fail, keep firmware training as a fallback if sw training fails.
>
> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
> Signed-off-by: Lin Huang <hl@rock-chips.com>
> ---
> Changes in v2:
> - update patch following Enric suggest
> Changes in v3:
> - use variable fw_training instead sw_training_success
> - base on DP SPCE, if training fail use lower link rate to retry training
>
> drivers/gpu/drm/rockchip/Makefile | 3 +-
> drivers/gpu/drm/rockchip/cdn-dp-core.c | 24 +-
> drivers/gpu/drm/rockchip/cdn-dp-core.h | 2 +
> drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 416 ++++++++++++++++++++++++
> drivers/gpu/drm/rockchip/cdn-dp-reg.c | 31 +-
> drivers/gpu/drm/rockchip/cdn-dp-reg.h | 38 ++-
> 6 files changed, 501 insertions(+), 13 deletions(-)
> create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c
>
> diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
> index a314e21..b932f62 100644
> --- a/drivers/gpu/drm/rockchip/Makefile
> +++ b/drivers/gpu/drm/rockchip/Makefile
> @@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
> rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
>
> rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
> -rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
> +rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
> + cdn-dp-link-training.o
> rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
> rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
> rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> index cce64c1..d9d0d4d 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> @@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
> goto out;
> }
> }
> -
> - ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
> - if (ret) {
> - DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
> - goto out;
> + if (dp->use_fw_training == true) {
> + ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev,
> + "Failed to idle video %d\n", ret);
> + goto out;
> + }
> }
>
> ret = cdn_dp_config_video(dp);
> @@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
> goto out;
> }
>
> - ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
> - if (ret) {
> - DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
> - goto out;
> + if (dp->use_fw_training == true) {
> + ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev,
> + "Failed to valid video %d\n", ret);
> + goto out;
> + }
> }
> +
> out:
> mutex_unlock(&dp->lock);
> }
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
> index 46159b2..77a9793 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
> @@ -84,6 +84,7 @@ struct cdn_dp_device {
> bool connected;
> bool active;
> bool suspended;
> + bool use_fw_training;
>
> const struct firmware *fw; /* cdn dp firmware */
> unsigned int fw_version; /* cdn fw version */
> @@ -106,6 +107,7 @@ struct cdn_dp_device {
> u8 ports;
> u8 lanes;
> int active_port;
> + u8 train_set[4];
>
> u8 dpcd[DP_RECEIVER_CAP_SIZE];
> bool sink_has_audio;
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
> new file mode 100644
> index 0000000..b8fd5bc
> --- /dev/null
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
/snip
> +static int cdn_dp_get_lower_link_rate(struct cdn_dp_device *dp)
> +{
> + if (dp->link.rate == DP_LINK_BW_1_62)
> + return -EINVAL;
> + else if (dp->link.rate == DP_LINK_BW_2_7)
> + dp->link.rate = DP_LINK_BW_1_62;
Extra indent
> + else
> + dp->link.rate = DP_LINK_BW_2_7;
This is better expressed as a switch statement:
switch (dp->link.rate) {
case DP_LINK_BW_1_62:
return -EINVAL;
case DP_LINK_BW_2_7:
dp->link.rate = DP_LINK_BW_1_62:
break;
default:
dp->link.rate = DP_LINK_BW_2_7:
break;
}
You might also consider adding an additional case since there are rates higher
than 5.4GHz. ie:
case DP_LINK_BW_5_4:
dp->link.rate = DP_LINK_BW_2_7:
break;
default:
dp->link.rate = DP_LINK_BW_5_4:
break;
> +
> + return 0;
> +}
> +
> +int cdn_dp_software_train_link(struct cdn_dp_device *dp)
> +{
> + int ret, stop_err;
> + u8 link_config[2];
> + u32 rate, sink_max, source_max;
> +
> + ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd,
> + sizeof(dp->dpcd));
> + if (ret < 0) {
> + DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
> + return ret;
> + }
> +
> + source_max = dp->lanes;
> + sink_max = drm_dp_max_lane_count(dp->dpcd);
> + dp->link.num_lanes = min(source_max, sink_max);
> +
> + source_max = drm_dp_bw_code_to_link_rate(CDN_DP_MAX_LINK_RATE);
> + sink_max = drm_dp_max_link_rate(dp->dpcd);
> + rate = min(source_max, sink_max);
> + dp->link.rate = drm_dp_link_rate_to_bw_code(rate);
> +
> +retry:
> + /* Write the link configuration data */
> + link_config[0] = dp->link.rate;
> + link_config[1] = dp->link.num_lanes;
> + if (drm_dp_enhanced_frame_cap(dp->dpcd))
> + link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
> + drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, link_config, 2);
> +
> + link_config[0] = 0;
> + link_config[1] = 0;
> + if (dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] & 0x01)
> + link_config[1] = DP_SET_ANSI_8B10B;
> + drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
> +
> + ret = cdn_dp_link_training_clock_recovery(dp);
> + if (ret) {
> + if (cdn_dp_get_lower_link_rate(dp)) {
> + DRM_ERROR("training clock recovery fail, err: %d\n",
> + ret);
> + goto stop_training;
> + }
> +
> + /* use lower link rate to retraining */
> + goto retry;
> + }
> +
> + ret = cdn_dp_link_training_channel_equalization(dp);
> + if (ret) {
> + if (cdn_dp_get_lower_link_rate(dp)) {
> + DRM_ERROR("training channel equalization fail, err: %d\n",
> + ret);
> + goto stop_training;
> + }
> +
> + /* use lower link rate to retraining */
> + goto retry;
> + }
> +
> +stop_training:
> + stop_err = cdn_dp_stop_link_train(dp);
> + if (stop_err) {
> + DRM_ERROR("stop training fail, error: %d\n", stop_err);
> + return stop_err;
> + }
> +
> + return ret;
Using labels to do loops reduces readability, it seems like you can also pull
out the downspread control write.
link_config[0] = 0;
link_config[1] = 0;
if (dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] & 0x01)
link_config[1] = DP_SET_ANSI_8B10B;
drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
while (true) {
/* Write the link configuration data */
link_config[0] = dp->link.rate;
link_config[1] = dp->link.num_lanes;
if (drm_dp_enhanced_frame_cap(dp->dpcd))
link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, link_config, 2);
ret = cdn_dp_link_training_clock_recovery(dp);
if (ret) {
if (!cdn_dp_get_lower_link_rate(dp))
continue;
DRM_ERROR("training clock recovery failed: %d\n", ret);
break;
}
ret = cdn_dp_link_training_channel_equalization(dp);
if (ret) {
if (!cdn_dp_get_lower_link_rate(dp))
continue;
DRM_ERROR("training channel eq failed: %d\n", ret);
break;
}
return 0;
}
stop_err = cdn_dp_stop_link_train(dp);
if (stop_err) {
DRM_ERROR("stop training fail, error: %d\n", stop_err);
return stop_err;
}
return ret;
> +
> +stop_training:
> + stop_err = cdn_dp_stop_link_train(dp);
> + if (stop_err) {
> + DRM_ERROR("stop training fail, error: %d\n", stop_err);
> + return stop_err;
> + }
> +
> + return ret;
> +}
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> index 979355d..e1273e6 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> @@ -17,7 +17,9 @@
> #include <linux/delay.h>
> #include <linux/io.h>
> #include <linux/iopoll.h>
> +#include <linux/phy/phy.h>
> #include <linux/reset.h>
> +#include <soc/rockchip/rockchip_phy_typec.h>
>
> #include "cdn-dp-core.h"
> #include "cdn-dp-reg.h"
> @@ -189,7 +191,7 @@ static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id,
> return 0;
> }
>
> -static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
> {
> u8 msg[6];
>
> @@ -609,6 +611,31 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
> {
> int ret;
>
> + /*
> + * DP firmware uses fixed phy config values to do training, but some
> + * boards need to adjust these values to fit for their unique hardware
> + * design. So if the phy is using custom config values, do software
> + * link training instead of relying on firmware, if software training
This comment is no longer accurate.
> + * fail, keep firmware training as a fallback if sw training fails.
> + */
> + ret = cdn_dp_software_train_link(dp);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev,
> + "Failed to do software training %d\n", ret);
> + goto do_fw_training;
> + }
> + ret = cdn_dp_reg_write(dp, SOURCE_HDTX_CAR, 0xf);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev,
> + "Failed to write SOURCE_HDTX_CAR register %d\n", ret);
> + goto do_fw_training;
> + }
> + dp->use_fw_training = false;
> + return 0;
> +
> +do_fw_training:
> + dp->use_fw_training = true;
> + DRM_DEV_DEBUG_KMS(dp->dev, "use fw training\n");
> ret = cdn_dp_training_start(dp);
> if (ret) {
> DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
> @@ -623,7 +650,7 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
>
> DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
> dp->link.num_lanes);
> - return ret;
> + return 0;
> }
>
> int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
>
/snip
--
Sean Paul, Software Engineer, Google / Chromium OS
^ permalink raw reply
* [PATCH 4/4] firmware: arm_sdei: use common SMCCC_CONDUIT_*
From: James Morse @ 2018-05-14 15:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503170330.5591-5-mark.rutland@arm.com>
Hi Mark,
On 03/05/18 18:03, Mark Rutland wrote:
> Now that we have common definitions for SMCCC conduits, move the SDEI
> code over to them, and remove the SDEI-specific definitions.
>
> There should be no functional change as a result of this patch.
Thanks for clearing this up!
Acked-by: James Morse <james.morse@arm.com>
James
^ permalink raw reply
* [PATCH] ghes_edac: enable HIP08 platform edac driver
From: James Morse @ 2018-05-14 15:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514094709.GC23049@pd.tnic>
Hi Borislav,
(CC: +linux-arm list, just in case there is wider discussion)
On 14/05/18 10:47, Borislav Petkov wrote:
> On Mon, May 14, 2018 at 12:11:28PM +0800, Zhengqiang wrote:
>> In ARM64 defconfig, ghes_edac is default load. memory error report to
>> user space rasdaemon tool through function ghes_edac_report_mem_error,
>> we need it.
>
> So depending on whether there will be an ARM64 edac driver, we can do
I'm afraid there could be a mix: The v8.2 CPU RAS Extensions mean the kernel can
do kernel first. (I agree for those systems there should only be one edac driver).
For systems without the v8.2 CPU RAS Extensions firmware-first is the only way
of doing it.
> the platform whitelisting on x86 only if ARM prefers to do the reporting
> through ghes_edac. James?
I'm afraid I'd like to keep both doors open. Kernel-first handling will require
some ACPI-table/DT property as some aspects of the CPU extensions aren't
discover-able. Can't we use this to pick up whether the platform supports
firmware-first (HEST and GHES entries) or kernel-first via some as-yet-undefined
HEST bits?
Without GHES entries this code would never be run. So we 'just' need to catch
systems that are describing both. (which can be the platform specific kernel
first bits problem to do)
Thanks,
James
^ permalink raw reply
* [PATCH] ARM: dts: socfpga: Fix NAND controller node compatible
From: Dinh Nguyen @ 2018-05-14 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <73h8nak8y3.fsf@pengutronix.de>
On 05/14/2018 02:11 AM, Steffen Trumtrar wrote:
>
> Marek Vasut <marex@denx.de> writes:
>
>> The compatible string for the Denali NAND controller is incorrect,
>> fix it by replacing it with one matching the DT bindings and the
>> driver.
>>
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> Fixes: d837a80d19 ("ARM: dts: socfpga: add nand controller nodes")
>> Cc: Steffen Trumtrar <s.trumtrar@pengutronix.de>
>> Cc: Dinh Nguyen <dinguyen@kernel.org>
>> ---
>> ?arch/arm/boot/dts/socfpga.dtsi | 2 +-
>> ?1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/socfpga.dtsi
>> b/arch/arm/boot/dts/socfpga.dtsi
>> index 7e24dc8e82d4..d697f5062624 100644
>> --- a/arch/arm/boot/dts/socfpga.dtsi
>> +++ b/arch/arm/boot/dts/socfpga.dtsi
>> @@ -744,7 +744,7 @@
>> ???????? nand0: nand at ff900000 {
>> ???????????? #address-cells = <0x1>;
>> ???????????? #size-cells = <0x1>;
>> -??????????? compatible = "denali,denali-nand-dt";
>> +??????????? compatible = "altr,socfpga-denali-nand";
>> ???????????? reg = <0xff900000 0x100000>,
>> ?????????????????? <0xffb80000 0x10000>;
>> ???????????? reg-names = "nand_data", "denali_reg";
>
> Ack. As the binding was changed after d837a80d19 this is obviously
> correct.
>
> @Dinh: Maybe you also want to cleanup the socfpga_arria10.dtsi? It has
> both compatibles, but the "denali,denali-nand-dt" seems to be obsolete.
>
Patch applied and cc'd stable kernel.
Will clean up arria10.
Thanks,
Dinh
^ permalink raw reply
* [PATCH] ARM: dts: socfpga: Fix NAND controller node compatible
From: Dinh Nguyen @ 2018-05-14 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <73h8nak8y3.fsf@pengutronix.de>
On 05/14/2018 02:11 AM, Steffen Trumtrar wrote:
>
> Marek Vasut <marex@denx.de> writes:
>
>> The compatible string for the Denali NAND controller is incorrect,
>> fix it by replacing it with one matching the DT bindings and the
>> driver.
>>
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> Fixes: d837a80d19 ("ARM: dts: socfpga: add nand controller nodes")
>> Cc: Steffen Trumtrar <s.trumtrar@pengutronix.de>
>> Cc: Dinh Nguyen <dinguyen@kernel.org>
>> ---
>> ?arch/arm/boot/dts/socfpga.dtsi | 2 +-
>> ?1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/socfpga.dtsi
>> b/arch/arm/boot/dts/socfpga.dtsi
>> index 7e24dc8e82d4..d697f5062624 100644
>> --- a/arch/arm/boot/dts/socfpga.dtsi
>> +++ b/arch/arm/boot/dts/socfpga.dtsi
>> @@ -744,7 +744,7 @@
>> ???????? nand0: nand at ff900000 {
>> ???????????? #address-cells = <0x1>;
>> ???????????? #size-cells = <0x1>;
>> -??????????? compatible = "denali,denali-nand-dt";
>> +??????????? compatible = "altr,socfpga-denali-nand";
>> ???????????? reg = <0xff900000 0x100000>,
>> ?????????????????? <0xffb80000 0x10000>;
>> ???????????? reg-names = "nand_data", "denali_reg";
>
> Ack. As the binding was changed after d837a80d19 this is obviously
> correct.
>
> @Dinh: Maybe you also want to cleanup the socfpga_arria10.dtsi? It has
> both compatibles, but the "denali,denali-nand-dt" seems to be obsolete.
>
Patch applied and cc'd stable kernel.
Will clean up arria10.
Thanks,
Dinh
^ permalink raw reply
* [PATCH] ARM: dts: socfpga: Fix NAND controller node compatible
From: Dinh Nguyen @ 2018-05-14 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <73h8nak8y3.fsf@pengutronix.de>
On 05/14/2018 02:11 AM, Steffen Trumtrar wrote:
>
> Marek Vasut <marex@denx.de> writes:
>
>> The compatible string for the Denali NAND controller is incorrect,
>> fix it by replacing it with one matching the DT bindings and the
>> driver.
>>
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> Fixes: d837a80d19 ("ARM: dts: socfpga: add nand controller nodes")
>> Cc: Steffen Trumtrar <s.trumtrar@pengutronix.de>
>> Cc: Dinh Nguyen <dinguyen@kernel.org>
>> ---
>> ?arch/arm/boot/dts/socfpga.dtsi | 2 +-
>> ?1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/socfpga.dtsi
>> b/arch/arm/boot/dts/socfpga.dtsi
>> index 7e24dc8e82d4..d697f5062624 100644
>> --- a/arch/arm/boot/dts/socfpga.dtsi
>> +++ b/arch/arm/boot/dts/socfpga.dtsi
>> @@ -744,7 +744,7 @@
>> ???????? nand0: nand at ff900000 {
>> ???????????? #address-cells = <0x1>;
>> ???????????? #size-cells = <0x1>;
>> -??????????? compatible = "denali,denali-nand-dt";
>> +??????????? compatible = "altr,socfpga-denali-nand";
>> ???????????? reg = <0xff900000 0x100000>,
>> ?????????????????? <0xffb80000 0x10000>;
>> ???????????? reg-names = "nand_data", "denali_reg";
>
> Ack. As the binding was changed after d837a80d19 this is obviously
> correct.
>
> @Dinh: Maybe you also want to cleanup the socfpga_arria10.dtsi? It has
> both compatibles, but the "denali,denali-nand-dt" seems to be obsolete.
>
Patch applied and cc'd stable kernel.
Will clean up arria10.
Thanks,
Dinh
^ permalink raw reply
* [PATCH] arm64: allowing mmap to be traced
From: Christian Hansen (chansen3) @ 2018-05-14 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526308362-45443-1-git-send-email-chansen3@cisco.com>
Indeed, you have the quicker draw. I concede to your patch.
?On 2018-05-14, 10:32 AM, "Christian Hansen (chansen3)" <chansen3@cisco.com> wrote:
Adding missing macro which is present all other system calls to
to mmap declaration for ARM. This allows it to appear as a kernel
tracing target.
Signed-off-by: Christian Hansen <chansen3@cisco.com>
---
arch/arm64/kernel/sys.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 72981ba..1ccdbfc 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -27,9 +27,9 @@
#include <linux/syscalls.h>
#include <asm/cpufeature.h>
-asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t off)
+SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags,
+ unsigned long, fd, off_t, off)
{
if (offset_in_page(off) != 0)
return -EINVAL;
--
2.5.0
^ permalink raw reply
* [PATCH] ARM: dts: socfpga: Fix NAND controller clock supply
From: Dinh Nguyen @ 2018-05-14 15:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510143726.8047-1-marex@denx.de>
On 05/10/2018 09:37 AM, Marek Vasut wrote:
> The Denali NAND x-clock should be supplied by nand_x_clk, not by
> nand_clk. Fix this, otherwise the Denali driver gets incorrect
> clock frequency information and incorrectly configures the NAND
> timing.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Fixes: d837a80d19 ("ARM: dts: socfpga: add nand controller nodes")
> Cc: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> Cc: Dinh Nguyen <dinguyen@kernel.org>
> ---
> arch/arm/boot/dts/socfpga.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
> index d697f5062624..e719c20a0e65 100644
> --- a/arch/arm/boot/dts/socfpga.dtsi
> +++ b/arch/arm/boot/dts/socfpga.dtsi
> @@ -750,7 +750,7 @@
> reg-names = "nand_data", "denali_reg";
> interrupts = <0x0 0x90 0x4>;
> dma-mask = <0xffffffff>;
> - clocks = <&nand_clk>;
> + clocks = <&nand_x_clk>;
> status = "disabled";
> };
>
>
Applied and cc'ed stable kernel.
Thanks,
Dinh
^ permalink raw reply
* [PATCH 10/18] arm64: convert native/compat syscall entry to C
From: Mark Rutland @ 2018-05-14 15:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514144331.GL7753@e103592.cambridge.arm.com>
On Mon, May 14, 2018 at 03:43:36PM +0100, Dave Martin wrote:
> On Mon, May 14, 2018 at 12:58:05PM +0100, Mark Rutland wrote:
> > On Mon, May 14, 2018 at 12:07:30PM +0100, Dave Martin wrote:
> > > On Mon, May 14, 2018 at 10:46:32AM +0100, Mark Rutland wrote:
> > > > +{
> > > > + if (!system_supports_sve())
> > > > + return;
> > > > +
> > > > + /*
> > > > + * task_fpsimd_load() won't be called to update CPACR_EL1 in
> > > > + * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
> > > > + * happens if a context switch or kernel_neon_begin() or context
> > > > + * modification (sigreturn, ptrace) intervenes.
> > > > + * So, ensure that CPACR_EL1 is already correct for the fast-path case.
> > > > + */
> > > > + if (test_and_clear_thread_flag(TIF_SVE))
> > > > + sve_user_disable();
> > >
> > > sve_user_disable() is already inline, and incorporates the if()
> > > internally via sysreg_clear_set().
> > >
> > > So, should this just be
> > >
> > > clear_thread_flag(TIF_SVE);
> > > sve_user_disable();
> >
> > Sure. That does mean we'll unconditionally read cpacr_el1, but I assume
> > you're happy with that. I'll note the difference in the commit message.
>
> This is what the code does today, conditioned no system_supports_sve().
>
> I'm assuming that reading CPACR_EL1 is cheap ... or have you come across
> counterexamples to that?
I have no data either way. :)
> > > > +}
> > > > +
> > > > +extern syscall_fn_t sys_call_table[];
> > > > +
> > > > +asmlinkage void el0_svc_handler(struct pt_regs *regs)
> > > > +{
> > >
> > > if (system_supports_sve()) ?
> > >
> > > > + sve_user_disable();
> > >
> > > Or should this be replaced by a call to sve_user_reset()?
> > >
> > > I suspect the latter, since we do want to be clearing TIF_SVE here too.
> >
> > Yes, this was mean to be sve_user_reset().
>
> OK. Just to be clear, I think there should be a system_supports_sve()
> check here (in case that wasn't obvious from my previous reply).
I understood that; the check is inside sve_user_reset(), which I had
mean to call here.
With your above comments, I now have the following:
static inline void sve_user_reset(void)
{
if (!system_supports_sve())
return;
/*
* task_fpsimd_load() won't be called to update CPACR_EL1 in
* ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
* happens if a context switch or kernel_neon_begin() or context
* modification (sigreturn, ptrace) intervenes.
* So, ensure that CPACR_EL1 is already correct for the fast-path case.
*/
clear_thread_flag(TIF_SVE);
sve_user_disable();
}
asmlinkage void el0_svc_handler(struct pt_regs *regs)
{
sve_user_reset();
el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
}
... which I think alleviates that concern?
Thanks,
Mark.
^ permalink raw reply
* [PATCH] arm64: defconfig: enable the Armada thermal driver
From: Antoine Tenart @ 2018-05-14 14:58 UTC (permalink / raw)
To: linux-arm-kernel
This patch enables the Armada thermal driver to support thermal
management on Marvell EBU Armada SoCs (7K,8K).
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index ecf613761e78..8f0707bcc54d 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -343,6 +343,7 @@ CONFIG_SENSORS_INA2XX=m
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
CONFIG_THERMAL_EMULATION=y
+CONFIG_ARMADA_THERMAL=y
CONFIG_BRCMSTB_THERMAL=m
CONFIG_EXYNOS_THERMAL=y
CONFIG_RCAR_GEN3_THERMAL=y
--
2.17.0
^ permalink raw reply related
* [PATCH v3 3/4] phy: rockchip-typec: support variable phy config value
From: Sean Paul @ 2018-05-14 14:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526291635-31122-3-git-send-email-hl@rock-chips.com>
On Mon, May 14, 2018 at 05:53:54PM +0800, Lin Huang wrote:
> the phy config values used to fix in dp firmware, but some boards
> need change these values to do training and get the better eye diagram
> result. So support that in phy driver.
>
> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
> Signed-off-by: Lin Huang <hl@rock-chips.com>
> ---
> Changes in v2:
> - update patch following Enric suggest
> Changes in v3:
> - delete need_software_training variable
> - add default phy config value, if dts do not define phy config value, use these value
>
> drivers/phy/rockchip/phy-rockchip-typec.c | 305 ++++++++++++++++++++----------
> include/soc/rockchip/rockchip_phy_typec.h | 63 ++++++
> 2 files changed, 270 insertions(+), 98 deletions(-)
> create mode 100644 include/soc/rockchip/rockchip_phy_typec.h
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
> index 76a4b58..10253ad 100644
> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
/snip
>
> +/* default phy config */
> +struct phy_config configs[3][4] = {
static const
Also, configs isn't a good name. How about tcphy_default_config?
> + {{ 0x2a, 0x00 },
Can you please expand the assignment for all of these, ie:
{ .swing = 0x2a, .pe = 0x00 },
> + { 0x1f, 0x15 },
> + { 0x14, 0x22 },
> + { 0x02, 0x2b } },
> +
> + {{ 0x21, 0x00 },
> + { 0x12, 0x15 },
> + { 0x02, 0x22 },
> + { 0, 0 } },
> +
> + {{ 0x15, 0x00 },
> + { 0x00, 0x15 },
> + { 0, 0 },
> + { 0, 0 } },
> +};
> +
/snip
--
Sean Paul, Software Engineer, Google / Chromium OS
^ permalink raw reply
* [PATCH v3 3/3] arm64: Force swiotlb bounce buffering for non-coherent DMA with large CWG
From: Catalin Marinas @ 2018-05-14 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180512123829.GA8024@lst.de>
On Sat, May 12, 2018 at 02:38:29PM +0200, Christoph Hellwig wrote:
> On Fri, May 11, 2018 at 02:55:47PM +0100, Catalin Marinas wrote:
> > On systems with a Cache Writeback Granule (CTR_EL0.CWG) greater than
> > ARCH_DMA_MINALIGN, DMA cache maintenance on sub-CWG ranges is not safe,
> > leading to data corruption. If such configuration is detected, the
> > kernel will force swiotlb bounce buffering for all non-coherent devices.
>
> Per the previous discussion I understand that so far this is a
> purely theoretical condition.
That's what we think, at least for publicly available hardware.
> Given that I'd rather avoid commiting this patch and just refuse too
> boot in this case.
I'll keep it to a WARN_TAINT() for now. Given that the warn triggers
only when cache_line_size() > ARCH_DMA_MINALIGN and we keep this
constant unchanged (128), it shouldn't be much different from our
current assumptions and no-one complained of DMA corruption so far.
> In a merge window or two I plan to have a noncoherent flag in struct
> device, at which point we can handle this entirely in common code.
Sounds ok, looking forward to this.
Thanks.
--
Catalin
^ permalink raw reply
* [PATCH 20/21] i2c: stu300: make use of i2c_8bit_addr_from_msg
From: Peter Rosin @ 2018-05-14 14:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514145330.4857-1-peda@axentia.se>
Because it looks neater.
Also restructure debug output for resends, since that code as a
result is only handling debug output.
Signed-off-by: Peter Rosin <peda@axentia.se>
---
drivers/i2c/busses/i2c-stu300.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c
index dc63236b45b2..e866c481bfc3 100644
--- a/drivers/i2c/busses/i2c-stu300.c
+++ b/drivers/i2c/busses/i2c-stu300.c
@@ -602,20 +602,24 @@ static int stu300_send_address(struct stu300_dev *dev,
u32 val;
int ret;
- if (msg->flags & I2C_M_TEN)
+ if (msg->flags & I2C_M_TEN) {
/* This is probably how 10 bit addresses look */
val = (0xf0 | (((u32) msg->addr & 0x300) >> 7)) &
I2C_DR_D_MASK;
- else
- val = ((msg->addr << 1) & I2C_DR_D_MASK);
+ if (msg->flags & I2C_M_RD)
+ /* This is the direction bit */
+ val |= 0x01;
+ } else {
+ val = i2c_8bit_addr_from_msg(msg);
+ }
- if (msg->flags & I2C_M_RD) {
- /* This is the direction bit */
- val |= 0x01;
- if (resend)
+ if (resend) {
+ if (msg->flags & I2C_M_RD)
dev_dbg(&dev->pdev->dev, "read resend\n");
- } else if (resend)
- dev_dbg(&dev->pdev->dev, "write resend\n");
+ else
+ dev_dbg(&dev->pdev->dev, "write resend\n");
+ }
+
stu300_wr8(val, dev->virtbase + I2C_DR);
/* For 10bit addressing, await 10bit request (EVENT 9) */
--
2.11.0
^ permalink raw reply related
* [PATCH 07/21] i2c: efm32: make use of i2c_8bit_addr_from_msg
From: Peter Rosin @ 2018-05-14 14:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514145330.4857-1-peda@axentia.se>
Because it looks neater.
Signed-off-by: Peter Rosin <peda@axentia.se>
---
drivers/i2c/busses/i2c-efm32.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-efm32.c b/drivers/i2c/busses/i2c-efm32.c
index aa336ba89aa3..5f2bab878b2c 100644
--- a/drivers/i2c/busses/i2c-efm32.c
+++ b/drivers/i2c/busses/i2c-efm32.c
@@ -144,8 +144,7 @@ static void efm32_i2c_send_next_msg(struct efm32_i2c_ddata *ddata)
struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg];
efm32_i2c_write32(ddata, REG_CMD, REG_CMD_START);
- efm32_i2c_write32(ddata, REG_TXDATA, cur_msg->addr << 1 |
- (cur_msg->flags & I2C_M_RD ? 1 : 0));
+ efm32_i2c_write32(ddata, REG_TXDATA, i2c_8bit_addr_from_msg(cur_msg));
}
static void efm32_i2c_send_next_byte(struct efm32_i2c_ddata *ddata)
--
2.11.0
^ permalink raw reply related
* [PATCH 04/21] i2c: aspeed: make use of i2c_8bit_addr_from_msg
From: Peter Rosin @ 2018-05-14 14:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514145330.4857-1-peda@axentia.se>
Because it looks neater.
Signed-off-by: Peter Rosin <peda@axentia.se>
---
drivers/i2c/busses/i2c-aspeed.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 7d4aeb4465b3..60e4d0e939a3 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -335,13 +335,12 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus)
{
u32 command = ASPEED_I2CD_M_START_CMD | ASPEED_I2CD_M_TX_CMD;
struct i2c_msg *msg = &bus->msgs[bus->msgs_index];
- u8 slave_addr = msg->addr << 1;
+ u8 slave_addr = i2c_8bit_addr_from_msg(msg);
bus->master_state = ASPEED_I2C_MASTER_START;
bus->buf_index = 0;
if (msg->flags & I2C_M_RD) {
- slave_addr |= 1;
command |= ASPEED_I2CD_M_RX_CMD;
/* Need to let the hardware know to NACK after RX. */
if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN))
--
2.11.0
^ permalink raw reply related
* [PATCH 00/21] i2c: make use of i2c_8bit_addr_from_msg
From: Peter Rosin @ 2018-05-14 14:53 UTC (permalink / raw)
To: linux-arm-kernel
Hi!
The nice little inline i2c_8bit_addr_from_msg is not getting
enough use. This series improves the situation and drops a
bunch of lines in the process.
I have only compile-tested (that part fine, at least over here).
Cheers,
Peter
Peter Rosin (21):
i2c: algo: bit: make use of i2c_8bit_addr_from_msg
i2c: algo: pca: make use of i2c_8bit_addr_from_msg
i2c: algo: pcf: make use of i2c_8bit_addr_from_msg
i2c: aspeed: make use of i2c_8bit_addr_from_msg
i2c: axxia: make use of i2c_8bit_addr_from_msg
i2c: diolan: make use of i2c_8bit_addr_from_msg
i2c: efm32: make use of i2c_8bit_addr_from_msg
i2c: eg20t: make use of i2c_8bit_addr_from_msg
i2c: emev2: make use of i2c_8bit_addr_from_msg
i2c: hix5hd2: make use of i2c_8bit_addr_from_msg
i2c: imx-lpi2c: make use of i2c_8bit_addr_from_msg
i2c: imx: make use of i2c_8bit_addr_from_msg
i2c: kempld: make use of i2c_8bit_addr_from_msg
i2c: mxs: make use of i2c_8bit_addr_from_msg
i2c: ocores: make use of i2c_8bit_addr_from_msg
i2c: pasemi: make use of i2c_8bit_addr_from_msg
i2c: qup: make use of i2c_8bit_addr_from_msg
i2c: rcar: make use of i2c_8bit_addr_from_msg
i2c: riic: make use of i2c_8bit_addr_from_msg
i2c: stu300: make use of i2c_8bit_addr_from_msg
i2c: xiic: make use of i2c_8bit_addr_from_msg
drivers/i2c/algos/i2c-algo-bit.c | 4 +---
drivers/i2c/algos/i2c-algo-pca.c | 5 +----
drivers/i2c/algos/i2c-algo-pcf.c | 5 +----
drivers/i2c/busses/i2c-aspeed.c | 3 +--
drivers/i2c/busses/i2c-axxia.c | 5 +++--
drivers/i2c/busses/i2c-diolan-u2c.c | 11 ++++-------
drivers/i2c/busses/i2c-efm32.c | 3 +--
drivers/i2c/busses/i2c-eg20t.c | 5 ++---
drivers/i2c/busses/i2c-emev2.c | 2 +-
drivers/i2c/busses/i2c-hix5hd2.c | 9 ++-------
drivers/i2c/busses/i2c-imx-lpi2c.c | 4 +---
drivers/i2c/busses/i2c-imx.c | 10 +++++-----
drivers/i2c/busses/i2c-kempld.c | 7 +++----
drivers/i2c/busses/i2c-mxs.c | 9 +++------
drivers/i2c/busses/i2c-ocores.c | 5 +----
drivers/i2c/busses/i2c-pasemi.c | 2 +-
drivers/i2c/busses/i2c-qup.c | 2 +-
drivers/i2c/busses/i2c-rcar.c | 2 +-
drivers/i2c/busses/i2c-riic.c | 5 ++---
drivers/i2c/busses/i2c-stu300.c | 22 +++++++++++++---------
drivers/i2c/busses/i2c-xiic.c | 11 ++---------
21 files changed, 50 insertions(+), 81 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH] PM / Domains: Don't return -EEXIST at attach when PM domain exists
From: Ulf Hansson @ 2018-05-14 14:52 UTC (permalink / raw)
To: linux-arm-kernel
As dev_pm_domain_attach() isn't the only way to assign PM domain pointers
to devices, clearly we must allow a device to have the pointer already
being assigned. For this reason, return 0 instead of -EEXIST.
Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Reported-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Tested-by: Krzysztof Kozlowski <krzk@kernel.org>
---
Krzysztof reported problems for an Exynos5 board, where some devices are added
to their PM domains (genpd) via calling of_genpd_add_device(). As also pointed
out by Sylvester, this leads to probe failure when dev_pm_domain_attach()
returns -EXISTS.
Rafael, potentially this change could be squashed with the recently queued
patch: "PM / Domains: Check for existing PM domain in dev_pm_domain_attach()",
but perhaps its too late for that and the fix is better applied on top!?
---
drivers/base/power/common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
index 5e4b481..390868c 100644
--- a/drivers/base/power/common.c
+++ b/drivers/base/power/common.c
@@ -106,7 +106,7 @@ int dev_pm_domain_attach(struct device *dev, bool power_on)
int ret;
if (dev->pm_domain)
- return -EEXIST;
+ return 0;
ret = acpi_dev_pm_attach(dev, power_on);
if (!ret)
--
2.7.4
^ permalink raw reply related
* [PATCH v2 4/4] ARM: PWM: add allwinner sun8i pwm support.
From: Hao Zhang @ 2018-05-14 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180226090038.etk5q4pd4rl5dvf6@flea.lan>
2018-02-26 17:00 GMT+08:00 Maxime Ripard <maxime.ripard@bootlin.com>:
> Hi,
>
> Thanks for respinning this serie. It looks mostly good, but you still
> have a quite significant number of checkpatch (--strict) warnings that
> you should address.
Thanks for reviews :) ,i'm sorry for that, it will be fixed next time.
and, besides, in what situation were the checkpatch warning can be ignore?
>
> On Sun, Feb 25, 2018 at 09:53:08PM +0800, hao_zhang wrote:
>> +#define CAPTURE_IRQ_ENABLE_REG 0x0010
>> +#define CFIE(ch) BIT(ch << 1 + 1)
>> +#define CRIE(ch) BIT(ch << 1)
>
> You should also put your argument between parentheses here (and in all
> your other macros).
Do you mean like this ?
#define CFIE(ch) BIT((ch) << 1 + 1)
#define CRIE(ch) BIT((ch) << 1)
>
>> +static const u16 div_m_table[] = {
>> + 1,
>> + 2,
>> + 4,
>> + 8,
>> + 16,
>> + 32,
>> + 64,
>> + 128,
>> + 256
>> +};
>
> If this is just a power of two, you can use either the power of two /
> ilog2 to switch back and forth, instead of using that table.
I think using table is more explicit and extended...
>
>> +static int sun8i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>> + struct pwm_state *state)
>> +{
>> + int ret;
>> + struct sun8i_pwm_chip *sun8i_pwm = to_sun8i_pwm_chip(chip);
>> + struct pwm_state cstate;
>> +
>> + pwm_get_state(pwm, &cstate);
>> + if (!cstate.enabled) {
>> + ret = clk_prepare_enable(sun8i_pwm->clk);
>> + if (ret) {
>> + dev_err(chip->dev, "Failed to enable PWM clock\n");
>> + return ret;
>> + }
>> + }
>> +
>> + spin_lock(&sun8i_pwm->ctrl_lock);
>
> What do you need that spinlock for? Can you use a mutex instead?
It should be remove.
>
> Thanks!
> Maxime
>
> --
> Maxime Ripard, Bootlin (formerly Free Electrons)
> Embedded Linux and Kernel engineering
> https://bootlin.com
^ permalink raw reply
* [PATCH 10/18] arm64: convert native/compat syscall entry to C
From: Dave Martin @ 2018-05-14 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514115805.bdlcxsw6q3xsbjb7@lakrids.cambridge.arm.com>
On Mon, May 14, 2018 at 12:58:05PM +0100, Mark Rutland wrote:
> On Mon, May 14, 2018 at 12:07:30PM +0100, Dave Martin wrote:
> > On Mon, May 14, 2018 at 10:46:32AM +0100, Mark Rutland wrote:
>
> > > diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> > > index 5df857e32b48..4706f841e758 100644
> > > --- a/arch/arm64/kernel/syscall.c
> > > +++ b/arch/arm64/kernel/syscall.c
> > > @@ -6,7 +6,9 @@
> > > #include <linux/ptrace.h>
> > >
> > > #include <asm/daifflags.h>
> > > +#include <asm/fpsimd.h>
> > > #include <asm/thread_info.h>
> > > +#include <asm/unistd.h>
> > >
> > > long do_ni_syscall(struct pt_regs *regs);
> > >
> > > @@ -41,8 +43,8 @@ static inline bool has_syscall_work(unsigned long flags)
> > > int syscall_trace_enter(struct pt_regs *regs);
> > > void syscall_trace_exit(struct pt_regs *regs);
> > >
> > > -asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> > > - syscall_fn_t syscall_table[])
> > > +static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> > > + syscall_fn_t syscall_table[])
> > > {
> > > unsigned long flags = current_thread_info()->flags;
> > >
> > > @@ -79,3 +81,37 @@ asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> > > trace_exit:
> > > syscall_trace_exit(regs);
> > > }
> > > +
> > > +static inline void sve_user_reset(void)
> >
> > Static function with no caller...
>
> Ugh, this was intended to be called below in el0_svc_handler().
>
> > > +{
> > > + if (!system_supports_sve())
> > > + return;
> > > +
> > > + /*
> > > + * task_fpsimd_load() won't be called to update CPACR_EL1 in
> > > + * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
> > > + * happens if a context switch or kernel_neon_begin() or context
> > > + * modification (sigreturn, ptrace) intervenes.
> > > + * So, ensure that CPACR_EL1 is already correct for the fast-path case.
> > > + */
> > > + if (test_and_clear_thread_flag(TIF_SVE))
> > > + sve_user_disable();
> >
> > sve_user_disable() is already inline, and incorporates the if()
> > internally via sysreg_clear_set().
> >
> > So, should this just be
> >
> > clear_thread_flag(TIF_SVE);
> > sve_user_disable();
>
> Sure. That does mean we'll unconditionally read cpacr_el1, but I assume
> you're happy with that. I'll note the difference in the commit message.
This is what the code does today, conditioned no system_supports_sve().
I'm assuming that reading CPACR_EL1 is cheap ... or have you come across
counterexamples to that?
> > > +}
> > > +
> > > +extern syscall_fn_t sys_call_table[];
> > > +
> > > +asmlinkage void el0_svc_handler(struct pt_regs *regs)
> > > +{
> >
> > if (system_supports_sve()) ?
> >
> > > + sve_user_disable();
> >
> > Or should this be replaced by a call to sve_user_reset()?
> >
> > I suspect the latter, since we do want to be clearing TIF_SVE here too.
>
> Yes, this was mean to be sve_user_reset().
OK. Just to be clear, I think there should be a system_supports_sve()
check here (in case that wasn't obvious from my previous reply).
Cheers
---Dave
^ permalink raw reply
* [PATCH v3 4/4] KVM: arm64: Add support for PUD hugepages at stage 2
From: Punit Agrawal @ 2018-05-14 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514144304.10484-1-punit.agrawal@arm.com>
KVM only supports PMD hugepages at stage 2. Extend the stage 2 fault
handling to add support for PUD hugepages.
Addition of pud hugepage support enables additional hugepage
sizes (e.g., 1G with 4K granule) which can be useful on cores that
support mapping larger block sizes in the TLB entries.
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm/include/asm/kvm_mmu.h | 19 ++++++++++++
arch/arm64/include/asm/kvm_mmu.h | 15 ++++++++++
arch/arm64/include/asm/pgtable-hwdef.h | 4 +++
arch/arm64/include/asm/pgtable.h | 2 ++
virt/kvm/arm/mmu.c | 40 ++++++++++++++++++++++++--
5 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 224c22c0a69c..155916dbdd7e 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -77,8 +77,11 @@ void kvm_clear_hyp_idmap(void);
#define kvm_pfn_pte(pfn, prot) pfn_pte(pfn, prot)
#define kvm_pfn_pmd(pfn, prot) pfn_pmd(pfn, prot)
+#define kvm_pfn_pud(pfn, prot) (__pud(0))
#define kvm_pmd_mkhuge(pmd) pmd_mkhuge(pmd)
+/* No support for pud hugepages */
+#define kvm_pud_mkhuge(pud) (pud)
/*
* The following kvm_*pud*() functionas are provided strictly to allow
@@ -95,6 +98,22 @@ static inline bool kvm_s2pud_readonly(pud_t *pud)
return false;
}
+static inline void kvm_set_pud(pud_t *pud, pud_t new_pud)
+{
+ BUG();
+}
+
+static inline pud_t kvm_s2pud_mkwrite(pud_t pud)
+{
+ BUG();
+ return pud;
+}
+
+static inline pud_t kvm_s2pud_mkexec(pud_t pud)
+{
+ BUG();
+ return pud;
+}
static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
{
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index f440cf216a23..f49a68fcbf26 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -172,11 +172,14 @@ void kvm_clear_hyp_idmap(void);
#define kvm_set_pte(ptep, pte) set_pte(ptep, pte)
#define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd)
+#define kvm_set_pud(pudp, pud) set_pud(pudp, pud)
#define kvm_pfn_pte(pfn, prot) pfn_pte(pfn, prot)
#define kvm_pfn_pmd(pfn, prot) pfn_pmd(pfn, prot)
+#define kvm_pfn_pud(pfn, prot) pfn_pud(pfn, prot)
#define kvm_pmd_mkhuge(pmd) pmd_mkhuge(pmd)
+#define kvm_pud_mkhuge(pud) pud_mkhuge(pud)
static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
{
@@ -190,6 +193,12 @@ static inline pmd_t kvm_s2pmd_mkwrite(pmd_t pmd)
return pmd;
}
+static inline pud_t kvm_s2pud_mkwrite(pud_t pud)
+{
+ pud_val(pud) |= PUD_S2_RDWR;
+ return pud;
+}
+
static inline pte_t kvm_s2pte_mkexec(pte_t pte)
{
pte_val(pte) &= ~PTE_S2_XN;
@@ -202,6 +211,12 @@ static inline pmd_t kvm_s2pmd_mkexec(pmd_t pmd)
return pmd;
}
+static inline pud_t kvm_s2pud_mkexec(pud_t pud)
+{
+ pud_val(pud) &= ~PUD_S2_XN;
+ return pud;
+}
+
static inline void kvm_set_s2pte_readonly(pte_t *ptep)
{
pteval_t old_pteval, pteval;
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index fd208eac9f2a..e327665e94d1 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -193,6 +193,10 @@
#define PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
#define PMD_S2_XN (_AT(pmdval_t, 2) << 53) /* XN[1:0] */
+#define PUD_S2_RDONLY (_AT(pudval_t, 1) << 6) /* HAP[2:1] */
+#define PUD_S2_RDWR (_AT(pudval_t, 3) << 6) /* HAP[2:1] */
+#define PUD_S2_XN (_AT(pudval_t, 2) << 53) /* XN[1:0] */
+
/*
* Memory Attribute override for Stage-2 (MemAttr[3:0])
*/
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7c4c8f318ba9..31ea9fda07e3 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -386,6 +386,8 @@ static inline int pmd_protnone(pmd_t pmd)
#define pud_write(pud) pte_write(pud_pte(pud))
+#define pud_mkhuge(pud) (__pud(pud_val(pud) & ~PUD_TABLE_BIT))
+
#define __pud_to_phys(pud) __pte_to_phys(pud_pte(pud))
#define __phys_to_pud_val(phys) __phys_to_pte_val(phys)
#define pud_pfn(pud) ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 671d3c0825f2..b0931fa2d64e 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1036,6 +1036,26 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
return 0;
}
+static int stage2_set_pud_huge(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
+ phys_addr_t addr, const pud_t *new_pud)
+{
+ pud_t *pud, old_pud;
+
+ pud = stage2_get_pud(kvm, cache, addr);
+ VM_BUG_ON(!pud);
+
+ old_pud = *pud;
+ if (pud_present(old_pud)) {
+ pud_clear(pud);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+ } else {
+ get_page(virt_to_page(pud));
+ }
+
+ kvm_set_pud(pud, *new_pud);
+ return 0;
+}
+
static bool stage2_is_exec(struct kvm *kvm, phys_addr_t addr)
{
pmd_t *pmdp;
@@ -1467,9 +1487,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
}
vma_pagesize = vma_kernel_pagesize(vma);
- if (vma_pagesize == PMD_SIZE && !logging_active) {
+ if ((vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE) &&
+ !logging_active) {
+ struct hstate *h = hstate_vma(vma);
+
hugetlb = true;
- gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
+ gfn = (fault_ipa & huge_page_mask(h)) >> PAGE_SHIFT;
} else {
/*
* Pages belonging to memslots that don't have the same
@@ -1555,7 +1578,18 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (exec_fault)
invalidate_icache_guest_page(pfn, vma_pagesize);
- if (vma_pagesize == PMD_SIZE) {
+ if (vma_pagesize == PUD_SIZE) {
+ pud_t new_pud = kvm_pfn_pud(pfn, mem_type);
+
+ new_pud = kvm_pud_mkhuge(new_pud);
+ if (writable)
+ new_pud = kvm_s2pud_mkwrite(new_pud);
+
+ if (stage2_should_exec(kvm, fault_ipa, exec_fault, fault_status))
+ new_pud = kvm_s2pud_mkexec(new_pud);
+
+ ret = stage2_set_pud_huge(kvm, memcache, fault_ipa, &new_pud);
+ } else if (vma_pagesize == PMD_SIZE) {
pmd_t new_pmd = kvm_pfn_pmd(pfn, mem_type);
new_pmd = kvm_pmd_mkhuge(new_pmd);
--
2.17.0
^ permalink raw reply related
* [PATCH v3 3/4] KVM: arm64: Support dirty page tracking for PUD hugepages
From: Punit Agrawal @ 2018-05-14 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514144304.10484-1-punit.agrawal@arm.com>
In preparation for creating PUD hugepages at stage 2, add support for
write protecting PUD hugepages when they are encountered. Write
protecting guest tables is used to track dirty pages when migrating
VMs.
Also, provide trivial implementations of required kvm_s2pud_* helpers
to allow sharing of code with arm32.
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm/include/asm/kvm_mmu.h | 16 ++++++++++++++++
arch/arm64/include/asm/kvm_mmu.h | 10 ++++++++++
virt/kvm/arm/mmu.c | 9 ++++++---
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 5907a81ad5c1..224c22c0a69c 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -80,6 +80,22 @@ void kvm_clear_hyp_idmap(void);
#define kvm_pmd_mkhuge(pmd) pmd_mkhuge(pmd)
+/*
+ * The following kvm_*pud*() functionas are provided strictly to allow
+ * sharing code with arm64. They should never be called in practice.
+ */
+static inline void kvm_set_s2pud_readonly(pud_t *pud)
+{
+ BUG();
+}
+
+static inline bool kvm_s2pud_readonly(pud_t *pud)
+{
+ BUG();
+ return false;
+}
+
+
static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
{
*pmd = new_pmd;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index d962508ce4b3..f440cf216a23 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -240,6 +240,16 @@ static inline bool kvm_s2pmd_exec(pmd_t *pmdp)
return !(READ_ONCE(pmd_val(*pmdp)) & PMD_S2_XN);
}
+static inline void kvm_set_s2pud_readonly(pud_t *pudp)
+{
+ kvm_set_s2pte_readonly((pte_t *)pudp);
+}
+
+static inline bool kvm_s2pud_readonly(pud_t *pudp)
+{
+ return kvm_s2pte_readonly((pte_t *)pudp);
+}
+
static inline bool kvm_page_empty(void *ptr)
{
struct page *ptr_page = virt_to_page(ptr);
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 0beefcc5e090..671d3c0825f2 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1286,9 +1286,12 @@ static void stage2_wp_puds(pgd_t *pgd, phys_addr_t addr, phys_addr_t end)
do {
next = stage2_pud_addr_end(addr, end);
if (!stage2_pud_none(*pud)) {
- /* TODO:PUD not supported, revisit later if supported */
- BUG_ON(stage2_pud_huge(*pud));
- stage2_wp_pmds(pud, addr, next);
+ if (stage2_pud_huge(*pud)) {
+ if (!kvm_s2pud_readonly(pud))
+ kvm_set_s2pud_readonly(pud);
+ } else {
+ stage2_wp_pmds(pud, addr, next);
+ }
}
} while (pud++, addr = next, addr != end);
}
--
2.17.0
^ permalink raw reply related
* [PATCH v3 2/4] KVM: arm/arm64: Introduce helpers to manupulate page table entries
From: Punit Agrawal @ 2018-05-14 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514144304.10484-1-punit.agrawal@arm.com>
Introduce helpers to abstract architectural handling of the conversion
of pfn to page table entries and marking a PMD page table entry as a
block entry.
The helpers are introduced in preparation for supporting PUD hugepages
at stage 2 - which are supported on arm64 but do not exist on arm.
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm/include/asm/kvm_mmu.h | 5 +++++
arch/arm64/include/asm/kvm_mmu.h | 5 +++++
virt/kvm/arm/mmu.c | 7 ++++---
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 707a1f06dc5d..5907a81ad5c1 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -75,6 +75,11 @@ phys_addr_t kvm_get_idmap_vector(void);
int kvm_mmu_init(void);
void kvm_clear_hyp_idmap(void);
+#define kvm_pfn_pte(pfn, prot) pfn_pte(pfn, prot)
+#define kvm_pfn_pmd(pfn, prot) pfn_pmd(pfn, prot)
+
+#define kvm_pmd_mkhuge(pmd) pmd_mkhuge(pmd)
+
static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
{
*pmd = new_pmd;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 082110993647..d962508ce4b3 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -173,6 +173,11 @@ void kvm_clear_hyp_idmap(void);
#define kvm_set_pte(ptep, pte) set_pte(ptep, pte)
#define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd)
+#define kvm_pfn_pte(pfn, prot) pfn_pte(pfn, prot)
+#define kvm_pfn_pmd(pfn, prot) pfn_pmd(pfn, prot)
+
+#define kvm_pmd_mkhuge(pmd) pmd_mkhuge(pmd)
+
static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
{
pte_val(pte) |= PTE_S2_RDWR;
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 07ae1e003762..0beefcc5e090 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1553,8 +1553,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
invalidate_icache_guest_page(pfn, vma_pagesize);
if (vma_pagesize == PMD_SIZE) {
- pmd_t new_pmd = pfn_pmd(pfn, mem_type);
- new_pmd = pmd_mkhuge(new_pmd);
+ pmd_t new_pmd = kvm_pfn_pmd(pfn, mem_type);
+
+ new_pmd = kvm_pmd_mkhuge(new_pmd);
if (writable)
new_pmd = kvm_s2pmd_mkwrite(new_pmd);
@@ -1563,7 +1564,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd);
} else {
- pte_t new_pte = pfn_pte(pfn, mem_type);
+ pte_t new_pte = kvm_pfn_pte(pfn, mem_type);
if (writable) {
new_pte = kvm_s2pte_mkwrite(new_pte);
--
2.17.0
^ permalink raw reply related
* [PATCH v3 1/4] KVM: arm/arm64: Share common code in user_mem_abort()
From: Punit Agrawal @ 2018-05-14 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180514144304.10484-1-punit.agrawal@arm.com>
The code for operations such as marking the pfn as dirty, and
dcache/icache maintenance during stage 2 fault handling is duplicated
between normal pages and PMD hugepages.
Instead of creating another copy of the operations when we introduce
PUD hugepages, let's share them across the different pagesizes.
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
virt/kvm/arm/mmu.c | 69 +++++++++++++++++++++++++++-------------------
1 file changed, 40 insertions(+), 29 deletions(-)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 7f6a944db23d..07ae1e003762 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1396,6 +1396,21 @@ static void invalidate_icache_guest_page(kvm_pfn_t pfn, unsigned long size)
__invalidate_icache_guest_page(pfn, size);
}
+static bool stage2_should_exec(struct kvm *kvm, phys_addr_t addr,
+ bool exec_fault, unsigned long fault_status)
+{
+ /*
+ * If we took an execution fault we will have made the
+ * icache/dcache coherent and should now let the s2 mapping be
+ * executable.
+ *
+ * Write faults (!exec_fault && FSC_PERM) are orthogonal to
+ * execute permissions, and we preserve whatever we have.
+ */
+ return exec_fault ||
+ (fault_status == FSC_PERM && stage2_is_exec(kvm, addr));
+}
+
static void kvm_send_hwpoison_signal(unsigned long address,
struct vm_area_struct *vma)
{
@@ -1428,7 +1443,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
kvm_pfn_t pfn;
pgprot_t mem_type = PAGE_S2;
bool logging_active = memslot_is_logging(memslot);
- unsigned long flags = 0;
+ unsigned long vma_pagesize, flags = 0;
write_fault = kvm_is_write_fault(vcpu);
exec_fault = kvm_vcpu_trap_is_iabt(vcpu);
@@ -1448,7 +1463,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
return -EFAULT;
}
- if (vma_kernel_pagesize(vma) == PMD_SIZE && !logging_active) {
+ vma_pagesize = vma_kernel_pagesize(vma);
+ if (vma_pagesize == PMD_SIZE && !logging_active) {
hugetlb = true;
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
} else {
@@ -1517,28 +1533,33 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (mmu_notifier_retry(kvm, mmu_seq))
goto out_unlock;
- if (!hugetlb && !force_pte)
- hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa);
+ if (!hugetlb && !force_pte) {
+ /*
+ * Only PMD_SIZE transparent hugepages(THP) are
+ * currently supported. This code will need to be
+ * updated to support other THP sizes.
+ */
+ if (transparent_hugepage_adjust(&pfn, &fault_ipa))
+ vma_pagesize = PMD_SIZE;
+ }
+
+ if (writable)
+ kvm_set_pfn_dirty(pfn);
- if (hugetlb) {
+ if (fault_status != FSC_PERM)
+ clean_dcache_guest_page(pfn, vma_pagesize);
+
+ if (exec_fault)
+ invalidate_icache_guest_page(pfn, vma_pagesize);
+
+ if (vma_pagesize == PMD_SIZE) {
pmd_t new_pmd = pfn_pmd(pfn, mem_type);
new_pmd = pmd_mkhuge(new_pmd);
- if (writable) {
+ if (writable)
new_pmd = kvm_s2pmd_mkwrite(new_pmd);
- kvm_set_pfn_dirty(pfn);
- }
- if (fault_status != FSC_PERM)
- clean_dcache_guest_page(pfn, PMD_SIZE);
-
- if (exec_fault) {
+ if (stage2_should_exec(kvm, fault_ipa, exec_fault, fault_status))
new_pmd = kvm_s2pmd_mkexec(new_pmd);
- invalidate_icache_guest_page(pfn, PMD_SIZE);
- } else if (fault_status == FSC_PERM) {
- /* Preserve execute if XN was already cleared */
- if (stage2_is_exec(kvm, fault_ipa))
- new_pmd = kvm_s2pmd_mkexec(new_pmd);
- }
ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd);
} else {
@@ -1546,21 +1567,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (writable) {
new_pte = kvm_s2pte_mkwrite(new_pte);
- kvm_set_pfn_dirty(pfn);
mark_page_dirty(kvm, gfn);
}
- if (fault_status != FSC_PERM)
- clean_dcache_guest_page(pfn, PAGE_SIZE);
-
- if (exec_fault) {
+ if (stage2_should_exec(kvm, fault_ipa, exec_fault, fault_status))
new_pte = kvm_s2pte_mkexec(new_pte);
- invalidate_icache_guest_page(pfn, PAGE_SIZE);
- } else if (fault_status == FSC_PERM) {
- /* Preserve execute if XN was already cleared */
- if (stage2_is_exec(kvm, fault_ipa))
- new_pte = kvm_s2pte_mkexec(new_pte);
- }
ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, flags);
}
--
2.17.0
^ permalink raw reply related
* [PATCH v3 0/4] KVM: Support PUD hugepages at stage 2
From: Punit Agrawal @ 2018-05-14 14:43 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This patchset adds support for PUD hugepages at stage 2. This feature
is useful on cores that have support for large sized TLB mappings
(e.g., 1GB for 4K granule). Previous postings can be found at
[0][1][2].
Support is added to code that is shared between arm and arm64. Dummy
helpers for arm are provided as the port does not support PUD hugepage
sizes.
There is a small conflict with the series to add support for 52 bit
IPA[3]. The patches have been functionally tested on an A57 based
system. The patchset is based on v4.17-rc5 and incorporates feedback
received on the previous version.
Thanks,
Punit
v2 -> v3:
* Update vma_pagesize directly if THP [1/4]. Previsouly this was done
indirectly via hugetlb
* Added review tag [4/4]
v1 -> v2:
* Create helper to check if the page should have exec permission [1/4]
* Fix broken condition to detect THP hugepage [1/4]
* Fix in-correct hunk resulting from a rebase [4/4]
[0] https://www.spinics.net/lists/arm-kernel/msg628053.html
[1] https://lkml.org/lkml/2018/4/20/566
[2] https://lkml.org/lkml/2018/5/1/133
[3] https://lwn.net/Articles/750176/
Punit Agrawal (4):
KVM: arm/arm64: Share common code in user_mem_abort()
KVM: arm/arm64: Introduce helpers to manupulate page table entries
KVM: arm64: Support dirty page tracking for PUD hugepages
KVM: arm64: Add support for PUD hugepages at stage 2
arch/arm/include/asm/kvm_mmu.h | 40 ++++++++
arch/arm64/include/asm/kvm_mmu.h | 30 ++++++
arch/arm64/include/asm/pgtable-hwdef.h | 4 +
arch/arm64/include/asm/pgtable.h | 2 +
virt/kvm/arm/mmu.c | 121 +++++++++++++++++--------
5 files changed, 161 insertions(+), 36 deletions(-)
--
2.17.0
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox