* [PATCH v2 3/3] HID: i2c-hid: Align i2c_hid_set_power() retry with HID descriptor read
From: Kenny Levinsen @ 2024-04-23 12:07 UTC (permalink / raw)
To: Jiri Kosina, Dmitry Torokhov, Benjamin Tissoires,
Douglas Anderson, Hans de Goede, Maxime Ripard, Kai-Heng Feng,
Johan Hovold, linux-input, linux-kernel, Radoslaw Biernacki,
Lukasz Majczak
Cc: Kenny Levinsen
In-Reply-To: <20240423122518.34811-1-kl@kl.wtf>
The retry for HID descriptor and for power commands deals with the same
device quirk, so align the two.
Signed-off-by: Kenny Levinsen <kl@kl.wtf>
---
drivers/hid/i2c-hid/i2c-hid-core.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 252ccb3b71d1..749c0c036adb 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -391,25 +391,21 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state)
i2c_hid_dbg(ihid, "%s\n", __func__);
/*
- * Some devices require to send a command to wakeup before power on.
- * The call will get a return value (EREMOTEIO) but device will be
- * triggered and activated. After that, it goes like a normal device.
+ * Some STM-based devices need 400µs after a rising clock edge to wake
+ * from deep sleep, which in turn means that our first command will
+ * fail EREMOTEIO. Certain Weida Tech devices also need this wake-up.
+ * Retry the command in this case.
*/
- if (power_state == I2C_HID_PWR_ON) {
+ ret = i2c_hid_set_power_command(ihid, power_state);
+ if (ret == -EREMOTEIO && power_state == I2C_HID_PWR_ON) {
+ usleep_range(400, 500);
ret = i2c_hid_set_power_command(ihid, I2C_HID_PWR_ON);
-
- /* Device was already activated */
- if (!ret)
- goto set_pwr_exit;
}
- ret = i2c_hid_set_power_command(ihid, power_state);
if (ret)
dev_err(&ihid->client->dev,
"failed to change power setting.\n");
-set_pwr_exit:
-
/*
* The HID over I2C specification states that if a DEVICE needs time
* after the PWR_ON request, it should utilise CLOCK stretching.
--
2.44.0
^ permalink raw reply related
* [PATCH v2 2/3] HID: i2c-hid: Retry HID descriptor read to wake up STM devices
From: Kenny Levinsen @ 2024-04-23 12:07 UTC (permalink / raw)
To: Jiri Kosina, Dmitry Torokhov, Benjamin Tissoires,
Douglas Anderson, Hans de Goede, Maxime Ripard, Kai-Heng Feng,
Johan Hovold, linux-input, linux-kernel, Radoslaw Biernacki,
Lukasz Majczak
Cc: Kenny Levinsen
In-Reply-To: <20240423122518.34811-1-kl@kl.wtf>
Some STM microcontrollers need 400µs after rising clock edge in order to
come out of their deep sleep state. This in turn means that the first
command send to them timeout and fail with EREMOTEIO.
Retry once on EREMOTEIO to see if the device came alive, otherwise treat
the error as if no device was present like before.
Link: https://lore.kernel.org/all/20240405102436.3479210-1-lma@chromium.org/#t
Co-developed-by: Radoslaw Biernacki <rad@chromium.org>
Co-developed-by: Lukasz Majczak <lma@chromium.org>
Signed-off-by: Kenny Levinsen <kl@kl.wtf>
---
drivers/hid/i2c-hid/i2c-hid-core.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 515a80dbf6c7..252ccb3b71d1 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -1010,7 +1010,17 @@ static int __i2c_hid_core_probe(struct i2c_hid *ihid)
struct hid_device *hid = ihid->hid;
int ret;
+ /*
+ * Some STM-based devices need 400µs after a rising clock edge to wake
+ * from deep sleep, which in turn means that our first command will
+ * fail EREMOTEIO. Retry the command in this case.
+ */
ret = i2c_hid_fetch_hid_descriptor(ihid);
+ if (ret == -EREMOTEIO) {
+ usleep_range(400, 500);
+ ret = i2c_hid_fetch_hid_descriptor(ihid);
+ }
+
if (ret == -EREMOTEIO) {
i2c_hid_dbg(ihid, "nothing at this address: %d\n", ret);
return -ENXIO;
--
2.44.0
^ permalink raw reply related
* [PATCH v2 1/3] HID: i2c-hid: Rely on HID descriptor fetch to probe
From: Kenny Levinsen @ 2024-04-23 12:07 UTC (permalink / raw)
To: Jiri Kosina, Dmitry Torokhov, Benjamin Tissoires,
Douglas Anderson, Hans de Goede, Maxime Ripard, Kai-Heng Feng,
Johan Hovold, linux-input, linux-kernel, Radoslaw Biernacki,
Lukasz Majczak
Cc: Kenny Levinsen
In-Reply-To: <20240423122518.34811-1-kl@kl.wtf>
To avoid error messages when a device is not present, b3a81b6c4fc6 added
an initial bus probe using a dummy i2c_smbus_read_byte() call.
Without this probe, i2c_hid_fetch_hid_descriptor() will fail with
EREMOTEIO. Propagate the error up so the caller can handle EREMOTEIO
gracefully, and remove the probe as it is no longer necessary.
Signed-off-by: Kenny Levinsen <kl@kl.wtf>
---
drivers/hid/i2c-hid/i2c-hid-core.c | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 2df1ab3c31cc..515a80dbf6c7 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -894,12 +894,8 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid)
ihid->wHIDDescRegister,
&ihid->hdesc,
sizeof(ihid->hdesc));
- if (error) {
- dev_err(&ihid->client->dev,
- "failed to fetch HID descriptor: %d\n",
- error);
- return -ENODEV;
- }
+ if (error)
+ return error;
}
/* Validate the length of HID descriptor, the 4 first bytes:
@@ -1014,17 +1010,13 @@ static int __i2c_hid_core_probe(struct i2c_hid *ihid)
struct hid_device *hid = ihid->hid;
int ret;
- /* Make sure there is something at this address */
- ret = i2c_smbus_read_byte(client);
- if (ret < 0) {
+ ret = i2c_hid_fetch_hid_descriptor(ihid);
+ if (ret == -EREMOTEIO) {
i2c_hid_dbg(ihid, "nothing at this address: %d\n", ret);
return -ENXIO;
- }
-
- ret = i2c_hid_fetch_hid_descriptor(ihid);
- if (ret < 0) {
+ } else if (ret < 0) {
dev_err(&client->dev,
- "Failed to fetch the HID Descriptor\n");
+ "failed to fetch HID descriptor: %d\n", ret);
return ret;
}
--
2.44.0
^ permalink raw reply related
* [PATCH v2 0/3] HID: i2c-hid: Probe and wake device with HID descriptor fetch
From: Kenny Levinsen @ 2024-04-23 12:07 UTC (permalink / raw)
To: Jiri Kosina, Dmitry Torokhov, Benjamin Tissoires,
Douglas Anderson, Hans de Goede, Maxime Ripard, Kai-Heng Feng,
Johan Hovold, linux-input, linux-kernel, Radoslaw Biernacki,
Lukasz Majczak
This revises my previous patch[0] to add the sleep STM chips seem to
require as per discussion on the original patch from Lukasz and
Radoslaw[1]. I had initially tried without as it had not previously been
needed in the similar logic in our resume path, but it would appear that
this was simply luck as the affected device was woken up in that case by
"noise" from other sources.
To reiterate, the idea is to add the retry that Lukasz and Radoslaw
discovered was necessary, but do away with the dummy smbus probe and
instead just let HID descriptor fetch retry as needed, aligning more
with the existing retry logic used after resume while saving some noise
on the bus and speeding up initialization a tiny bit.
I added Co-developed-by tags, I hope that's appropriate. We should await
an ACK from Lukasz on it fixing their hardware quirk.
[0]: https://lore.kernel.org/all/20240415170517.18780-1-kl@kl.wtf/
[1]: https://lore.kernel.org/all/CAE5UKNqPA4SnnXyaB7Hwk0kcKMMQ_DUuxogDphnnvSGP8g1nAQ@mail.gmail.com/
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: input: sun4i-lradc-keys: Add H616 compatible
From: Krzysztof Kozlowski @ 2024-04-23 12:18 UTC (permalink / raw)
To: Andre Przywara, Hans de Goede, Dmitry Torokhov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland
Cc: linux-input, devicetree, linux-arm-kernel, linux-sunxi,
James McGregor
In-Reply-To: <20240423111502.6e068887@donnerap.manchester.arm.com>
On 23/04/2024 12:15, Andre Przywara wrote:
> On Mon, 22 Apr 2024 17:45:10 +0100
> Andre Przywara <andre.przywara@arm.com> wrote:
>
> Hi,
>
>> From: James McGregor <jamcgregor@protonmail.com>
>>
>> The Allwinner H616 SoC has an LRADC which is compatible with the
>> versions in existing SoCs.
>> Add a compatible string for H616, with the R329 fallback. This is the
>> same as the D1, so put them into an enum.
>>
>> Signed-off-by: James McGregor <jamcgregor@protonmail.com>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>
> Compared the descriptions in the manual between the R392 and the H616, they
> look the same:
>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Why do you review your own patches? Does it mean that you contribute
code which you did not review before?
This is odd process.
Your Review is implied by sending the patch. And you have there SoB
which indicates you sent it...
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2] HID: i2c-hid: wait for i2c touchpad deep-sleep to power-up transition
From: Łukasz Majczak @ 2024-04-23 11:32 UTC (permalink / raw)
To: Kenny Levinsen
Cc: Johan Hovold, benjamin.tissoires, dianders, dtor, hdegoede, jikos,
johan+linaro, kai.heng.feng, linux-input, linux-kernel, mripard,
rad
In-Reply-To: <535f3756-80d9-4599-bf73-a8785d18c399@kl.wtf>
On Mon, Apr 15, 2024 at 7:14 PM Kenny Levinsen <kl@kl.wtf> wrote:
>
> On 4/15/24 3:22 PM, Johan Hovold wrote:
> > We also use it for devices that may not be populated (e.g. an optional
> > touchscreen) and in that case we should not print anything.
>
> I sent a patch series[0] that shows how the same can be achieved
> (gracefully handling missing device + retry to wake device) without any
> smbus probes, following the existing retry style in i2c_hid_set_power().
>
> Radoslaw and Lukasz, it somehow felt rude to tag and blame you for code
> you hadn't seen yet. If my patch ends up favored we should make sure to
> have the appropriate attribution tags added...
>
> [0]: https://lore.kernel.org/all/20240415170517.18780-1-kl@kl.wtf/
>
Hi Kenny,
Unfortunately, your fix doesn't help in our case as there is no sleep
before the second call to
i2c_hid_fetch_hid_descriptor().
Saying more, this STM exposes two i2c addresses (connected physically
to the same bus)
one is the HID interface and the other one gives an access to the base
firmware and is
served by cros_ec_i2c driver and actually thanks to this driver,
touchpad is woken up because
In the resume path cros_ec_i2c "starts talking" through the i2c bus
thus generating a wakeup
interrupt.
So we need to send a dummy (or any other) transaction that may fail to
wake up the controller after
a whole chromebook rebook and on the resume path.
Best regards,
Lukasz
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: input: sun4i-lradc-keys: Add H616 compatible
From: Andre Przywara @ 2024-04-23 10:15 UTC (permalink / raw)
To: Hans de Goede, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-input, devicetree, linux-arm-kernel, linux-sunxi,
James McGregor
In-Reply-To: <20240422164511.2488261-2-andre.przywara@arm.com>
On Mon, 22 Apr 2024 17:45:10 +0100
Andre Przywara <andre.przywara@arm.com> wrote:
Hi,
> From: James McGregor <jamcgregor@protonmail.com>
>
> The Allwinner H616 SoC has an LRADC which is compatible with the
> versions in existing SoCs.
> Add a compatible string for H616, with the R329 fallback. This is the
> same as the D1, so put them into an enum.
>
> Signed-off-by: James McGregor <jamcgregor@protonmail.com>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Compared the descriptions in the manual between the R392 and the H616, they
look the same:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> ---
> .../bindings/input/allwinner,sun4i-a10-lradc-keys.yaml | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
> index c384bf0bb25d..8cb5820774e0 100644
> --- a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
> +++ b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
> @@ -22,7 +22,9 @@ properties:
> - const: allwinner,sun8i-a83t-r-lradc
> - const: allwinner,sun50i-r329-lradc
> - items:
> - - const: allwinner,sun20i-d1-lradc
> + - enum:
> + - allwinner,sun50i-h616-lradc
> + - allwinner,sun20i-d1-lradc
> - const: allwinner,sun50i-r329-lradc
>
> reg:
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: allwinner: h616: Add LRADC node
From: Andre Przywara @ 2024-04-23 10:11 UTC (permalink / raw)
To: Hans de Goede, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
James McGregor
Cc: linux-input, devicetree, linux-arm-kernel, linux-sunxi
In-Reply-To: <20240422164511.2488261-3-andre.przywara@arm.com>
On Mon, 22 Apr 2024 17:45:11 +0100
Andre Przywara <andre.przywara@arm.com> wrote:
Hi,
> From: James McGregor <jamcgregor@protonmail.com>
>
> Add a DT node for the Allwinner H616 LRADC describing the base address,
> interrupt, reset and clock gates.
>
> Signed-off-by: James McGregor <jamcgregor@protonmail.com>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
> arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> index a061b69c07c2..58fb28f83feb 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> @@ -125,6 +125,16 @@ sram_c: sram@28000 {
> };
> };
>
> + lradc: lradc@5070800 {
The nodes under the /soc node are ordered by their MMIO address, so this
needs to be moved down, after the THS node.
> + compatible = "allwinner,sun50i-h616-lradc",
> + "allwinner,sun50i-r329-lradc";
> + reg = <0x05070800 0x400>;
> + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&ccu CLK_BUS_KEYADC>;
> + resets = <&ccu RST_BUS_KEYADC>;
Compared against the manual, and can confirm the MMIO base address,
clock, reset and IRQ number.
Also the IP descriptions looks the same as in the R329 manual.
So with the node moved around:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> + status = "disabled";
> + };
> +
> ccu: clock@3001000 {
> compatible = "allwinner,sun50i-h616-ccu";
> reg = <0x03001000 0x1000>;
^ permalink raw reply
* Re: [PATCH 33/34] drivers: remove incorrect of_match_ptr/ACPI_PTR annotations
From: Peter Rosin @ 2024-04-23 9:52 UTC (permalink / raw)
To: Arnd Bergmann, linux-kernel, Corey Minyard, Peter Huewe,
Jarkko Sakkinen, Vinod Koul, Moritz Fischer, Wu Hao, Xu Yilun,
Jiri Kosina, Benjamin Tissoires, Michael Hennerich,
Dmitry Torokhov, Iyappan Subramanian, Keyur Chudgar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Yisen Zhuang, Salil Mehta, Tony Lindgren, Liam Girdwood,
Mark Brown, Alexandre Belloni, Xiang Chen, James E.J. Bottomley,
Martin K. Petersen, Greg Kroah-Hartman, Russell King, Jiri Slaby,
Jacky Huang, Shan-Chun Hung
Cc: Arnd Bergmann, Jason Gunthorpe, Tom Rix, Uwe Kleine-König,
Randy Dunlap, Rob Herring, Linus Walleij, openipmi-developer,
linux-integrity, dmaengine, linux-fpga, linux-input, linux-i2c,
netdev, linux-omap, linux-rtc, linux-scsi, linux-staging,
linux-serial, linux-arm-kernel
In-Reply-To: <20240403080702.3509288-34-arnd@kernel.org>
Hi!
2024-04-03 at 10:06, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> When building with CONFIG_OF and/or CONFIG_ACPI disabled but W=1 extra
> warnings enabled, a lot of driver cause a warning about an unused
> ID table:
>
> drivers/char/tpm/tpm_ftpm_tee.c:356:34: error: unused variable 'of_ftpm_tee_ids' [-Werror,-Wunused-const-variable]
> drivers/dma/img-mdc-dma.c:863:34: error: unused variable 'mdc_dma_of_match' [-Werror,-Wunused-const-variable]
> drivers/fpga/versal-fpga.c:62:34: error: unused variable 'versal_fpga_of_match' [-Werror,-Wunused-const-variable]
> drivers/i2c/muxes/i2c-mux-ltc4306.c:200:34: error: unused variable 'ltc4306_of_match' [-Werror,-Wunused-const-variable]
> drivers/i2c/muxes/i2c-mux-reg.c:242:34: error: unused variable 'i2c_mux_reg_of_match' [-Werror,-Wunused-const-variable]
> drivers/memory/pl353-smc.c:62:34: error: unused variable 'pl353_smc_supported_children' [-Werror,-Wunused-const-variable]
> drivers/regulator/pbias-regulator.c:136:34: error: unused variable 'pbias_of_match' [-Werror,-Wunused-const-variable]
> drivers/regulator/twl-regulator.c:552:34: error: unused variable 'twl_of_match' [-Werror,-Wunused-const-variable]
> drivers/regulator/twl6030-regulator.c:645:34: error: unused variable 'twl_of_match' [-Werror,-Wunused-const-variable]
> drivers/scsi/hisi_sas/hisi_sas_v2_hw.c:3635:36: error: unused variable 'sas_v2_acpi_match' [-Werror,-Wunused-const-variable]
> drivers/staging/pi433/pi433_if.c:1359:34: error: unused variable 'pi433_dt_ids' [-Werror,-Wunused-const-variable]
> drivers/tty/serial/amba-pl011.c:2945:34: error: unused variable 'sbsa_uart_of_match' [-Werror,-Wunused-const-variable]
>
> The fix is always to just remove the of_match_ptr() and ACPI_PTR() wrappers
> that remove the reference, rather than adding another #ifdef just for build
> testing for a configuration that doesn't matter in practice.
>
> I considered splitting up the large patch into per subsystem patches, but since
> it's really just the same thing everywhere it feels better to do it all at once.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> drivers/char/ipmi/ipmb_dev_int.c | 2 +-
> drivers/char/tpm/tpm_ftpm_tee.c | 2 +-
> drivers/dma/img-mdc-dma.c | 2 +-
> drivers/fpga/versal-fpga.c | 2 +-
> drivers/hid/hid-google-hammer.c | 6 ++----
> drivers/i2c/muxes/i2c-mux-ltc4306.c | 2 +-
> drivers/i2c/muxes/i2c-mux-reg.c | 2 +-
> drivers/input/touchscreen/wdt87xx_i2c.c | 2 +-
> drivers/mux/adg792a.c | 2 +-
> drivers/net/ethernet/apm/xgene-v2/main.c | 2 +-
> drivers/net/ethernet/hisilicon/hns_mdio.c | 2 +-
> drivers/regulator/pbias-regulator.c | 2 +-
> drivers/regulator/twl-regulator.c | 2 +-
> drivers/regulator/twl6030-regulator.c | 2 +-
> drivers/rtc/rtc-fsl-ftm-alarm.c | 2 +-
> drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +-
> drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +-
> drivers/staging/pi433/pi433_if.c | 2 +-
> drivers/tty/serial/amba-pl011.c | 6 +++---
> drivers/tty/serial/ma35d1_serial.c | 2 +-
> 20 files changed, 23 insertions(+), 25 deletions(-)
As far as I can tell, this triggers unconditional use of the
.of_match_table, and the compiler will have a harder time dropping
that data. However, the wasted data is negligible for the parts
touching "my" drivers:
drivers/i2c/muxes/i2c-mux-ltc4306.c
drivers/i2c/muxes/i2c-mux-reg.c
drivers/mux/adg729a.c
Acked-by: Peter Rosin <peda@axentia.se>
Cheers,
Peter
^ permalink raw reply
* Re: [PATCH 01/11] can: Add LIN bus as CAN abstraction
From: Christoph Fritz @ 2024-04-23 9:33 UTC (permalink / raw)
To: Jiri Slaby
Cc: Oliver Hartkopp, Marc Kleine-Budde, Vincent Mailhol,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Kosina,
Benjamin Tissoires, Greg Kroah-Hartman, Andreas Lauser,
Jonathan Corbet, linux-can, netdev, devicetree, linux-input,
linux-serial
In-Reply-To: <cf9109ac-f17b-4812-aa50-449b8fb9504e@kernel.org>
...
> > --- /dev/null
> > +++ b/drivers/net/can/lin.c
> ...> +static int lin_create_sysfs_id_files(struct net_device *ndev)
> > +{
> > + struct lin_device *ldev = netdev_priv(ndev);
> > + struct kobj_attribute *attr;
> > + int ret;
> > +
> > + for (int id = 0; id < LIN_NUM_IDS; id++) {
> > + ldev->sysfs_entries[id].ldev = ldev;
> > + attr = &ldev->sysfs_entries[id].attr;
> > + attr->attr.name = kasprintf(GFP_KERNEL, "%02x", id);
> > + if (!attr->attr.name)
> > + return -ENOMEM;
> > + attr->attr.mode = 0644;
> > + attr->show = lin_identifier_show;
> > + attr->store = lin_identifier_store;
> > +
> > + sysfs_attr_init(&attr->attr);
> > + ret = sysfs_create_file(ldev->lin_ids_kobj, &attr->attr);
> > + if (ret) {
> > + kfree(attr->attr.name);
> > + kfree(attr);
>
> Is the latter kfree() right? It appears not.
Thanks for the catch, it's wrong and will be removed in v2.
>
> > + return -ENOMEM;
> > + }
> > + }
> > +
> > + return 0;
> > +}
> ...
> > +static void lin_tx_work_handler(struct work_struct *ws)
> > +{
> > + struct lin_device *ldev = container_of(ws, struct lin_device,
> > + tx_work);
> > + struct net_device *ndev = ldev->ndev;
> > + struct canfd_frame *cfd;
> > + struct lin_frame lf;
> > +
> > + ldev->tx_busy = true;
>
> How is this store protected against reordering/race conditions?
Falsely it is not, like in mcp251x.c I'll add a mutex.
>
> > +
> > + cfd = (struct canfd_frame *)ldev->tx_skb->data;
> > + lf.checksum_mode = (cfd->can_id & LIN_ENHANCED_CKSUM_FLAG) ?
> > + LINBUS_ENHANCED : LINBUS_CLASSIC;
> > + lf.lin_id = (u8)(cfd->can_id & LIN_ID_MASK);
>
> Why is that cast necessary?
It's not.
>
> > + lf.len = min(cfd->len, LIN_MAX_DLEN);
> > + memcpy(lf.data, cfd->data, lf.len);
> > +
> > + ret = ldev->ldev_ops->ldo_tx(ldev, &lf);
> > + if (ret) {
> > + DEV_STATS_INC(ndev, tx_dropped);
> > + netdev_err_once(ndev, "transmission failure %d\n", ret);
> > + goto lin_tx_out;
>
> Where is this label?
In a later patch, let me fix the patchset accordingly.
>
> > + }
> > +
> > + DEV_STATS_INC(ndev, tx_packets);
> > + DEV_STATS_ADD(ndev, tx_bytes, lf.len);
> > + ldev->tx_busy = false;
>
> The same as above.
OK
>
> > + netif_wake_queue(ndev);
> > +}
> > +
> > +static netdev_tx_t lin_start_xmit(struct sk_buff *skb,
> > + struct net_device *ndev)
> > +{
> > + struct lin_device *ldev = netdev_priv(ndev);
> > +
> > + if (ldev->tx_busy)
> > + return NETDEV_TX_BUSY;
>
> And here too.
OK
>
> > +
> > + netif_stop_queue(ndev);
> > + ldev->tx_skb = skb;
> > + queue_work(ldev->wq, &ldev->tx_work);
> > +
> > + return NETDEV_TX_OK;
> > +}
> ...
> > +u8 lin_get_checksum(u8 pid, u8 n_of_bytes, const u8 *bytes,
> > + enum lin_checksum_mode cm)
> > +{
> > + uint csum = 0;
>
> Is "uint" of the preffered types in the kernel?
OK, no sysv 'uint', will be changed in another patch too
>
> > + int i;
> > +
> > + if (cm == LINBUS_ENHANCED)
> > + csum += pid;
> > +
> > + for (i = 0; i < n_of_bytes; i++) {
> > + csum += bytes[i];
> > + if (csum > 255)
> > + csum -= 255;
> > + }
> > +
> > + return (u8)(~csum & 0xff);
>
> Unnecessary cast?
Yes
>
> > +}
>
>
> > +int lin_rx(struct lin_device *ldev, const struct lin_frame *lf)
> > +{
> > + struct net_device *ndev = ldev->ndev;
> > + struct can_frame *cf;
> > + struct sk_buff *skb;
> > + int ret;
> > +
> > + if (!ndev)
> > + return -ENODEV;
>
> Is this racy or is this only a sanity check?
Just beeing cautious, I guess it can be removed
>
> > + netdev_dbg(ndev, "id:%02x, len:%u, data:%*ph, checksum:%02x (%s)\n",
> > + lf->lin_id, lf->len, lf->len, lf->data, lf->checksum,
> > + lf->checksum_mode ? "enhanced" : "classic");
> > +
> > + ret = lin_bump_rx_err(ldev, lf);
> > + if (ret) {
> > + DEV_STATS_INC(ndev, rx_dropped);
> > + return ret;
> > + }
> > +
> > + skb = alloc_can_skb(ndev, &cf);
> > + if (unlikely(!skb)) {
> > + DEV_STATS_INC(ndev, rx_dropped);
> > + return -ENOMEM;
> > + }
> > +
> > + cf->can_id = lf->lin_id;
> > + cf->len = min(lf->len, LIN_MAX_DLEN);
> > + memcpy(cf->data, lf->data, cf->len);
> > +
> > + DEV_STATS_INC(ndev, rx_packets);
> > + DEV_STATS_ADD(ndev, rx_bytes, cf->len);
> > +
> > + netif_receive_skb(skb);
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(lin_rx);
> > +
> > +static int lin_set_bittiming(struct net_device *ndev)
> > +{
> > + struct lin_device *ldev = netdev_priv(ndev);
> > + unsigned int bitrate;
> > + int ret;
> > +
> > + bitrate = ldev->can.bittiming.bitrate;
> > + ret = ldev->ldev_ops->update_bitrate(ldev, bitrate);
> > +
> > + return ret;
>
> No need for ret then.
Compact code, sure, will get adapted
>
> > +}
> > +
> > +static const u32 lin_bitrate[] = { 1200, 2400, 4800, 9600, 19200 };
> > +
> > +struct lin_device *register_lin(struct device *dev,
> > + const struct lin_device_ops *ldops)
> > +{
> > + struct net_device *ndev;
> > + struct lin_device *ldev;
> > + int ret;
> > +
> > + if (!ldops || !ldops->ldo_tx || !ldops->update_bitrate) {
> > + netdev_err(ndev, "missing mandatory lin_device_ops\n");
> > + return ERR_PTR(-EOPNOTSUPP);
>
> Would EINVAL fit better?
no preference over the other, will use EINVAL
>
> > + }
> > +
> > + ndev = alloc_candev(sizeof(struct lin_device), 1);
> > + if (!ndev)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + ldev = netdev_priv(ndev);
> > +
> > + ldev->ldev_ops = ldops;
> > + ndev->netdev_ops = &lin_netdev_ops;
> > + ndev->flags |= IFF_ECHO;
> > + ndev->mtu = CANFD_MTU;
> > + ldev->can.bittiming.bitrate = LIN_DEFAULT_BAUDRATE;
> > + ldev->can.ctrlmode = CAN_CTRLMODE_LIN;
> > + ldev->can.ctrlmode_supported = 0;
> > + ldev->can.bitrate_const = lin_bitrate;
> > + ldev->can.bitrate_const_cnt = ARRAY_SIZE(lin_bitrate);
> > + ldev->can.do_set_bittiming = lin_set_bittiming;
> > + ldev->ndev = ndev;
> > + ldev->dev = dev;
> > +
> > + SET_NETDEV_DEV(ndev, dev);
> > +
> > + ret = lin_set_bittiming(ndev);
> > + if (ret) {
> > + netdev_err(ndev, "set bittiming failed\n");
> > + goto exit_candev;
> > + }
> > +
> > + ret = register_candev(ndev);
> > + if (ret)
> > + goto exit_candev;
> > +
> > + ldev->lin_ids_kobj = kobject_create_and_add("lin_ids", &ndev->dev.kobj);
> > + if (!ldev->lin_ids_kobj) {
> > + netdev_err(ndev, "Failed to create sysfs directory\n");
> > + ret = -ENOMEM;
> > + goto exit_unreg;
> > + }
> > +
> > + ret = lin_create_sysfs_id_files(ndev);
> > + if (ret) {
> > + netdev_err(ndev, "Failed to create sysfs entry: %d\n", ret);
> > + goto exit_kobj_put;
> > + }
> > +
> > + ldev->wq = alloc_workqueue(dev_name(dev), WQ_FREEZABLE | WQ_MEM_RECLAIM,
> > + 0);
>
> It would be worth noting why you need your own WQ.
I'll add a comment stating:
/* Use workqueue as tx over USB/SPI/... may sleep */
>
> > + if (!ldev->wq)
> > + goto exit_rm_files;
> > +
> > + INIT_WORK(&ldev->tx_work, lin_tx_work_handler);
> > +
> > + netdev_info(ndev, "LIN initialized.\n");
> > +
> > + return ldev;
> > +
> > +exit_rm_files:
> > + lin_remove_sysfs_id_files(ndev);
> > +exit_kobj_put:
> > + kobject_put(ldev->lin_ids_kobj);
> > +exit_unreg:
> > + unregister_candev(ndev);
> > +exit_candev:
> > + free_candev(ndev);
> > + return ERR_PTR(ret);
> > +}
> > +EXPORT_SYMBOL_GPL(register_lin);
> > +
> > +void unregister_lin(struct lin_device *ldev)
> > +{
> > + struct net_device *ndev = ldev->ndev;
> > +
> > + lin_remove_sysfs_id_files(ndev);
> > + kobject_put(ldev->lin_ids_kobj);
> > + unregister_candev(ndev);
> > + destroy_workqueue(ldev->wq);
> > + free_candev(ndev);
> > +}
> > +EXPORT_SYMBOL_GPL(unregister_lin);
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_AUTHOR("Christoph Fritz <christoph.fritz@hexdev.de>");
> > +MODULE_DESCRIPTION("LIN bus to CAN glue driver");
> > diff --git a/include/net/lin.h b/include/net/lin.h
> > new file mode 100644
> > index 0000000000000..2fe16e142db96
> > --- /dev/null
> > +++ b/include/net/lin.h
> > @@ -0,0 +1,97 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/* Copyright (C) 2024 hexDEV GmbH - https://hexdev.de */
> > +
> > +#ifndef _NET_LIN_H_
> > +#define _NET_LIN_H_
> > +
> > +#include <linux/can/dev.h>
> > +#include <linux/device.h>
> > +
> > +#define LIN_NUM_IDS 64
> > +#define LIN_HEADER_SIZE 3
> > +#define LIN_MAX_DLEN 8
> > +
> > +#define LIN_MAX_BAUDRATE 20000
> > +#define LIN_MIN_BAUDRATE 1000
> > +#define LIN_DEFAULT_BAUDRATE 9600
> > +#define LIN_SYNC_BYTE 0x55
> > +
> > +#define LIN_ID_MASK 0x0000003FU
>
> GEN_MASK() ?
In the upcoming v2 I'll use:
#define LIN_ID_MASK GENMASK(5, 0)
>
> > +/* special ID descriptions for LIN */
> > +#define LIN_ENHANCED_CKSUM_FLAG 0x00000100U
> > +
> > +static const unsigned char lin_id_parity_tbl[] = {
>
> This ends up in every translation unit you include lin.h into. Bad.
This is also being used by a serial lin driver. But I guess most of the drivers have no need for this. Mhm, ... any ideas?
> And perhaps u8?
OK
>
> > + 0x80, 0xc0, 0x40, 0x00, 0xc0, 0x80, 0x00, 0x40,
> > + 0x00, 0x40, 0xc0, 0x80, 0x40, 0x00, 0x80, 0xc0,
> > + 0x40, 0x00, 0x80, 0xc0, 0x00, 0x40, 0xc0, 0x80,
> > + 0xc0, 0x80, 0x00, 0x40, 0x80, 0xc0, 0x40, 0x00,
> > + 0x00, 0x40, 0xc0, 0x80, 0x40, 0x00, 0x80, 0xc0,
> > + 0x80, 0xc0, 0x40, 0x00, 0xc0, 0x80, 0x00, 0x40,
> > + 0xc0, 0x80, 0x00, 0x40, 0x80, 0xc0, 0x40, 0x00,
> > + 0x40, 0x00, 0x80, 0xc0, 0x00, 0x40, 0xc0, 0x80,
> > +};
> > +
> > +#define LIN_GET_ID(PID) ((PID) & LIN_ID_MASK)
>
> FIELD_GET() ?
In the upcoming v2 I'll use:
#define LIN_GET_ID(PID) FIELD_GET(LIN_ID_MASK, PID)
>
> > +#define LIN_FORM_PID(ID) (LIN_GET_ID(ID) | \
> > + lin_id_parity_tbl[LIN_GET_ID(ID)])
> > +#define LIN_GET_PARITY(PID) ((PID) & ~LIN_ID_MASK)
> > +#define LIN_CHECK_PID(PID) (LIN_GET_PARITY(PID) == \
> > + LIN_GET_PARITY(LIN_FORM_PID(PID)))
>
Thanks for the feedback
-- Christoph
^ permalink raw reply
* Re: [PATCH 33/34] drivers: remove incorrect of_match_ptr/ACPI_PTR annotations
From: Xu Yilun @ 2024-04-23 7:33 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, Corey Minyard, Peter Huewe, Jarkko Sakkinen,
Vinod Koul, Moritz Fischer, Wu Hao, Xu Yilun, Jiri Kosina,
Benjamin Tissoires, Michael Hennerich, Peter Rosin,
Dmitry Torokhov, Iyappan Subramanian, Keyur Chudgar,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Yisen Zhuang, Salil Mehta, Tony Lindgren, Liam Girdwood,
Mark Brown, Alexandre Belloni, Xiang Chen, James E.J. Bottomley,
Martin K. Petersen, Greg Kroah-Hartman, Russell King, Jiri Slaby,
Jacky Huang, Shan-Chun Hung, Arnd Bergmann, Jason Gunthorpe,
Tom Rix, Uwe Kleine-König, Randy Dunlap, Rob Herring,
Linus Walleij, openipmi-developer, linux-integrity, dmaengine,
linux-fpga, linux-input, linux-i2c, netdev, linux-omap, linux-rtc,
linux-scsi, linux-staging, linux-serial, linux-arm-kernel
In-Reply-To: <20240403080702.3509288-34-arnd@kernel.org>
> diff --git a/drivers/fpga/versal-fpga.c b/drivers/fpga/versal-fpga.c
> index 3710e8f01be2..e6189106c468 100644
> --- a/drivers/fpga/versal-fpga.c
> +++ b/drivers/fpga/versal-fpga.c
> @@ -69,7 +69,7 @@ static struct platform_driver versal_fpga_driver = {
> .probe = versal_fpga_probe,
> .driver = {
> .name = "versal_fpga_manager",
> - .of_match_table = of_match_ptr(versal_fpga_of_match),
> + .of_match_table = versal_fpga_of_match,
For this part
Acked-by: Xu Yilun <yilun.xu@intel.com>
^ permalink raw reply
* Re: [PATCH 3/3] HID: bpf: lazy load the hid_tail_call entrypoint
From: Dan Carpenter @ 2024-04-23 7:10 UTC (permalink / raw)
To: oe-kbuild, Benjamin Tissoires, Jiri Kosina, Benjamin Tissoires
Cc: lkp, oe-kbuild-all, linux-input, linux-kernel, stable
In-Reply-To: <20240419-hid_bpf_lazy_skel-v1-3-9210bcd4b61c@kernel.org>
Hi Benjamin,
kernel test robot noticed the following build warnings:
url: https://github.com/intel-lab-lkp/linux/commits/Benjamin-Tissoires/HID-bpf-fix-a-comment-in-a-define/20240419-225110
base: b912cf042072e12e93faa874265b30cc0aa521b9
patch link: https://lore.kernel.org/r/20240419-hid_bpf_lazy_skel-v1-3-9210bcd4b61c%40kernel.org
patch subject: [PATCH 3/3] HID: bpf: lazy load the hid_tail_call entrypoint
config: i386-randconfig-141-20240423 (https://download.01.org/0day-ci/archive/20240423/202404231109.h2IRrMMD-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202404231109.h2IRrMMD-lkp@intel.com/
smatch warnings:
drivers/hid/bpf/hid_bpf_jmp_table.c:478 __hid_bpf_attach_prog() error: uninitialized symbol 'link'.
vim +/link +478 drivers/hid/bpf/hid_bpf_jmp_table.c
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 396 noinline int
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 397 __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
7cdd2108903a4e3 Benjamin Tissoires 2024-01-24 398 int prog_fd, struct bpf_prog *prog, __u32 flags)
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 399 {
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 400 struct bpf_link_primer link_primer;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 401 struct hid_bpf_link *link;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 402 struct hid_bpf_prog_entry *prog_entry;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 403 int cnt, err = -EINVAL, prog_table_idx = -1;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 404
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 405 mutex_lock(&hid_bpf_attach_lock);
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 406
60caa381da7dc38 Benjamin Tissoires 2024-04-19 407 if (!jmp_table.map) {
60caa381da7dc38 Benjamin Tissoires 2024-04-19 408 err = hid_bpf_preload_skel();
60caa381da7dc38 Benjamin Tissoires 2024-04-19 409 WARN_ONCE(err, "error while preloading HID BPF dispatcher: %d", err);
60caa381da7dc38 Benjamin Tissoires 2024-04-19 410 if (err)
60caa381da7dc38 Benjamin Tissoires 2024-04-19 411 goto err_unlock;
^^^^^^^^^^^^^^^^
link isn't initialized.
60caa381da7dc38 Benjamin Tissoires 2024-04-19 412 }
60caa381da7dc38 Benjamin Tissoires 2024-04-19 413
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 414 link = kzalloc(sizeof(*link), GFP_USER);
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 415 if (!link) {
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 416 err = -ENOMEM;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 417 goto err_unlock;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 418 }
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 419
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 420 bpf_link_init(&link->link, BPF_LINK_TYPE_UNSPEC,
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 421 &hid_bpf_link_lops, prog);
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 422
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 423 /* do not attach too many programs to a given HID device */
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 424 cnt = hid_bpf_program_count(hdev, NULL, prog_type);
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 425 if (cnt < 0) {
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 426 err = cnt;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 427 goto err_unlock;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 428 }
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 429
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 430 if (cnt >= hid_bpf_max_programs(prog_type)) {
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 431 err = -E2BIG;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 432 goto err_unlock;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 433 }
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 434
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 435 prog_table_idx = hid_bpf_insert_prog(prog_fd, prog);
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 436 /* if the jmp table is full, abort */
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 437 if (prog_table_idx < 0) {
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 438 err = prog_table_idx;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 439 goto err_unlock;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 440 }
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 441
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 442 if (flags & HID_BPF_FLAG_INSERT_HEAD) {
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 443 /* take the previous prog_entry slot */
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 444 jmp_table.tail = PREV(jmp_table.tail);
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 445 prog_entry = &jmp_table.entries[jmp_table.tail];
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 446 } else {
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 447 /* take the next prog_entry slot */
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 448 prog_entry = &jmp_table.entries[jmp_table.head];
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 449 jmp_table.head = NEXT(jmp_table.head);
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 450 }
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 451
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 452 /* we steal the ref here */
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 453 prog_entry->prog = prog;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 454 prog_entry->idx = prog_table_idx;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 455 prog_entry->hdev = hdev;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 456 prog_entry->type = prog_type;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 457
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 458 /* finally store the index in the device list */
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 459 err = hid_bpf_populate_hdev(hdev, prog_type);
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 460 if (err) {
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 461 hid_bpf_release_prog_at(prog_table_idx);
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 462 goto err_unlock;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 463 }
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 464
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 465 link->hid_table_index = prog_table_idx;
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 466
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 467 err = bpf_link_prime(&link->link, &link_primer);
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 468 if (err)
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 469 goto err_unlock;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 470
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 471 mutex_unlock(&hid_bpf_attach_lock);
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 472
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 473 return bpf_link_settle(&link_primer);
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 474
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 475 err_unlock:
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 476 mutex_unlock(&hid_bpf_attach_lock);
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 477
4b9a3f49f02bf68 Benjamin Tissoires 2023-01-13 @478 kfree(link);
^^^^
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 479
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 480 return err;
f5c27da4e3c8a2e Benjamin Tissoires 2022-11-03 481 }
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH 05/11] dt-bindings: net: can: Add serdev LIN bus dt bindings
From: Krzysztof Kozlowski @ 2024-04-23 6:55 UTC (permalink / raw)
To: Christoph Fritz, Oliver Hartkopp, Marc Kleine-Budde,
Vincent Mailhol, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jiri Kosina, Benjamin Tissoires, Greg Kroah-Hartman, Jiri Slaby
Cc: Andreas Lauser, Jonathan Corbet, linux-can, netdev, devicetree,
linux-input, linux-serial
In-Reply-To: <20240422065114.3185505-6-christoph.fritz@hexdev.de>
On 22/04/2024 08:51, Christoph Fritz wrote:
> Add documentation of device tree bindings for serdev UART LIN-Bus
> devices equipped with LIN transceivers.
>
> Signed-off-by: Christoph Fritz <christoph.fritz@hexdev.de>
> ---
Please test patches before sending...
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v8 7/7] x86/vmware: Add TDX hypercall support
From: Alexey Makhalov @ 2024-04-22 22:56 UTC (permalink / raw)
To: linux-kernel, virtualization, bp, hpa, dave.hansen, mingo, tglx
Cc: x86, netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
linux-graphics-maintainer, pv-drivers, timothym, akaher,
dri-devel, daniel, airlied, tzimmermann, mripard,
maarten.lankhorst, horms, kirill.shutemov, Alexey Makhalov,
Tim Merrifield, Nadav Amit
In-Reply-To: <20240422225656.10309-1-alexey.makhalov@broadcom.com>
VMware hypercalls use I/O port, VMCALL or VMMCALL instructions.
Add __tdx_hypercall path to support TDX guests.
No change in high bandwidth hypercalls, as only low bandwidth
ones are supported for TDX guests.
Co-developed-by: Tim Merrifield <tim.merrifield@broadcom.com>
Signed-off-by: Tim Merrifield <tim.merrifield@broadcom.com>
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Reviewed-by: Nadav Amit <nadav.amit@gmail.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
---
arch/x86/include/asm/vmware.h | 46 +++++++++++++++++++++++++++++++
arch/x86/kernel/cpu/vmware.c | 52 +++++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+)
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 84a31f579a30..cc79c14d1ac2 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -18,6 +18,12 @@
* arg2 - Hypercall command
* arg3 bits [15:0] - Port number, LB and direction flags
*
+ * - Low bandwidth TDX hypercalls (x86_64 only) are similar to LB
+ * hypercalls. They also have up to 6 input and 6 output on registers
+ * arguments, with different argument to register mapping:
+ * %r12 (arg0), %rbx (arg1), %r13 (arg2), %rdx (arg3),
+ * %rsi (arg4), %rdi (arg5).
+ *
* - High bandwidth (HB) hypercalls are I/O port based only. They have
* up to 7 input and 7 output arguments passed and returned using
* registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3),
@@ -54,12 +60,28 @@
#define VMWARE_CMD_GETHZ 45
#define VMWARE_CMD_GETVCPU_INFO 68
#define VMWARE_CMD_STEALCLOCK 91
+/*
+ * Hypercall command mask:
+ * bits [6:0] command, range [0, 127]
+ * bits [19:16] sub-command, range [0, 15]
+ */
+#define VMWARE_CMD_MASK 0xf007fU
#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0)
#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1)
extern u8 vmware_hypercall_mode;
+#define VMWARE_TDX_VENDOR_LEAF 0x1af7e4909ULL
+#define VMWARE_TDX_HCALL_FUNC 1
+
+extern unsigned long vmware_tdx_hypercall(unsigned long cmd,
+ unsigned long in1, unsigned long in3,
+ unsigned long in4, unsigned long in5,
+ uint32_t *out1, uint32_t *out2,
+ uint32_t *out3, uint32_t *out4,
+ uint32_t *out5);
+
/*
* The low bandwidth call. The low word of %edx is presumed to have OUT bit
* set. The high word of %edx may contain input data from the caller.
@@ -87,6 +109,10 @@ unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
{
unsigned long out0;
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -105,6 +131,10 @@ unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
{
unsigned long out0;
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+ out1, out2, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -124,6 +154,10 @@ unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
{
unsigned long out0;
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+ out1, out2, out3, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -143,6 +177,10 @@ unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
{
unsigned long out0;
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, in3, in4, in5,
+ NULL, out2, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=c" (*out2)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -165,6 +203,10 @@ unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
{
unsigned long out0;
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, in3, 0, 0,
+ NULL, out2, out3, out4, out5);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4),
"=D" (*out5)
@@ -186,6 +228,10 @@ unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
{
unsigned long out0;
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return vmware_tdx_hypercall(cmd, in1, in3, in4, in5,
+ out1, out2, out3, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 3aa1adaed18f..41309f03cb94 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -428,6 +428,58 @@ static bool __init vmware_legacy_x2apic_available(void)
(eax & BIT(VCPU_LEGACY_X2APIC));
}
+#ifdef CONFIG_INTEL_TDX_GUEST
+/*
+ * TDCALL[TDG.VP.VMCALL] uses %rax (arg0) and %rcx (arg2). Therefore,
+ * we remap those registers to %r12 and %r13, respectively.
+ */
+unsigned long vmware_tdx_hypercall(unsigned long cmd,
+ unsigned long in1, unsigned long in3,
+ unsigned long in4, unsigned long in5,
+ uint32_t *out1, uint32_t *out2,
+ uint32_t *out3, uint32_t *out4,
+ uint32_t *out5)
+{
+ struct tdx_module_args args;
+
+ if (!hypervisor_is_type(X86_HYPER_VMWARE)) {
+ pr_warn_once("Incorrect usage\n");
+ return ULONG_MAX;
+ }
+
+ if (cmd & ~VMWARE_CMD_MASK) {
+ pr_warn_once("Out of range command %lx\n", cmd);
+ return ULONG_MAX;
+ }
+
+ args.rbx = in1;
+ args.rdx = in3;
+ args.rsi = in4;
+ args.rdi = in5;
+ args.r10 = VMWARE_TDX_VENDOR_LEAF;
+ args.r11 = VMWARE_TDX_HCALL_FUNC;
+ args.r12 = VMWARE_HYPERVISOR_MAGIC;
+ args.r13 = cmd;
+ args.r15 = 0; /* CPL */
+
+ __tdx_hypercall(&args);
+
+ if (out1)
+ *out1 = args.rbx;
+ if (out2)
+ *out2 = args.r13;
+ if (out3)
+ *out3 = args.rdx;
+ if (out4)
+ *out4 = args.rsi;
+ if (out5)
+ *out5 = args.rdi;
+
+ return args.r12;
+}
+EXPORT_SYMBOL_GPL(vmware_tdx_hypercall);
+#endif
+
#ifdef CONFIG_AMD_MEM_ENCRYPT
static void vmware_sev_es_hcall_prepare(struct ghcb *ghcb,
struct pt_regs *regs)
--
2.39.0
^ permalink raw reply related
* [PATCH v8 6/7] x86/vmware: Undefine VMWARE_HYPERCALL
From: Alexey Makhalov @ 2024-04-22 22:56 UTC (permalink / raw)
To: linux-kernel, virtualization, bp, hpa, dave.hansen, mingo, tglx
Cc: x86, netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
linux-graphics-maintainer, pv-drivers, timothym, akaher,
dri-devel, daniel, airlied, tzimmermann, mripard,
maarten.lankhorst, horms, kirill.shutemov, Alexey Makhalov
In-Reply-To: <20240422225656.10309-1-alexey.makhalov@broadcom.com>
No more direct use of VMWARE_HYPERCALL macro should be allowed.
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
---
arch/x86/include/asm/vmware.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 2ac87068184a..84a31f579a30 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -273,5 +273,6 @@ unsigned long vmware_hypercall_hb_in(unsigned long cmd, unsigned long in2,
}
#undef VMW_BP_REG
#undef VMW_BP_CONSTRAINT
+#undef VMWARE_HYPERCALL
#endif
--
2.39.0
^ permalink raw reply related
* [PATCH v8 5/7] drm/vmwgfx: Use VMware hypercall API
From: Alexey Makhalov @ 2024-04-22 22:56 UTC (permalink / raw)
To: linux-kernel, virtualization, bp, hpa, dave.hansen, mingo, tglx
Cc: x86, netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
linux-graphics-maintainer, pv-drivers, timothym, akaher,
dri-devel, daniel, airlied, tzimmermann, mripard,
maarten.lankhorst, horms, kirill.shutemov, Alexey Makhalov,
Nadav Amit, Zack Rusin
In-Reply-To: <20240422225656.10309-1-alexey.makhalov@broadcom.com>
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code.
drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h: implement arm64 variant
of vmware_hypercall. And keep it here until introduction of ARM64
VMWare hypervisor interface.
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Reviewed-by: Nadav Amit <nadav.amit@gmail.com>
Reviewed-by: Zack Rusin <zack.rusin@broadcom.com>
---
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 173 +++++++------------
drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +++++++++++++++-------
drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h | 187 --------------------
3 files changed, 197 insertions(+), 360 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 2651fe0ef518..1f15990d3934 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -48,8 +48,6 @@
#define RETRIES 3
-#define VMW_HYPERVISOR_MAGIC 0x564D5868
-
#define VMW_PORT_CMD_MSG 30
#define VMW_PORT_CMD_HB_MSG 0
#define VMW_PORT_CMD_OPEN_CHANNEL (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG)
@@ -104,20 +102,18 @@ static const char* const mksstat_kern_name_desc[MKSSTAT_KERN_COUNT][2] =
*/
static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
{
- unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
+ u32 ecx, edx, esi, edi;
- VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
- (protocol | GUESTMSG_FLAG_COOKIE), si, di,
- 0,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall6(VMW_PORT_CMD_OPEN_CHANNEL,
+ (protocol | GUESTMSG_FLAG_COOKIE), 0,
+ &ecx, &edx, &esi, &edi);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
return -EINVAL;
channel->channel_id = HIGH_WORD(edx);
- channel->cookie_high = si;
- channel->cookie_low = di;
+ channel->cookie_high = esi;
+ channel->cookie_low = edi;
return 0;
}
@@ -133,17 +129,13 @@ static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
*/
static int vmw_close_channel(struct rpc_channel *channel)
{
- unsigned long eax, ebx, ecx, edx, si, di;
-
- /* Set up additional parameters */
- si = channel->cookie_high;
- di = channel->cookie_low;
+ u32 ecx;
- VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
- 0, si, di,
- channel->channel_id << 16,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall5(VMW_PORT_CMD_CLOSE_CHANNEL,
+ 0, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ &ecx);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
return -EINVAL;
@@ -163,24 +155,18 @@ static int vmw_close_channel(struct rpc_channel *channel)
static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
const char *msg, bool hb)
{
- unsigned long si, di, eax, ebx, ecx, edx;
+ u32 ebx, ecx;
unsigned long msg_len = strlen(msg);
/* HB port can't access encrypted memory. */
if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
- unsigned long bp = channel->cookie_high;
- u32 channel_id = (channel->channel_id << 16);
-
- si = (uintptr_t) msg;
- di = channel->cookie_low;
-
- VMW_PORT_HB_OUT(
+ vmware_hypercall_hb_out(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
- msg_len, si, di,
- VMWARE_HYPERVISOR_HB | channel_id |
- VMWARE_HYPERVISOR_OUT,
- VMW_HYPERVISOR_MAGIC, bp,
- eax, ebx, ecx, edx, si, di);
+ msg_len,
+ channel->channel_id << 16,
+ (uintptr_t) msg, channel->cookie_low,
+ channel->cookie_high,
+ &ebx);
return ebx;
}
@@ -194,14 +180,13 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
memcpy(&word, msg, bytes);
msg_len -= bytes;
msg += bytes;
- si = channel->cookie_high;
- di = channel->cookie_low;
-
- VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
- word, si, di,
- channel->channel_id << 16,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+
+ vmware_hypercall5(VMW_PORT_CMD_MSG |
+ (MSG_TYPE_SENDPAYLOAD << 16),
+ word, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ &ecx);
}
return ecx;
@@ -220,22 +205,17 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
unsigned long reply_len, bool hb)
{
- unsigned long si, di, eax, ebx, ecx, edx;
+ u32 ebx, ecx, edx;
/* HB port can't access encrypted memory */
if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
- unsigned long bp = channel->cookie_low;
- u32 channel_id = (channel->channel_id << 16);
-
- si = channel->cookie_high;
- di = (uintptr_t) reply;
-
- VMW_PORT_HB_IN(
+ vmware_hypercall_hb_in(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
- reply_len, si, di,
- VMWARE_HYPERVISOR_HB | channel_id,
- VMW_HYPERVISOR_MAGIC, bp,
- eax, ebx, ecx, edx, si, di);
+ reply_len,
+ channel->channel_id << 16,
+ channel->cookie_high,
+ (uintptr_t) reply, channel->cookie_low,
+ &ebx);
return ebx;
}
@@ -245,14 +225,13 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
while (reply_len) {
unsigned int bytes = min_t(unsigned long, reply_len, 4);
- si = channel->cookie_high;
- di = channel->cookie_low;
-
- VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16),
- MESSAGE_STATUS_SUCCESS, si, di,
- channel->channel_id << 16,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall7(VMW_PORT_CMD_MSG |
+ (MSG_TYPE_RECVPAYLOAD << 16),
+ MESSAGE_STATUS_SUCCESS,
+ channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ &ebx, &ecx, &edx);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
break;
@@ -276,22 +255,18 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
*/
static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
{
- unsigned long eax, ebx, ecx, edx, si, di;
+ u32 ebx, ecx;
size_t msg_len = strlen(msg);
int retries = 0;
while (retries < RETRIES) {
retries++;
- /* Set up additional parameters */
- si = channel->cookie_high;
- di = channel->cookie_low;
-
- VMW_PORT(VMW_PORT_CMD_SENDSIZE,
- msg_len, si, di,
- channel->channel_id << 16,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall5(VMW_PORT_CMD_SENDSIZE,
+ msg_len, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ &ecx);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
/* Expected success. Give up. */
@@ -329,7 +304,7 @@ STACK_FRAME_NON_STANDARD(vmw_send_msg);
static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
size_t *msg_len)
{
- unsigned long eax, ebx, ecx, edx, si, di;
+ u32 ebx, ecx, edx;
char *reply;
size_t reply_len;
int retries = 0;
@@ -341,15 +316,11 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
while (retries < RETRIES) {
retries++;
- /* Set up additional parameters */
- si = channel->cookie_high;
- di = channel->cookie_low;
-
- VMW_PORT(VMW_PORT_CMD_RECVSIZE,
- 0, si, di,
- channel->channel_id << 16,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall7(VMW_PORT_CMD_RECVSIZE,
+ 0, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ &ebx, &ecx, &edx);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
DRM_ERROR("Failed to get reply size for host message.\n");
@@ -384,16 +355,12 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
reply[reply_len] = '\0';
-
- /* Ack buffer */
- si = channel->cookie_high;
- di = channel->cookie_low;
-
- VMW_PORT(VMW_PORT_CMD_RECVSTATUS,
- MESSAGE_STATUS_SUCCESS, si, di,
- channel->channel_id << 16,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall5(VMW_PORT_CMD_RECVSTATUS,
+ MESSAGE_STATUS_SUCCESS,
+ channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ &ecx);
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
kfree(reply);
@@ -652,13 +619,7 @@ static inline void reset_ppn_array(PPN64 *arr, size_t size)
*/
static inline void hypervisor_ppn_reset_all(void)
{
- unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
-
- VMW_PORT(VMW_PORT_CMD_MKSGS_RESET,
- 0, si, di,
- 0,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall1(VMW_PORT_CMD_MKSGS_RESET, 0);
}
/**
@@ -669,13 +630,7 @@ static inline void hypervisor_ppn_reset_all(void)
*/
static inline void hypervisor_ppn_add(PPN64 pfn)
{
- unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
-
- VMW_PORT(VMW_PORT_CMD_MKSGS_ADD_PPN,
- (unsigned long)pfn, si, di,
- 0,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall1(VMW_PORT_CMD_MKSGS_ADD_PPN, (unsigned long)pfn);
}
/**
@@ -686,13 +641,7 @@ static inline void hypervisor_ppn_add(PPN64 pfn)
*/
static inline void hypervisor_ppn_remove(PPN64 pfn)
{
- unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
-
- VMW_PORT(VMW_PORT_CMD_MKSGS_REMOVE_PPN,
- (unsigned long)pfn, si, di,
- 0,
- VMW_HYPERVISOR_MAGIC,
- eax, ebx, ecx, edx, si, di);
+ vmware_hypercall1(VMW_PORT_CMD_MKSGS_REMOVE_PPN, (unsigned long)pfn);
}
#if IS_ENABLED(CONFIG_DRM_VMWGFX_MKSSTATS)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h b/drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h
index 4f40167ad61f..29bd0af83038 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h
@@ -34,6 +34,8 @@
#define VMWARE_HYPERVISOR_HB BIT(0)
#define VMWARE_HYPERVISOR_OUT BIT(1)
+#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
+
#define X86_IO_MAGIC 0x86
#define X86_IO_W7_SIZE_SHIFT 0
@@ -45,86 +47,159 @@
#define X86_IO_W7_IMM_SHIFT 5
#define X86_IO_W7_IMM_MASK (0xff << X86_IO_W7_IMM_SHIFT)
-static inline void vmw_port(unsigned long cmd, unsigned long in_ebx,
- unsigned long in_si, unsigned long in_di,
- unsigned long flags, unsigned long magic,
- unsigned long *eax, unsigned long *ebx,
- unsigned long *ecx, unsigned long *edx,
- unsigned long *si, unsigned long *di)
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
{
- register u64 x0 asm("x0") = magic;
- register u64 x1 asm("x1") = in_ebx;
+ register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
+ register u64 x1 asm("x1") = in1;
register u64 x2 asm("x2") = cmd;
- register u64 x3 asm("x3") = flags | VMWARE_HYPERVISOR_PORT;
- register u64 x4 asm("x4") = in_si;
- register u64 x5 asm("x5") = in_di;
+ register u64 x3 asm("x3") = VMWARE_HYPERVISOR_PORT;
+ register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
+ X86_IO_W7_WITH |
+ X86_IO_W7_DIR |
+ (2 << X86_IO_W7_SIZE_SHIFT);
+ asm_inline volatile (
+ "mrs xzr, mdccsr_el0; "
+ : "+r" (x0)
+ : "r" (x1), "r" (x2), "r" (x3), "r" (x7)
+ : "memory");
+
+ return x0;
+}
+
+static inline
+unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, uint32_t *out2)
+{
+ register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
+ register u64 x1 asm("x1") = in1;
+ register u64 x2 asm("x2") = cmd;
+ register u64 x3 asm("x3") = in3 | VMWARE_HYPERVISOR_PORT;
+ register u64 x4 asm("x4") = in4;
+ register u64 x5 asm("x5") = in5;
register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
X86_IO_W7_WITH |
X86_IO_W7_DIR |
(2 << X86_IO_W7_SIZE_SHIFT);
- asm volatile("mrs xzr, mdccsr_el0 \n\t"
- : "+r"(x0), "+r"(x1), "+r"(x2),
- "+r"(x3), "+r"(x4), "+r"(x5)
- : "r"(x7)
- :);
- *eax = x0;
- *ebx = x1;
- *ecx = x2;
- *edx = x3;
- *si = x4;
- *di = x5;
+ asm_inline volatile (
+ "mrs xzr, mdccsr_el0; "
+ : "+r" (x0), "+r" (x2)
+ : "r" (x1), "r" (x3), "r" (x4), "r" (x5), "r" (x7)
+ : "memory");
+
+ *out2 = x2;
+ return x0;
}
-static inline void vmw_port_hb(unsigned long cmd, unsigned long in_ecx,
- unsigned long in_si, unsigned long in_di,
- unsigned long flags, unsigned long magic,
- unsigned long bp, u32 w7dir,
- unsigned long *eax, unsigned long *ebx,
- unsigned long *ecx, unsigned long *edx,
- unsigned long *si, unsigned long *di)
+static inline
+unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
+ unsigned long in3, uint32_t *out2,
+ uint32_t *out3, uint32_t *out4,
+ uint32_t *out5)
{
- register u64 x0 asm("x0") = magic;
+ register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
+ register u64 x1 asm("x1") = in1;
+ register u64 x2 asm("x2") = cmd;
+ register u64 x3 asm("x3") = in3 | VMWARE_HYPERVISOR_PORT;
+ register u64 x4 asm("x4");
+ register u64 x5 asm("x5");
+ register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
+ X86_IO_W7_WITH |
+ X86_IO_W7_DIR |
+ (2 << X86_IO_W7_SIZE_SHIFT);
+
+ asm_inline volatile (
+ "mrs xzr, mdccsr_el0; "
+ : "+r" (x0), "+r" (x2), "+r" (x3), "=r" (x4), "=r" (x5)
+ : "r" (x1), "r" (x7)
+ : "memory");
+
+ *out2 = x2;
+ *out3 = x3;
+ *out4 = x4;
+ *out5 = x5;
+ return x0;
+}
+
+static inline
+unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, uint32_t *out1,
+ uint32_t *out2, uint32_t *out3)
+{
+ register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
+ register u64 x1 asm("x1") = in1;
+ register u64 x2 asm("x2") = cmd;
+ register u64 x3 asm("x3") = in3 | VMWARE_HYPERVISOR_PORT;
+ register u64 x4 asm("x4") = in4;
+ register u64 x5 asm("x5") = in5;
+ register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
+ X86_IO_W7_WITH |
+ X86_IO_W7_DIR |
+ (2 << X86_IO_W7_SIZE_SHIFT);
+
+ asm_inline volatile (
+ "mrs xzr, mdccsr_el0; "
+ : "+r" (x0), "+r" (x1), "+r" (x2), "+r" (x3)
+ : "r" (x4), "r" (x5), "r" (x7)
+ : "memory");
+
+ *out1 = x1;
+ *out2 = x2;
+ *out3 = x3;
+ return x0;
+}
+
+static inline
+unsigned long vmware_hypercall_hb(unsigned long cmd, unsigned long in2,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, unsigned long in6,
+ uint32_t *out1, int dir)
+{
+ register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
register u64 x1 asm("x1") = cmd;
- register u64 x2 asm("x2") = in_ecx;
- register u64 x3 asm("x3") = flags | VMWARE_HYPERVISOR_PORT_HB;
- register u64 x4 asm("x4") = in_si;
- register u64 x5 asm("x5") = in_di;
- register u64 x6 asm("x6") = bp;
+ register u64 x2 asm("x2") = in2;
+ register u64 x3 asm("x3") = in3 | VMWARE_HYPERVISOR_PORT_HB;
+ register u64 x4 asm("x4") = in4;
+ register u64 x5 asm("x5") = in5;
+ register u64 x6 asm("x6") = in6;
register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
X86_IO_W7_STR |
X86_IO_W7_WITH |
- w7dir;
-
- asm volatile("mrs xzr, mdccsr_el0 \n\t"
- : "+r"(x0), "+r"(x1), "+r"(x2),
- "+r"(x3), "+r"(x4), "+r"(x5)
- : "r"(x6), "r"(x7)
- :);
- *eax = x0;
- *ebx = x1;
- *ecx = x2;
- *edx = x3;
- *si = x4;
- *di = x5;
-}
+ dir;
-#define VMW_PORT(cmd, in_ebx, in_si, in_di, flags, magic, eax, ebx, ecx, edx, \
- si, di) \
- vmw_port(cmd, in_ebx, in_si, in_di, flags, magic, &eax, &ebx, &ecx, \
- &edx, &si, &di)
+ asm_inline volatile (
+ "mrs xzr, mdccsr_el0; "
+ : "+r" (x0), "+r" (x1)
+ : "r" (x2), "r" (x3), "r" (x4), "r" (x5),
+ "r" (x6), "r" (x7)
+ : "memory");
-#define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, flags, magic, bp, eax, ebx, \
- ecx, edx, si, di) \
- vmw_port_hb(cmd, in_ecx, in_si, in_di, flags, magic, bp, \
- 0, &eax, &ebx, &ecx, &edx, &si, &di)
+ *out1 = x1;
+ return x0;
+}
-#define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, flags, magic, bp, eax, ebx, \
- ecx, edx, si, di) \
- vmw_port_hb(cmd, in_ecx, in_si, in_di, flags, magic, bp, \
- X86_IO_W7_DIR, &eax, &ebx, &ecx, &edx, &si, &di)
+static inline
+unsigned long vmware_hypercall_hb_out(unsigned long cmd, unsigned long in2,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, unsigned long in6,
+ uint32_t *out1)
+{
+ return vmware_hypercall_hb(cmd, in2, in3, in4, in5, in6, out1, 0);
+}
+static inline
+unsigned long vmware_hypercall_hb_in(unsigned long cmd, unsigned long in2,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, unsigned long in6,
+ uint32_t *out1)
+{
+ return vmware_hypercall_hb(cmd, in2, in3, in4, in5, in6, out1,
+ X86_IO_W7_DIR);
+}
#endif
#endif /* _VMWGFX_MSG_ARM64_H */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h b/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h
index e040ee21ea1a..13304d34cc6e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h
@@ -37,193 +37,6 @@
#include <asm/vmware.h>
-/**
- * Hypervisor-specific bi-directional communication channel. Should never
- * execute on bare metal hardware. The caller must make sure to check for
- * supported hypervisor before using these macros.
- *
- * The last two parameters are both input and output and must be initialized.
- *
- * @cmd: [IN] Message Cmd
- * @in_ebx: [IN] Message Len, through EBX
- * @in_si: [IN] Input argument through SI, set to 0 if not used
- * @in_di: [IN] Input argument through DI, set ot 0 if not used
- * @flags: [IN] hypercall flags + [channel id]
- * @magic: [IN] hypervisor magic value
- * @eax: [OUT] value of EAX register
- * @ebx: [OUT] e.g. status from an HB message status command
- * @ecx: [OUT] e.g. status from a non-HB message status command
- * @edx: [OUT] e.g. channel id
- * @si: [OUT]
- * @di: [OUT]
- */
-#define VMW_PORT(cmd, in_ebx, in_si, in_di, \
- flags, magic, \
- eax, ebx, ecx, edx, si, di) \
-({ \
- asm volatile (VMWARE_HYPERCALL : \
- "=a"(eax), \
- "=b"(ebx), \
- "=c"(ecx), \
- "=d"(edx), \
- "=S"(si), \
- "=D"(di) : \
- [port] "i" (VMWARE_HYPERVISOR_PORT), \
- [mode] "m" (vmware_hypercall_mode), \
- "a"(magic), \
- "b"(in_ebx), \
- "c"(cmd), \
- "d"(flags), \
- "S"(in_si), \
- "D"(in_di) : \
- "memory"); \
-})
-
-
-/**
- * Hypervisor-specific bi-directional communication channel. Should never
- * execute on bare metal hardware. The caller must make sure to check for
- * supported hypervisor before using these macros.
- *
- * The last 3 parameters are both input and output and must be initialized.
- *
- * @cmd: [IN] Message Cmd
- * @in_ecx: [IN] Message Len, through ECX
- * @in_si: [IN] Input argument through SI, set to 0 if not used
- * @in_di: [IN] Input argument through DI, set to 0 if not used
- * @flags: [IN] hypercall flags + [channel id]
- * @magic: [IN] hypervisor magic value
- * @bp: [IN]
- * @eax: [OUT] value of EAX register
- * @ebx: [OUT] e.g. status from an HB message status command
- * @ecx: [OUT] e.g. status from a non-HB message status command
- * @edx: [OUT] e.g. channel id
- * @si: [OUT]
- * @di: [OUT]
- */
-#ifdef __x86_64__
-
-#define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \
- flags, magic, bp, \
- eax, ebx, ecx, edx, si, di) \
-({ \
- asm volatile ( \
- UNWIND_HINT_SAVE \
- "push %%rbp;" \
- UNWIND_HINT_UNDEFINED \
- "mov %12, %%rbp;" \
- "rep outsb;" \
- "pop %%rbp;" \
- UNWIND_HINT_RESTORE : \
- "=a"(eax), \
- "=b"(ebx), \
- "=c"(ecx), \
- "=d"(edx), \
- "=S"(si), \
- "=D"(di) : \
- "a"(magic), \
- "b"(cmd), \
- "c"(in_ecx), \
- "d"(flags), \
- "S"(in_si), \
- "D"(in_di), \
- "r"(bp) : \
- "memory", "cc"); \
-})
-
-
-#define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \
- flags, magic, bp, \
- eax, ebx, ecx, edx, si, di) \
-({ \
- asm volatile ( \
- UNWIND_HINT_SAVE \
- "push %%rbp;" \
- UNWIND_HINT_UNDEFINED \
- "mov %12, %%rbp;" \
- "rep insb;" \
- "pop %%rbp;" \
- UNWIND_HINT_RESTORE : \
- "=a"(eax), \
- "=b"(ebx), \
- "=c"(ecx), \
- "=d"(edx), \
- "=S"(si), \
- "=D"(di) : \
- "a"(magic), \
- "b"(cmd), \
- "c"(in_ecx), \
- "d"(flags), \
- "S"(in_si), \
- "D"(in_di), \
- "r"(bp) : \
- "memory", "cc"); \
-})
-
-#elif defined(__i386__)
-
-/*
- * In the 32-bit version of this macro, we store bp in a memory location
- * because we've ran out of registers.
- * Now we can't reference that memory location while we've modified
- * %esp or %ebp, so we first push it on the stack, just before we push
- * %ebp, and then when we need it we read it from the stack where we
- * just pushed it.
- */
-#define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \
- flags, magic, bp, \
- eax, ebx, ecx, edx, si, di) \
-({ \
- asm volatile ("push %12;" \
- "push %%ebp;" \
- "mov 0x04(%%esp), %%ebp;" \
- VMWARE_HYPERCALL_HB_OUT \
- "pop %%ebp;" \
- "add $0x04, %%esp;" : \
- "=a"(eax), \
- "=b"(ebx), \
- "=c"(ecx), \
- "=d"(edx), \
- "=S"(si), \
- "=D"(di) : \
- "a"(magic), \
- "b"(cmd), \
- "c"(in_ecx), \
- "d"(flags), \
- "S"(in_si), \
- "D"(in_di), \
- "m"(bp) : \
- "memory", "cc"); \
-})
-
-
-#define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \
- flags, magic, bp, \
- eax, ebx, ecx, edx, si, di) \
-({ \
- asm volatile ("push %12;" \
- "push %%ebp;" \
- "mov 0x04(%%esp), %%ebp;" \
- VMWARE_HYPERCALL_HB_IN \
- "pop %%ebp;" \
- "add $0x04, %%esp;" : \
- "=a"(eax), \
- "=b"(ebx), \
- "=c"(ecx), \
- "=d"(edx), \
- "=S"(si), \
- "=D"(di) : \
- "a"(magic), \
- "b"(cmd), \
- "c"(in_ecx), \
- "d"(flags), \
- "S"(in_si), \
- "D"(in_di), \
- "m"(bp) : \
- "memory", "cc"); \
-})
-#endif /* defined(__i386__) */
-
#endif /* defined(__i386__) || defined(__x86_64__) */
#endif /* _VMWGFX_MSG_X86_H */
--
2.39.0
^ permalink raw reply related
* [PATCH v8 4/7] input/vmmouse: Use VMware hypercall API
From: Alexey Makhalov @ 2024-04-22 22:56 UTC (permalink / raw)
To: linux-kernel, virtualization, bp, hpa, dave.hansen, mingo, tglx
Cc: x86, netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
linux-graphics-maintainer, pv-drivers, timothym, akaher,
dri-devel, daniel, airlied, tzimmermann, mripard,
maarten.lankhorst, horms, kirill.shutemov, Alexey Makhalov,
Nadav Amit, Zack Rusin
In-Reply-To: <20240422225656.10309-1-alexey.makhalov@broadcom.com>
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code. No functional changes intended.
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Reviewed-by: Nadav Amit <nadav.amit@gmail.com>
Reviewed-by: Zack Rusin <zack.rusin@broadcom.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/vmmouse.c | 78 ++++++++++-------------------------
1 file changed, 22 insertions(+), 56 deletions(-)
diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c
index ad94c835ee66..fb1d986a6895 100644
--- a/drivers/input/mouse/vmmouse.c
+++ b/drivers/input/mouse/vmmouse.c
@@ -21,19 +21,16 @@
#include "psmouse.h"
#include "vmmouse.h"
-#define VMMOUSE_PROTO_MAGIC 0x564D5868U
-
/*
* Main commands supported by the vmmouse hypervisor port.
*/
-#define VMMOUSE_PROTO_CMD_GETVERSION 10
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA 39
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS 40
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND 41
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT 86
+#define VMWARE_CMD_ABSPOINTER_DATA 39
+#define VMWARE_CMD_ABSPOINTER_STATUS 40
+#define VMWARE_CMD_ABSPOINTER_COMMAND 41
+#define VMWARE_CMD_ABSPOINTER_RESTRICT 86
/*
- * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
+ * Subcommands for VMWARE_CMD_ABSPOINTER_COMMAND
*/
#define VMMOUSE_CMD_ENABLE 0x45414552U
#define VMMOUSE_CMD_DISABLE 0x000000f5U
@@ -76,30 +73,6 @@ struct vmmouse_data {
char dev_name[128];
};
-/*
- * Hypervisor-specific bi-directional communication channel
- * implementing the vmmouse protocol. Should never execute on
- * bare metal hardware.
- */
-#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \
-({ \
- unsigned long __dummy1, __dummy2; \
- __asm__ __volatile__ (VMWARE_HYPERCALL : \
- "=a"(out1), \
- "=b"(out2), \
- "=c"(out3), \
- "=d"(out4), \
- "=S"(__dummy1), \
- "=D"(__dummy2) : \
- [port] "i" (VMWARE_HYPERVISOR_PORT), \
- [mode] "m" (vmware_hypercall_mode), \
- "a"(VMMOUSE_PROTO_MAGIC), \
- "b"(in1), \
- "c"(VMMOUSE_PROTO_CMD_##cmd), \
- "d"(0) : \
- "memory"); \
-})
-
/**
* vmmouse_report_button - report button state on the correct input device
*
@@ -147,14 +120,12 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse)
struct input_dev *abs_dev = priv->abs_dev;
struct input_dev *pref_dev;
u32 status, x, y, z;
- u32 dummy1, dummy2, dummy3;
unsigned int queue_length;
unsigned int count = 255;
while (count--) {
/* See if we have motion data. */
- VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
- status, dummy1, dummy2, dummy3);
+ status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) {
psmouse_err(psmouse, "failed to fetch status data\n");
/*
@@ -174,7 +145,8 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse)
}
/* Now get it */
- VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z);
+ status = vmware_hypercall4(VMWARE_CMD_ABSPOINTER_DATA, 4,
+ &x, &y, &z);
/*
* And report what we've got. Prefer to report button
@@ -249,14 +221,10 @@ static psmouse_ret_t vmmouse_process_byte(struct psmouse *psmouse)
static void vmmouse_disable(struct psmouse *psmouse)
{
u32 status;
- u32 dummy1, dummy2, dummy3, dummy4;
-
- VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE,
- dummy1, dummy2, dummy3, dummy4);
- VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
- status, dummy1, dummy2, dummy3);
+ vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE);
+ status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR)
psmouse_warn(psmouse, "failed to disable vmmouse device\n");
}
@@ -273,26 +241,24 @@ static void vmmouse_disable(struct psmouse *psmouse)
static int vmmouse_enable(struct psmouse *psmouse)
{
u32 status, version;
- u32 dummy1, dummy2, dummy3, dummy4;
/*
* Try enabling the device. If successful, we should be able to
* read valid version ID back from it.
*/
- VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE,
- dummy1, dummy2, dummy3, dummy4);
+ vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE);
/*
* See if version ID can be retrieved.
*/
- VMMOUSE_CMD(ABSPOINTER_STATUS, 0, status, dummy1, dummy2, dummy3);
+ status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & 0x0000ffff) == 0) {
psmouse_dbg(psmouse, "empty flags - assuming no device\n");
return -ENXIO;
}
- VMMOUSE_CMD(ABSPOINTER_DATA, 1 /* single item */,
- version, dummy1, dummy2, dummy3);
+ version = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_DATA,
+ 1 /* single item */);
if (version != VMMOUSE_VERSION_ID) {
psmouse_dbg(psmouse, "Unexpected version value: %u vs %u\n",
(unsigned) version, VMMOUSE_VERSION_ID);
@@ -303,11 +269,11 @@ static int vmmouse_enable(struct psmouse *psmouse)
/*
* Restrict ioport access, if possible.
*/
- VMMOUSE_CMD(ABSPOINTER_RESTRICT, VMMOUSE_RESTRICT_CPL0,
- dummy1, dummy2, dummy3, dummy4);
+ vmware_hypercall1(VMWARE_CMD_ABSPOINTER_RESTRICT,
+ VMMOUSE_RESTRICT_CPL0);
- VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_REQUEST_ABSOLUTE,
- dummy1, dummy2, dummy3, dummy4);
+ vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND,
+ VMMOUSE_CMD_REQUEST_ABSOLUTE);
return 0;
}
@@ -344,7 +310,7 @@ static bool vmmouse_check_hypervisor(void)
*/
int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
{
- u32 response, version, dummy1, dummy2;
+ u32 response, version, type;
if (!vmmouse_check_hypervisor()) {
psmouse_dbg(psmouse,
@@ -353,9 +319,9 @@ int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
}
/* Check if the device is present */
- response = ~VMMOUSE_PROTO_MAGIC;
- VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2);
- if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU)
+ response = ~VMWARE_HYPERVISOR_MAGIC;
+ version = vmware_hypercall3(VMWARE_CMD_GETVERSION, 0, &response, &type);
+ if (response != VMWARE_HYPERVISOR_MAGIC || version == 0xffffffffU)
return -ENXIO;
if (set_properties) {
--
2.39.0
^ permalink raw reply related
* [PATCH v8 3/7] ptp/vmware: Use VMware hypercall API
From: Alexey Makhalov @ 2024-04-22 22:56 UTC (permalink / raw)
To: linux-kernel, virtualization, bp, hpa, dave.hansen, mingo, tglx
Cc: x86, netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
linux-graphics-maintainer, pv-drivers, timothym, akaher,
dri-devel, daniel, airlied, tzimmermann, mripard,
maarten.lankhorst, horms, kirill.shutemov, Alexey Makhalov,
Nadav Amit, Jeff Sipek
In-Reply-To: <20240422225656.10309-1-alexey.makhalov@broadcom.com>
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code. No functional changes intended.
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Reviewed-by: Nadav Amit <nadav.amit@gmail.com>
Reviewed-by: Jeff Sipek <jsipek@vmware.com>
---
drivers/ptp/ptp_vmw.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/ptp/ptp_vmw.c b/drivers/ptp/ptp_vmw.c
index 279d191d2df9..e5bb521b9b82 100644
--- a/drivers/ptp/ptp_vmw.c
+++ b/drivers/ptp/ptp_vmw.c
@@ -14,7 +14,6 @@
#include <asm/hypervisor.h>
#include <asm/vmware.h>
-#define VMWARE_MAGIC 0x564D5868
#define VMWARE_CMD_PCLK(nr) ((nr << 16) | 97)
#define VMWARE_CMD_PCLK_GETTIME VMWARE_CMD_PCLK(0)
@@ -24,17 +23,10 @@ static struct ptp_clock *ptp_vmw_clock;
static int ptp_vmw_pclk_read(u64 *ns)
{
- u32 ret, nsec_hi, nsec_lo, unused1, unused2, unused3;
-
- asm volatile (VMWARE_HYPERCALL :
- "=a"(ret), "=b"(nsec_hi), "=c"(nsec_lo), "=d"(unused1),
- "=S"(unused2), "=D"(unused3) :
- [port] "i" (VMWARE_HYPERVISOR_PORT),
- [mode] "m" (vmware_hypercall_mode),
- "a"(VMWARE_MAGIC), "b"(0),
- "c"(VMWARE_CMD_PCLK_GETTIME), "d"(0) :
- "memory");
+ u32 ret, nsec_hi, nsec_lo;
+ ret = vmware_hypercall3(VMWARE_CMD_PCLK_GETTIME, 0,
+ &nsec_hi, &nsec_lo);
if (ret == 0)
*ns = ((u64)nsec_hi << 32) | nsec_lo;
return ret;
--
2.39.0
^ permalink raw reply related
* [PATCH v8 2/7] x86/vmware: Introduce VMware hypercall API
From: Alexey Makhalov @ 2024-04-22 22:56 UTC (permalink / raw)
To: linux-kernel, virtualization, bp, hpa, dave.hansen, mingo, tglx
Cc: x86, netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
linux-graphics-maintainer, pv-drivers, timothym, akaher,
dri-devel, daniel, airlied, tzimmermann, mripard,
maarten.lankhorst, horms, kirill.shutemov, Alexey Makhalov,
Nadav Amit, Jeff Sipek
In-Reply-To: <20240422225656.10309-1-alexey.makhalov@broadcom.com>
Introduce vmware_hypercall family of functions. It is a common
implementation to be used by the VMware guest code and virtual
device drivers in architecture independent manner.
The API consists of vmware_hypercallX and vmware_hypercall_hb_{out,in}
set of functions by analogy with KVM hypercall API. Architecture
specific implementation is hidden inside.
It will simplify future enhancements in VMware hypercalls such
as SEV-ES and TDX related changes without needs to modify a
caller in device drivers code.
Current implementation extends an idea from commit bac7b4e84323
("x86/vmware: Update platform detection code for VMCALL/VMMCALL
hypercalls") to have a slow, but safe path in VMWARE_HYPERCALL
earlier during the boot when alternatives are not yet applied.
This logic was inherited from VMWARE_CMD from the commit mentioned
above. Default alternative code was optimized by size to reduce
excessive nop alignment once alternatives are applied. Total
default code size is 26 bytes, in worse case (3 bytes alternative)
remaining 23 bytes will be aligned by only 3 long NOP instructions.
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Reviewed-by: Nadav Amit <nadav.amit@gmail.com>
Reviewed-by: Jeff Sipek <jsipek@vmware.com>
---
arch/x86/include/asm/vmware.h | 288 +++++++++++++++++++-----
arch/x86/kernel/cpu/vmware.c | 35 ++-
drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h | 6 +-
drivers/input/mouse/vmmouse.c | 2 +
drivers/ptp/ptp_vmw.c | 2 +
5 files changed, 252 insertions(+), 81 deletions(-)
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index de2533337611..2ac87068184a 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -7,14 +7,37 @@
#include <linux/stringify.h>
/*
- * The hypercall definitions differ in the low word of the %edx argument
+ * VMware hypercall ABI.
+ *
+ * - Low bandwidth (LB) hypercalls (I/O port based, vmcall and vmmcall)
+ * have up to 6 input and 6 output arguments passed and returned using
+ * registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3),
+ * %esi (arg4), %edi (arg5).
+ * The following input arguments must be initialized by the caller:
+ * arg0 - VMWARE_HYPERVISOR_MAGIC
+ * arg2 - Hypercall command
+ * arg3 bits [15:0] - Port number, LB and direction flags
+ *
+ * - High bandwidth (HB) hypercalls are I/O port based only. They have
+ * up to 7 input and 7 output arguments passed and returned using
+ * registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3),
+ * %esi (arg4), %edi (arg5), %ebp (arg6).
+ * The following input arguments must be initialized by the caller:
+ * arg0 - VMWARE_HYPERVISOR_MAGIC
+ * arg1 - Hypercall command
+ * arg3 bits [15:0] - Port number, HB and direction flags
+ *
+ * For compatibility purposes, x86_64 systems use only lower 32 bits
+ * for input and output arguments.
+ *
+ * The hypercall definitions differ in the low word of the %edx (arg3)
* in the following way: the old I/O port based interface uses the port
* number to distinguish between high- and low bandwidth versions, and
* uses IN/OUT instructions to define transfer direction.
*
* The new vmcall interface instead uses a set of flags to select
* bandwidth mode and transfer direction. The flags should be loaded
- * into %dx by any user and are automatically replaced by the port
+ * into arg3 by any user and are automatically replaced by the port
* number if the I/O port method is used.
*/
@@ -37,69 +60,218 @@
extern u8 vmware_hypercall_mode;
-/* The low bandwidth call. The low word of edx is presumed clear. */
-#define VMWARE_HYPERCALL \
- ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \
- "inl (%%dx), %%eax", \
- "vmcall", X86_FEATURE_VMCALL, \
- "vmmcall", X86_FEATURE_VMW_VMMCALL)
-
/*
- * The high bandwidth out call. The low word of edx is presumed to have the
- * HB and OUT bits set.
+ * The low bandwidth call. The low word of %edx is presumed to have OUT bit
+ * set. The high word of %edx may contain input data from the caller.
*/
-#define VMWARE_HYPERCALL_HB_OUT \
- ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \
- "rep outsb", \
+#define VMWARE_HYPERCALL \
+ ALTERNATIVE_3("cmpb $" \
+ __stringify(CPUID_VMWARE_FEATURES_ECX_VMMCALL) \
+ ", %[mode]\n\t" \
+ "jg 2f\n\t" \
+ "je 1f\n\t" \
+ "movw %[port], %%dx\n\t" \
+ "inl (%%dx), %%eax\n\t" \
+ "jmp 3f\n\t" \
+ "1: vmmcall\n\t" \
+ "jmp 3f\n\t" \
+ "2: vmcall\n\t" \
+ "3:\n\t", \
+ "movw %[port], %%dx\n\t" \
+ "inl (%%dx), %%eax", X86_FEATURE_HYPERVISOR, \
"vmcall", X86_FEATURE_VMCALL, \
"vmmcall", X86_FEATURE_VMW_VMMCALL)
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
+{
+ unsigned long out0;
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+ uint32_t *out1, uint32_t *out2)
+{
+ unsigned long out0;
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=b" (*out1), "=c" (*out2)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+ uint32_t *out1, uint32_t *out2,
+ uint32_t *out3)
+{
+ unsigned long out0;
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, uint32_t *out2)
+{
+ unsigned long out0;
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=c" (*out2)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3),
+ "S" (in4),
+ "D" (in5)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
+ unsigned long in3, uint32_t *out2,
+ uint32_t *out3, uint32_t *out4,
+ uint32_t *out5)
+{
+ unsigned long out0;
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4),
+ "=D" (*out5)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, uint32_t *out1,
+ uint32_t *out2, uint32_t *out3)
+{
+ unsigned long out0;
+
+ asm_inline volatile (VMWARE_HYPERCALL
+ : "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
+ : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (in3),
+ "S" (in4),
+ "D" (in5)
+ : "cc", "memory");
+ return out0;
+}
+
+
+#ifdef CONFIG_X86_64
+#define VMW_BP_REG "%%rbp"
+#define VMW_BP_CONSTRAINT "r"
+#else
+#define VMW_BP_REG "%%ebp"
+#define VMW_BP_CONSTRAINT "m"
+#endif
+
/*
- * The high bandwidth in call. The low word of edx is presumed to have the
- * HB bit set.
+ * High bandwidth calls are not supported on encrypted memory guests.
+ * The caller should check cc_platform_has(CC_ATTR_MEM_ENCRYPT) and use
+ * low bandwidth hypercall it memory encryption is set.
+ * This assumption simplifies HB hypercall impementation to just I/O port
+ * based approach without alternative patching.
*/
-#define VMWARE_HYPERCALL_HB_IN \
- ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \
- "rep insb", \
- "vmcall", X86_FEATURE_VMCALL, \
- "vmmcall", X86_FEATURE_VMW_VMMCALL)
+static inline
+unsigned long vmware_hypercall_hb_out(unsigned long cmd, unsigned long in2,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, unsigned long in6,
+ uint32_t *out1)
+{
+ unsigned long out0;
+
+ asm_inline volatile (
+ UNWIND_HINT_SAVE
+ "push " VMW_BP_REG "\n\t"
+ UNWIND_HINT_UNDEFINED
+ "mov %[in6], " VMW_BP_REG "\n\t"
+ "rep outsb\n\t"
+ "pop " VMW_BP_REG "\n\t"
+ UNWIND_HINT_RESTORE
+ : "=a" (out0), "=b" (*out1)
+ : "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (cmd),
+ "c" (in2),
+ "d" (in3 | VMWARE_HYPERVISOR_PORT_HB),
+ "S" (in4),
+ "D" (in5),
+ [in6] VMW_BP_CONSTRAINT (in6)
+ : "cc", "memory");
+ return out0;
+}
+
+static inline
+unsigned long vmware_hypercall_hb_in(unsigned long cmd, unsigned long in2,
+ unsigned long in3, unsigned long in4,
+ unsigned long in5, unsigned long in6,
+ uint32_t *out1)
+{
+ unsigned long out0;
-#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \
- __asm__("inl (%%dx), %%eax" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \
- __asm__("vmcall" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(0), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx) \
- __asm__("vmmcall" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(0), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do { \
- switch (vmware_hypercall_mode) { \
- case CPUID_VMWARE_FEATURES_ECX_VMCALL: \
- VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \
- break; \
- case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \
- VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx); \
- break; \
- default: \
- VMWARE_PORT(cmd, eax, ebx, ecx, edx); \
- break; \
- } \
- } while (0)
+ asm_inline volatile (
+ UNWIND_HINT_SAVE
+ "push " VMW_BP_REG "\n\t"
+ UNWIND_HINT_UNDEFINED
+ "mov %[in6], " VMW_BP_REG "\n\t"
+ "rep insb\n\t"
+ "pop " VMW_BP_REG "\n\t"
+ UNWIND_HINT_RESTORE
+ : "=a" (out0), "=b" (*out1)
+ : "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (cmd),
+ "c" (in2),
+ "d" (in3 | VMWARE_HYPERVISOR_PORT_HB),
+ "S" (in4),
+ "D" (in5),
+ [in6] VMW_BP_CONSTRAINT (in6)
+ : "cc", "memory");
+ return out0;
+}
+#undef VMW_BP_REG
+#undef VMW_BP_CONSTRAINT
#endif
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 4db8e1daa4a1..3aa1adaed18f 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -67,9 +67,10 @@ EXPORT_SYMBOL_GPL(vmware_hypercall_mode);
static inline int __vmware_platform(void)
{
- uint32_t eax, ebx, ecx, edx;
- VMWARE_CMD(GETVERSION, eax, ebx, ecx, edx);
- return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
+ uint32_t eax, ebx, ecx;
+
+ eax = vmware_hypercall3(VMWARE_CMD_GETVERSION, 0, &ebx, &ecx);
+ return eax != UINT_MAX && ebx == VMWARE_HYPERVISOR_MAGIC;
}
static unsigned long vmware_get_tsc_khz(void)
@@ -121,21 +122,12 @@ static void __init vmware_cyc2ns_setup(void)
pr_info("using clock offset of %llu ns\n", d->cyc2ns_offset);
}
-static int vmware_cmd_stealclock(uint32_t arg1, uint32_t arg2)
+static int vmware_cmd_stealclock(uint32_t addr_hi, uint32_t addr_lo)
{
- uint32_t result, info;
-
- asm volatile (VMWARE_HYPERCALL :
- "=a"(result),
- "=c"(info) :
- "a"(VMWARE_HYPERVISOR_MAGIC),
- "b"(0),
- "c"(VMWARE_CMD_STEALCLOCK),
- "d"(0),
- "S"(arg1),
- "D"(arg2) :
- "memory");
- return result;
+ uint32_t info;
+
+ return vmware_hypercall5(VMWARE_CMD_STEALCLOCK, 0, 0, addr_hi, addr_lo,
+ &info);
}
static bool stealclock_enable(phys_addr_t pa)
@@ -344,10 +336,10 @@ static void __init vmware_set_capabilities(void)
static void __init vmware_platform_setup(void)
{
- uint32_t eax, ebx, ecx, edx;
+ uint32_t eax, ebx, ecx;
uint64_t lpj, tsc_khz;
- VMWARE_CMD(GETHZ, eax, ebx, ecx, edx);
+ eax = vmware_hypercall3(VMWARE_CMD_GETHZ, UINT_MAX, &ebx, &ecx);
if (ebx != UINT_MAX) {
lpj = tsc_khz = eax | (((uint64_t)ebx) << 32);
@@ -429,8 +421,9 @@ static uint32_t __init vmware_platform(void)
/* Checks if hypervisor supports x2apic without VT-D interrupt remapping. */
static bool __init vmware_legacy_x2apic_available(void)
{
- uint32_t eax, ebx, ecx, edx;
- VMWARE_CMD(GETVCPU_INFO, eax, ebx, ecx, edx);
+ uint32_t eax;
+
+ eax = vmware_hypercall1(VMWARE_CMD_GETVCPU_INFO, 0);
return !(eax & BIT(VCPU_RESERVED)) &&
(eax & BIT(VCPU_LEGACY_X2APIC));
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h b/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h
index 23899d743a90..e040ee21ea1a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h
@@ -68,6 +68,8 @@
"=d"(edx), \
"=S"(si), \
"=D"(di) : \
+ [port] "i" (VMWARE_HYPERVISOR_PORT), \
+ [mode] "m" (vmware_hypercall_mode), \
"a"(magic), \
"b"(in_ebx), \
"c"(cmd), \
@@ -110,7 +112,7 @@
"push %%rbp;" \
UNWIND_HINT_UNDEFINED \
"mov %12, %%rbp;" \
- VMWARE_HYPERCALL_HB_OUT \
+ "rep outsb;" \
"pop %%rbp;" \
UNWIND_HINT_RESTORE : \
"=a"(eax), \
@@ -139,7 +141,7 @@
"push %%rbp;" \
UNWIND_HINT_UNDEFINED \
"mov %12, %%rbp;" \
- VMWARE_HYPERCALL_HB_IN \
+ "rep insb;" \
"pop %%rbp;" \
UNWIND_HINT_RESTORE : \
"=a"(eax), \
diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c
index ea9eff7c8099..ad94c835ee66 100644
--- a/drivers/input/mouse/vmmouse.c
+++ b/drivers/input/mouse/vmmouse.c
@@ -91,6 +91,8 @@ struct vmmouse_data {
"=d"(out4), \
"=S"(__dummy1), \
"=D"(__dummy2) : \
+ [port] "i" (VMWARE_HYPERVISOR_PORT), \
+ [mode] "m" (vmware_hypercall_mode), \
"a"(VMMOUSE_PROTO_MAGIC), \
"b"(in1), \
"c"(VMMOUSE_PROTO_CMD_##cmd), \
diff --git a/drivers/ptp/ptp_vmw.c b/drivers/ptp/ptp_vmw.c
index 27c5547aa8a9..279d191d2df9 100644
--- a/drivers/ptp/ptp_vmw.c
+++ b/drivers/ptp/ptp_vmw.c
@@ -29,6 +29,8 @@ static int ptp_vmw_pclk_read(u64 *ns)
asm volatile (VMWARE_HYPERCALL :
"=a"(ret), "=b"(nsec_hi), "=c"(nsec_lo), "=d"(unused1),
"=S"(unused2), "=D"(unused3) :
+ [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
"a"(VMWARE_MAGIC), "b"(0),
"c"(VMWARE_CMD_PCLK_GETTIME), "d"(0) :
"memory");
--
2.39.0
^ permalink raw reply related
* [PATCH v8 1/7] x86/vmware: Move common macros to vmware.h
From: Alexey Makhalov @ 2024-04-22 22:56 UTC (permalink / raw)
To: linux-kernel, virtualization, bp, hpa, dave.hansen, mingo, tglx
Cc: x86, netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
linux-graphics-maintainer, pv-drivers, timothym, akaher,
dri-devel, daniel, airlied, tzimmermann, mripard,
maarten.lankhorst, horms, kirill.shutemov, Alexey Makhalov,
Nadav Amit
In-Reply-To: <20240422225656.10309-1-alexey.makhalov@broadcom.com>
Move VMware hypercall macros to vmware.h. This is a prerequisite for
the introduction of vmware_hypercall API. No functional changes besides
exporting vmware_hypercall_mode symbol.
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Reviewed-by: Nadav Amit <nadav.amit@gmail.com>
---
arch/x86/include/asm/vmware.h | 72 +++++++++++++++++++++++++++++------
arch/x86/kernel/cpu/vmware.c | 57 +++------------------------
2 files changed, 66 insertions(+), 63 deletions(-)
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index ac9fc51e2b18..de2533337611 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -8,25 +8,34 @@
/*
* The hypercall definitions differ in the low word of the %edx argument
- * in the following way: the old port base interface uses the port
- * number to distinguish between high- and low bandwidth versions.
+ * in the following way: the old I/O port based interface uses the port
+ * number to distinguish between high- and low bandwidth versions, and
+ * uses IN/OUT instructions to define transfer direction.
*
* The new vmcall interface instead uses a set of flags to select
* bandwidth mode and transfer direction. The flags should be loaded
* into %dx by any user and are automatically replaced by the port
- * number if the VMWARE_HYPERVISOR_PORT method is used.
- *
- * In short, new driver code should strictly use the new definition of
- * %dx content.
+ * number if the I/O port method is used.
*/
-/* Old port-based version */
-#define VMWARE_HYPERVISOR_PORT 0x5658
-#define VMWARE_HYPERVISOR_PORT_HB 0x5659
+#define VMWARE_HYPERVISOR_HB BIT(0)
+#define VMWARE_HYPERVISOR_OUT BIT(1)
+
+#define VMWARE_HYPERVISOR_PORT 0x5658
+#define VMWARE_HYPERVISOR_PORT_HB (VMWARE_HYPERVISOR_PORT | \
+ VMWARE_HYPERVISOR_HB)
+
+#define VMWARE_HYPERVISOR_MAGIC 0x564d5868U
+
+#define VMWARE_CMD_GETVERSION 10
+#define VMWARE_CMD_GETHZ 45
+#define VMWARE_CMD_GETVCPU_INFO 68
+#define VMWARE_CMD_STEALCLOCK 91
+
+#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0)
+#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1)
-/* Current vmcall / vmmcall version */
-#define VMWARE_HYPERVISOR_HB BIT(0)
-#define VMWARE_HYPERVISOR_OUT BIT(1)
+extern u8 vmware_hypercall_mode;
/* The low bandwidth call. The low word of edx is presumed clear. */
#define VMWARE_HYPERCALL \
@@ -54,4 +63,43 @@
"rep insb", \
"vmcall", X86_FEATURE_VMCALL, \
"vmmcall", X86_FEATURE_VMW_VMMCALL)
+
+#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \
+ __asm__("inl (%%dx), %%eax" : \
+ "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
+ "a"(VMWARE_HYPERVISOR_MAGIC), \
+ "c"(VMWARE_CMD_##cmd), \
+ "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) : \
+ "memory")
+
+#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \
+ __asm__("vmcall" : \
+ "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
+ "a"(VMWARE_HYPERVISOR_MAGIC), \
+ "c"(VMWARE_CMD_##cmd), \
+ "d"(0), "b"(UINT_MAX) : \
+ "memory")
+
+#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx) \
+ __asm__("vmmcall" : \
+ "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
+ "a"(VMWARE_HYPERVISOR_MAGIC), \
+ "c"(VMWARE_CMD_##cmd), \
+ "d"(0), "b"(UINT_MAX) : \
+ "memory")
+
+#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do { \
+ switch (vmware_hypercall_mode) { \
+ case CPUID_VMWARE_FEATURES_ECX_VMCALL: \
+ VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \
+ break; \
+ case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \
+ VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx); \
+ break; \
+ default: \
+ VMWARE_PORT(cmd, eax, ebx, ecx, edx); \
+ break; \
+ } \
+ } while (0)
+
#endif
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 11f83d07925e..4db8e1daa4a1 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -41,60 +41,14 @@
#define CPUID_VMWARE_INFO_LEAF 0x40000000
#define CPUID_VMWARE_FEATURES_LEAF 0x40000010
-#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0)
-#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1)
-#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
-
-#define VMWARE_CMD_GETVERSION 10
-#define VMWARE_CMD_GETHZ 45
-#define VMWARE_CMD_GETVCPU_INFO 68
-#define VMWARE_CMD_LEGACY_X2APIC 3
-#define VMWARE_CMD_VCPU_RESERVED 31
-#define VMWARE_CMD_STEALCLOCK 91
+#define VCPU_LEGACY_X2APIC 3
+#define VCPU_RESERVED 31
#define STEALCLOCK_NOT_AVAILABLE (-1)
#define STEALCLOCK_DISABLED 0
#define STEALCLOCK_ENABLED 1
-#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \
- __asm__("inl (%%dx), %%eax" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \
- __asm__("vmcall" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(0), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx) \
- __asm__("vmmcall" : \
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
- "a"(VMWARE_HYPERVISOR_MAGIC), \
- "c"(VMWARE_CMD_##cmd), \
- "d"(0), "b"(UINT_MAX) : \
- "memory")
-
-#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do { \
- switch (vmware_hypercall_mode) { \
- case CPUID_VMWARE_FEATURES_ECX_VMCALL: \
- VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \
- break; \
- case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \
- VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx); \
- break; \
- default: \
- VMWARE_PORT(cmd, eax, ebx, ecx, edx); \
- break; \
- } \
- } while (0)
-
struct vmware_steal_time {
union {
uint64_t clock; /* stolen time counter in units of vtsc */
@@ -108,7 +62,8 @@ struct vmware_steal_time {
};
static unsigned long vmware_tsc_khz __ro_after_init;
-static u8 vmware_hypercall_mode __ro_after_init;
+u8 vmware_hypercall_mode __ro_after_init;
+EXPORT_SYMBOL_GPL(vmware_hypercall_mode);
static inline int __vmware_platform(void)
{
@@ -476,8 +431,8 @@ static bool __init vmware_legacy_x2apic_available(void)
{
uint32_t eax, ebx, ecx, edx;
VMWARE_CMD(GETVCPU_INFO, eax, ebx, ecx, edx);
- return !(eax & BIT(VMWARE_CMD_VCPU_RESERVED)) &&
- (eax & BIT(VMWARE_CMD_LEGACY_X2APIC));
+ return !(eax & BIT(VCPU_RESERVED)) &&
+ (eax & BIT(VCPU_LEGACY_X2APIC));
}
#ifdef CONFIG_AMD_MEM_ENCRYPT
--
2.39.0
^ permalink raw reply related
* [PATCH v8 0/7] VMware hypercalls enhancements
From: Alexey Makhalov @ 2024-04-22 22:56 UTC (permalink / raw)
To: linux-kernel, virtualization, bp, hpa, dave.hansen, mingo, tglx
Cc: x86, netdev, richardcochran, linux-input, dmitry.torokhov, zackr,
linux-graphics-maintainer, pv-drivers, timothym, akaher,
dri-devel, daniel, airlied, tzimmermann, mripard,
maarten.lankhorst, horms, kirill.shutemov, Alexey Makhalov
No functional changes from version 7. Peter please consider reviewing
patch 7 where we addressed your comments from version 6. Thanks!
VMware hypercalls invocations were all spread out across the kernel
implementing same ABI as in-place asm-inline. With encrypted memory
and confidential computing it became harder to maintain every changes
in these hypercall implementations.
Intention of this patchset is to introduce arch independent VMware
hypercall API layer other subsystems such as device drivers can call
to, while hiding architecture specific implementation behind.
Second patch introduces the vmware_hypercall low and high bandwidth
families of functions, with little enhancements there.
Sixth patch adds tdx hypercall support
arm64 implementation of vmware_hypercalls is in drivers/gpu/drm/
vmwgfx/vmwgfx_msg_arm64.h and going to be moved to arch/arm64 with
a separate patchset with the introduction of VMware Linux guest
support for arm64.
No functional changes in drivers/input/mouse/vmmouse.c and
drivers/ptp/ptp_vmw.c
v7->v8 no functional changes. Updated authors and reviewers emails to
@broadcom.com
v6->v7 changes (only in patch 7):
- Addressed comments from H. Peter Anvin:
1. Removed vmware_tdx_hypercall_args(), moved args handling inside
vmware_tdx_hypercall().
2. Added pr_warn_once() for !hypervisor_is_type(X86_HYPER_VMWARE) case.
- Added ack by Dave Hansen.
v5->v6 change:
- Added ack by Kirill A. Shutemov in patch 7.
v4->v5 changes:
[patch 2]:
- Fixed the problem reported by Simon Horman where build fails after
patch 2 application. Do not undefine VMWARE_HYPERCALL for now, and
update vmwgfx, vmmouse and ptp_vmw code for new VMWARE_HYPERCALL macro.
- Introduce new patch 6 to undefine VMWARE_HYPERCALL, which is safe to do
after patches 3 to 5.
- [patch 7 (former patch 6)]: Add missing r15 (CPL) initialization.
v3->v4 changes: (no functional changes in patches 1-5)
[patch 2]:
- Added the comment with VMware hypercall ABI description.
[patch 6]:
- vmware_tdx_hypercall_args remove in6/out6 arguments as excessive.
- vmware_tdx_hypercall return ULONG_MAX on error to mimic bad hypercall
command error from the hypervisor.
- Replaced pr_warn by pr_warn_once as pointed by Kirill Shutemov.
- Fixed the warning reported by Intel's kernel test robot.
- Added the comment describing VMware TDX hypercall ABI.
v2->v3 changes: (no functional changes in patches 1-5)
- Improved commit message in patches 1, 2 and 5 as was suggested by
Borislav Petkov.
- To address Dave Hansen's concern, patch 6 was reorganized to avoid
exporting bare __tdx_hypercall and to make exported vmware_tdx_hypercall
VMWare guest specific.
v1->v2 changes (no functional changes):
- Improved commit message in patches 2 and 5.
- Added Reviewed-by for all patches.
- Added Ack from Dmitry Torokhov in patch 4. No fixes regarding reported
by Simon Horman gcc error in this patch.
Alexey Makhalov (7):
x86/vmware: Move common macros to vmware.h
x86/vmware: Introduce VMware hypercall API
ptp/vmware: Use VMware hypercall API
input/vmmouse: Use VMware hypercall API
drm/vmwgfx: Use VMware hypercall API
x86/vmware: Undefine VMWARE_HYPERCALL
x86/vmware: Add TDX hypercall support
arch/x86/include/asm/vmware.h | 331 +++++++++++++++++++---
arch/x86/kernel/cpu/vmware.c | 144 +++++-----
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 173 ++++-------
drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +++++++++----
drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h | 185 ------------
drivers/input/mouse/vmmouse.c | 76 ++---
drivers/ptp/ptp_vmw.c | 12 +-
7 files changed, 593 insertions(+), 525 deletions(-)
--
2.39.0
^ permalink raw reply
* Re: [PATCH v2] HID: i2c-hid: Revert to await reset ACK before reading report descriptor
From: Linux regression tracking (Thorsten Leemhuis) @ 2024-04-22 17:10 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires
Cc: Douglas Anderson, Hans de Goede, linux-input, linux-kernel,
Linux kernel regressions list, Kenny Levinsen
In-Reply-To: <20240331182440.14477-1-kl@kl.wtf>
On 31.03.24 20:24, Kenny Levinsen wrote:
> In af93a167eda9, i2c_hid_parse was changed to continue with reading the
> report descriptor before waiting for reset to be acknowledged.
>
> This has lead to two regressions:
Lo! Jiri, Benjamin, quick question: is there a reason why this fix for a
6.8-rc1 regression after more than two and half weeks is not yet
mainlined? Or is there some good reason why we should be should be extra
cautious?
Side note: I noticed this due to the tracking today, but I also saw a
user that recently ran into the problem the quoted fix is supposed to
resolve: https://social.lol/@major/112294923280815017
Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat)
--
Everything you wanna know about Linux kernel regression tracking:
https://linux-regtracking.leemhuis.info/about/#tldr
If I did something stupid, please tell me, as explained on that page.
#regzbot poke
> 1. We fail to handle reset acknowledgement if it happens while reading
> the report descriptor. The transfer sets I2C_HID_READ_PENDING, which
> causes the IRQ handler to return without doing anything.
>
> This affects both a Wacom touchscreen and a Sensel touchpad.
>
> 2. On a Sensel touchpad, reading the report descriptor this quickly
> after reset results in all zeroes or partial zeroes.
>
> The issues were observed on the Lenovo Thinkpad Z16 Gen 2.
>
> The change in question was made based on a Microsoft article[0] stating
> that Windows 8 *may* read the report descriptor in parallel with
> awaiting reset acknowledgement, intended as a slight reset performance
> optimization. Perhaps they only do this if reset is not completing
> quickly enough for their tastes?
>
> As the code is not currently ready to read registers in parallel with a
> pending reset acknowledgement, and as reading quickly breaks the report
> descriptor on the Sensel touchpad, revert to waiting for reset
> acknowledgement before proceeding to read the report descriptor.
>
> [0]: https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/plug-and-play-support-and-power-management
>
> Fixes: af93a167eda9 ("HID: i2c-hid: Move i2c_hid_finish_hwreset() to after reading the report-descriptor")
> Signed-off-by: Kenny Levinsen <kl@kl.wtf>
> ---
> drivers/hid/i2c-hid/i2c-hid-core.c | 13 ++++---------
> 1 file changed, 4 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
> index 2df1ab3c31cc..72d2bccf5621 100644
> --- a/drivers/hid/i2c-hid/i2c-hid-core.c
> +++ b/drivers/hid/i2c-hid/i2c-hid-core.c
> @@ -735,9 +735,12 @@ static int i2c_hid_parse(struct hid_device *hid)
> mutex_lock(&ihid->reset_lock);
> do {
> ret = i2c_hid_start_hwreset(ihid);
> - if (ret)
> + if (ret == 0)
> + ret = i2c_hid_finish_hwreset(ihid);
> + else
> msleep(1000);
> } while (tries-- > 0 && ret);
> + mutex_unlock(&ihid->reset_lock);
>
> if (ret)
> goto abort_reset;
> @@ -767,16 +770,8 @@ static int i2c_hid_parse(struct hid_device *hid)
> }
> }
>
> - /*
> - * Windows directly reads the report-descriptor after sending reset
> - * and then waits for resets completion afterwards. Some touchpads
> - * actually wait for the report-descriptor to be read before signalling
> - * reset completion.
> - */
> - ret = i2c_hid_finish_hwreset(ihid);
> abort_reset:
> clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
> - mutex_unlock(&ihid->reset_lock);
> if (ret)
> goto out;
>
^ permalink raw reply
* [PATCH 2/2] arm64: dts: allwinner: h616: Add LRADC node
From: Andre Przywara @ 2024-04-22 16:45 UTC (permalink / raw)
To: Hans de Goede, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-input, devicetree, linux-arm-kernel, linux-sunxi,
James McGregor
In-Reply-To: <20240422164511.2488261-1-andre.przywara@arm.com>
From: James McGregor <jamcgregor@protonmail.com>
Add a DT node for the Allwinner H616 LRADC describing the base address,
interrupt, reset and clock gates.
Signed-off-by: James McGregor <jamcgregor@protonmail.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index a061b69c07c2..58fb28f83feb 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -125,6 +125,16 @@ sram_c: sram@28000 {
};
};
+ lradc: lradc@5070800 {
+ compatible = "allwinner,sun50i-h616-lradc",
+ "allwinner,sun50i-r329-lradc";
+ reg = <0x05070800 0x400>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_KEYADC>;
+ resets = <&ccu RST_BUS_KEYADC>;
+ status = "disabled";
+ };
+
ccu: clock@3001000 {
compatible = "allwinner,sun50i-h616-ccu";
reg = <0x03001000 0x1000>;
--
2.34.1
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: input: sun4i-lradc-keys: Add H616 compatible
From: Andre Przywara @ 2024-04-22 16:45 UTC (permalink / raw)
To: Hans de Goede, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-input, devicetree, linux-arm-kernel, linux-sunxi,
James McGregor
In-Reply-To: <20240422164511.2488261-1-andre.przywara@arm.com>
From: James McGregor <jamcgregor@protonmail.com>
The Allwinner H616 SoC has an LRADC which is compatible with the
versions in existing SoCs.
Add a compatible string for H616, with the R329 fallback. This is the
same as the D1, so put them into an enum.
Signed-off-by: James McGregor <jamcgregor@protonmail.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
.../bindings/input/allwinner,sun4i-a10-lradc-keys.yaml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
index c384bf0bb25d..8cb5820774e0 100644
--- a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
+++ b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
@@ -22,7 +22,9 @@ properties:
- const: allwinner,sun8i-a83t-r-lradc
- const: allwinner,sun50i-r329-lradc
- items:
- - const: allwinner,sun20i-d1-lradc
+ - enum:
+ - allwinner,sun50i-h616-lradc
+ - allwinner,sun20i-d1-lradc
- const: allwinner,sun50i-r329-lradc
reg:
--
2.34.1
^ permalink raw reply related
* [PATCH 0/2] arm64: dts: allwinner: H616: Add LRADC
From: Andre Przywara @ 2024-04-22 16:45 UTC (permalink / raw)
To: Hans de Goede, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-input, devicetree, linux-arm-kernel, linux-sunxi,
James McGregor
From: James McGregor <jamcgregor@protonmail.com>
The Allwinner H616 series of SoCs have a low-rate ADC (LRADC) with
6-bit resolution and one input channel. They're compatible with the
existing drivers, so it only needs to be enabled in the DT.
Add an LRADC node to the H616 .dtsi, so board DTs can use them by
adding 'status = "okay";'.
This was tested on an OrangePi Zero 2W by attaching an expansion board
with two key buttons connected to the LRADC, and adding them to the DT.
/dev/input/event0 then properly reported the button presses. The patches
are based off sunxi/for-next.
James McGregor (2):
dt-bindings: input: sum4i-lradc-keys: Add H616 compatible
ARM: dts: sun50i: Add LRADC node
.../bindings/input/allwinner,sun4i-a10-lradc-keys.yaml | 4 +++-
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 10 ++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
--
2.34.1
^ 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