* Re: [PATCH v3 5/5] tty/serial: Add Spreadtrum sc9836-uart driver support
From: Lyra Zhang @ 2014-11-27 11:39 UTC (permalink / raw)
To: Tobias Klauser
Cc: Chunyan Zhang, Grant Likely, robh+dt@kernel.org, Catalin Marinas,
gregkh@linuxfoundation.org, ijc+devicetree@hellion.org.uk,
jslaby@suse.cz, Kumar Gala, Mark Brown, Mark Rutland,
m-karicheri2@ti.com, Pawel Moll, Ramkumar Ramachandra,
rrichter@cavium.com, Will Deacon, Arnd Bergmann, gnomes,
Jonathan Corbet, jason, Mark Brown, Heiko Stübner, shawn.guo
In-Reply-To: <20141126094838.GB17980@distanz.ch>
2014-11-26 17:48 GMT+08:00 Tobias Klauser <tklauser@distanz.ch>:
> On 2014-11-25 at 13:16:58 +0100, Chunyan Zhang <chunyan.zhang@spreadtrum.com> wrote:
>> ---
[...]
>> +
>> +config SERIAL_SPRD_CONSOLE
>> + bool "SPRD UART console support"
>> + depends on SERIAL_SPRD=y
>> + select SERIAL_CORE_CONSOLE
>> + select SERIAL_EARLYCON
>> + help
>> + Support for early debug console using Spreadtrum's serial. This enables
>> + the console before standard serial driver is probed. This is enabled
>> + with "earlycon" on the kernel command line. The console is
>> + enabled when early_param is processed.
>> +
>> endmenu
>
> Please consistently use tabs instead of spaces for indentation. The help
> text should be indented by one tabe + 2 spaces.
>
OK, I will note it later.
[...]
>> +static inline int handle_lsr_errors(struct uart_port *port,
>> + unsigned int *flag, unsigned int *lsr)
>
> This line should be aligned with the opening ( above.
>
OK, will change.
>> +static inline void sprd_rx(int irq, void *dev_id)
>> +{
>> + struct uart_port *port = (struct uart_port *)dev_id;
>
> No need to cast a void pointer.
>
>> +static void sprd_console_write(struct console *co, const char *s,
>> + unsigned int count)
>> +{
>> + struct uart_port *port = (struct uart_port *)sprd_port[co->index];
>
> Better explicitly access the .port member of sprd_port[co->index] here
> instead of casting.
>
>> + port = (struct uart_port *)sprd_port[co->index];
>
> Same here, use the .port member of struct sprd_port[co->index].
>
>> + if (port == NULL) {
>> + pr_info("srial port %d not yet initialized\n", co->index);
>
> Typo: should be serial instead of srial.
>
>> + up->mapbase = mem->start;
>> + up->membase = ioremap(mem->start, resource_size(mem));
>
> Return value of ioremap() should be checked for NULL.
>
>> +static int sprd_resume(struct platform_device *dev)
>> +{
>> + int id = dev->id;
>> + struct uart_port *port = (struct uart_port *)sprd_port[id];
>
> Access the .port member instead of the cast.
>
OK, will change all of the problems you pointed out in v4.
Thanks for your review.
Chunyan
^ permalink raw reply
* Re: [tpmdd-devel] [PATCH v7 01/10] tpm: merge duplicate transmit_cmd() functions
From: Jarkko Sakkinen @ 2014-11-27 11:43 UTC (permalink / raw)
To: Stefan Berger
Cc: Peter Huewe, Ashley Lai, Marcel Selhorst,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
josh.triplett-ral2JQCrhuEAvxtiuMwx3w,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
jason.gunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/,
trousers-tech-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <5474F22F.1030301-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
On Tue, Nov 25, 2014 at 04:18:39PM -0500, Stefan Berger wrote:
> On 11/11/2014 08:45 AM, Jarkko Sakkinen wrote:
> >Merged transmit_cmd() functions in tpm-interface.c and tpm-sysfs.c.
> >Added "tpm_" prefix for consistency sake. Changed cmd parameter as
> >opaque. This enables to use separate command structures for TPM1
> >and TPM2 commands in future. Loose coupling works fine here.
> >
> >Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> >---
> > drivers/char/tpm/tpm-interface.c | 49 +++++++++++++++++++++-------------------
> > drivers/char/tpm/tpm-sysfs.c | 23 ++-----------------
> > drivers/char/tpm/tpm.h | 3 ++-
> > 3 files changed, 30 insertions(+), 45 deletions(-)
> >
> >diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> >index 6af1700..0150b7c 100644
> >--- a/drivers/char/tpm/tpm-interface.c
> >+++ b/drivers/char/tpm/tpm-interface.c
> >@@ -398,9 +398,10 @@ out:
> > #define TPM_DIGEST_SIZE 20
> > #define TPM_RET_CODE_IDX 6
> >
> >-static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
> >- int len, const char *desc)
> >+ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd,
> >+ int len, const char *desc)
> > {
> >+ struct tpm_output_header *header;
> > int err;
> >
> > len = tpm_transmit(chip, (u8 *) cmd, len);
> >@@ -409,7 +410,9 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
> > else if (len < TPM_HEADER_SIZE)
> > return -EFAULT;
> >
> >- err = be32_to_cpu(cmd->header.out.return_code);
> >+ header = (struct tpm_output_header *) cmd;
>
> The cast should not be necessary -- and this change doesn't buy much...
>
> header = &cmd->header.out;
>
> Should do the trick without cast.
I changed the cmd parameter opaque to make this function work both with
TPM1 and TPM2 easily so that I do not have to drop everything to
struct tpm_cmd_t.
I can change this to
header = cmd;
> >+
> >+ err = be32_to_cpu(header->return_code);
> > if (err != 0 && desc)
> > dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
> >
> >@@ -448,7 +451,7 @@ ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
> > tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
> > tpm_cmd.params.getcap_in.subcap = subcap_id;
> > }
> >- rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
> >+ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
> > if (!rc)
> > *cap = tpm_cmd.params.getcap_out.cap;
> > return rc;
> >@@ -464,8 +467,8 @@ void tpm_gen_interrupt(struct tpm_chip *chip)
> > tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
> > tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
> >
> >- rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
> >- "attempting to determine the timeouts");
> >+ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
> >+ "attempting to determine the timeouts");
> > }
> > EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
> >
> >@@ -484,8 +487,8 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
> > struct tpm_cmd_t start_cmd;
> > start_cmd.header.in = tpm_startup_header;
> > start_cmd.params.startup_in.startup_type = startup_type;
> >- return transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE,
> >- "attempting to start the TPM");
> >+ return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE,
> >+ "attempting to start the TPM");
> > }
> >
> > int tpm_get_timeouts(struct tpm_chip *chip)
> >@@ -500,7 +503,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
> > tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
> > tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
> > tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
> >- rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, NULL);
> >+ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, NULL);
> >
> > if (rc == TPM_ERR_INVALID_POSTINIT) {
> > /* The TPM is not started, we are the first to talk to it.
> >@@ -513,7 +516,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
> > tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
> > tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
> > tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
> >- rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
> >+ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
> > NULL);
> > }
> > if (rc) {
> >@@ -575,8 +578,8 @@ duration:
> > tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
> > tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
> >
> >- rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
> >- "attempting to determine the durations");
> >+ rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
> >+ "attempting to determine the durations");
> > if (rc)
> > return rc;
> >
> >@@ -631,8 +634,8 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
> > struct tpm_cmd_t cmd;
> >
> > cmd.header.in = continue_selftest_header;
> >- rc = transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
> >- "continue selftest");
> >+ rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
> >+ "continue selftest");
> > return rc;
> > }
> >
> >@@ -672,8 +675,8 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
> >
> > cmd.header.in = pcrread_header;
> > cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
> >- rc = transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
> >- "attempting to read a pcr value");
> >+ rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
> >+ "attempting to read a pcr value");
> >
> > if (rc == 0)
> > memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
> >@@ -737,8 +740,8 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
> > cmd.header.in = pcrextend_header;
> > cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
> > memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
> >- rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
> >- "attempting extend a PCR value");
> >+ rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
> >+ "attempting extend a PCR value");
> >
> > tpm_chip_put(chip);
> > return rc;
> >@@ -817,7 +820,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
> > if (chip == NULL)
> > return -ENODEV;
> >
> >- rc = transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
> >+ rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
> >
> > tpm_chip_put(chip);
> > return rc;
> >@@ -938,14 +941,14 @@ int tpm_pm_suspend(struct device *dev)
> > cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr);
> > memcpy(cmd.params.pcrextend_in.hash, dummy_hash,
> > TPM_DIGEST_SIZE);
> >- rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
> >- "extending dummy pcr before suspend");
> >+ rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
> >+ "extending dummy pcr before suspend");
> > }
> >
> > /* now do the actual savestate */
> > for (try = 0; try < TPM_RETRY; try++) {
> > cmd.header.in = savestate_header;
> >- rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL);
> >+ rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL);
> >
> > /*
> > * If the TPM indicates that it is too busy to respond to
> >@@ -1022,7 +1025,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
> > tpm_cmd.header.in = tpm_getrandom_header;
> > tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
> >
> >- err = transmit_cmd(chip, &tpm_cmd,
> >+ err = tpm_transmit_cmd(chip, &tpm_cmd,
> > TPM_GETRANDOM_RESULT_SIZE + num_bytes,
> > "attempting get random");
> > if (err)
> >diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
> >index 01730a2..8ecb052 100644
> >--- a/drivers/char/tpm/tpm-sysfs.c
> >+++ b/drivers/char/tpm/tpm-sysfs.c
> >@@ -20,25 +20,6 @@
> > #include <linux/device.h>
> > #include "tpm.h"
> >
> >-/* XXX for now this helper is duplicated in tpm-interface.c */
> >-static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
> >- int len, const char *desc)
> >-{
> >- int err;
> >-
> >- len = tpm_transmit(chip, (u8 *) cmd, len);
> >- if (len < 0)
> >- return len;
> >- else if (len < TPM_HEADER_SIZE)
> >- return -EFAULT;
> >-
> >- err = be32_to_cpu(cmd->header.out.return_code);
> >- if (err != 0 && desc)
> >- dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
> >-
> >- return err;
> >-}
> >-
> > #define READ_PUBEK_RESULT_SIZE 314
> > #define TPM_ORD_READPUBEK cpu_to_be32(124)
> > static struct tpm_input_header tpm_readpubek_header = {
> >@@ -58,8 +39,8 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
> > struct tpm_chip *chip = dev_get_drvdata(dev);
> >
> > tpm_cmd.header.in = tpm_readpubek_header;
> >- err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
> >- "attempting to read the PUBEK");
> >+ err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
> >+ "attempting to read the PUBEK");
> > if (err)
> > goto out;
> >
> >diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> >index e4d0888..e638eb0 100644
> >--- a/drivers/char/tpm/tpm.h
> >+++ b/drivers/char/tpm/tpm.h
> >@@ -314,9 +314,10 @@ struct tpm_cmd_t {
> > } __packed;
> >
> > ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
> >-
> > ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
> > size_t bufsiz);
>
> Delete this prototype ?
tpm-dev.c uses tpm_transmit() and tpm_transmit_cmd() does unnecessary
steps for that use.
> >+ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, int len,
> >+ const char *desc);
> > extern int tpm_get_timeouts(struct tpm_chip *);
> > extern void tpm_gen_interrupt(struct tpm_chip *);
> > extern int tpm_do_selftest(struct tpm_chip *);
>
>
> Stefan
/Jarkko
^ permalink raw reply
* Re: [PATCH v3 3/5] arm64: dts: Add support for Spreadtrum SC9836 SoC in dts and Makefile
From: Mark Rutland @ 2014-11-27 11:50 UTC (permalink / raw)
To: Chunyan Zhang
Cc: grant.likely@linaro.org, robh+dt@kernel.org, Catalin Marinas,
gregkh@linuxfoundation.org, ijc+devicetree@hellion.org.uk,
jslaby@suse.cz, galak@codeaurora.org, broonie@linaro.org,
m-karicheri2@ti.com, Pawel Moll, artagnon@gmail.com,
rrichter@cavium.com, Will Deacon, arnd@arndb.de,
gnomes@lxorguk.ukuu.org.uk, corbet@lwn.net, jason@lakedaemon.net,
broonie@kernel.org, heiko@sntech.de,
"shawn.guo@freescale.com" <shawn.g>
In-Reply-To: <1416917818-10506-4-git-send-email-chunyan.zhang@spreadtrum.com>
On Tue, Nov 25, 2014 at 12:16:56PM +0000, Chunyan Zhang wrote:
> From: Zhizhou Zhang <zhizhou.zhang@spreadtrum.com>
>
> Adds the device tree support for Spreadtrum SC9836 SoC which is based on
> Sharkl64 platform.
>
> Sharkl64 platform contains the common nodes of Spreadtrum's arm64-based SoCs.
>
> Signed-off-by: Zhizhou Zhang <zhizhou.zhang@spreadtrum.com>
> Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
> Signed-off-by: Orson Zhai <orson.zhai@spreadtrum.com>
> ---
> arch/arm64/boot/dts/Makefile | 1 +
> arch/arm64/boot/dts/sprd-sc9836-openphone.dts | 85 ++++++++++++++++++++
> arch/arm64/boot/dts/sprd-sc9836.dtsi | 103 ++++++++++++++++++++++++
> arch/arm64/boot/dts/sprd-sharkl64.dtsi | 105 +++++++++++++++++++++++++
> 4 files changed, 294 insertions(+)
> create mode 100644 arch/arm64/boot/dts/sprd-sc9836-openphone.dts
> create mode 100644 arch/arm64/boot/dts/sprd-sc9836.dtsi
> create mode 100644 arch/arm64/boot/dts/sprd-sharkl64.dtsi
>
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index f8001a6..d0aff8a 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -1,4 +1,5 @@
> dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb
> +dtb-$(CONFIG_ARCH_SHARKL64) += sprd-sc9836-openphone.dtb
> dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb
> dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb
[...]
> + gic: interrupt-controller@12001000 {
> + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
> + #interrupt-cells = <3>;
> + interrupt-controller;
> + reg = <0 0x12001000 0 0x1000>,
> + <0 0x12002000 0 0x1000>,
> + <0 0x12004000 0 0x2000>,
> + <0 0x12006000 0 0x2000>;
> + };
I believe GICC should be 8KiB here.
> +
> + psci {
> + compatible = "arm,psci-0.2";
> + method = "smc";
> + };
Do you have a complete PSCI 0.2 implementation (e.g. are all the
mandatory functions implemented)?
I take it CPUs enter the kernel at EL2?
How have you tested this?
> +
> + timer {
> + compatible = "arm,armv8-timer";
> + interrupts = <1 13 0xff01>,
> + <1 14 0xff01>,
> + <1 11 0xff01>,
> + <1 10 0xff01>;
> + clock-frequency = <26000000>;
Please remove the clock-frequency property. Your FW should initialise
CNTFRQ_EL0 on all CPUs (certainly PSCI 0.2 requires that you do this).
[...]
> + clocks {
> + clk26mhz: clk26mhz {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <26000000>;
> + };
> + };
Get rid of the "clocks" container node. There's no need for it.
Thanks,
Mark.
^ permalink raw reply
* Re: [PATCH v3 5/5] tty/serial: Add Spreadtrum sc9836-uart driver support
From: Lyra Zhang @ 2014-11-27 11:59 UTC (permalink / raw)
To: Murali Karicheri
Cc: Chunyan Zhang, Grant Likely, robh+dt@kernel.org, Catalin Marinas,
gregkh@linuxfoundation.org, ijc+devicetree@hellion.org.uk,
jslaby@suse.cz, Kumar Gala, Mark Rutland, Pawel Moll,
Ramkumar Ramachandra, rrichter@cavium.com, Will Deacon,
Arnd Bergmann, gnomes, Jonathan Corbet, jason, Mark Brown,
Heiko Stübner, florian.vaussard, andrew, Hayato Suzuki,
Orson Zhai
In-Reply-To: <54761BFC.4020705@ti.com>
2014-11-27 2:29 GMT+08:00 Murali Karicheri <m-karicheri2@ti.com>:
> On 11/25/2014 07:16 AM, Chunyan Zhang wrote:
>>
>> Add a full sc9836-uart driver for SC9836 SoC which is based on the
>> +#include<linux/clk.h>
>
> How about sorting this includes? asm/irq.h go first followed linux/ in
> alphabatical order?
>> +static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
>> +{
>> + struct uart_port *port = (struct uart_port *)dev_id;
>> + u32 ims;
>> +
>> + ims = serial_in(port, SPRD_IMSR);
>> +
>> + serial_out(port, SPRD_ICLR, ~0);
>> +
>> + if (ims& (SPRD_IMSR_RX_FIFO_FULL |
>> + SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) {
>> + sprd_rx(irq, port);
>> + }
>> + if (ims& SPRD_IMSR_TX_FIFO_EMPTY)
>> + sprd_tx(irq, port);
>> +
>> + return IRQ_HANDLED;
>
> You are always returning IRQ_HANDLED and this is registered as a SHARED irq.
> Is there a chance this handler is called and the irq event doesn't
> belong to this device?
>
> Murali
You are right, this is not a SHARED irq. I'll pass 0 for irqflags when
called 'devm_request_irq' in the next version patch.
Thank you,
Chunyan
^ permalink raw reply
* Re: [PATCH v3 0/5] Add Spreadtrum Sharkl64 Platform support
From: Mark Rutland @ 2014-11-27 12:03 UTC (permalink / raw)
To: Chunyan Zhang
Cc: grant.likely@linaro.org, robh+dt@kernel.org, Catalin Marinas,
gregkh@linuxfoundation.org, ijc+devicetree@hellion.org.uk,
jslaby@suse.cz, galak@codeaurora.org, broonie@linaro.org,
m-karicheri2@ti.com, Pawel Moll, artagnon@gmail.com,
rrichter@cavium.com, Will Deacon, arnd@arndb.de,
gnomes@lxorguk.ukuu.org.uk, corbet@lwn.net, jason@lakedaemon.net,
broonie@kernel.org, heiko@sntech.de,
"shawn.guo@freescale.com" <shawn.g>
In-Reply-To: <1416917818-10506-1-git-send-email-chunyan.zhang@spreadtrum.com>
Hi,
On Tue, Nov 25, 2014 at 12:16:53PM +0000, Chunyan Zhang wrote:
> Spreadtrum is a rapid growing chip vendor providing smart phone total solutions.
>
> Sharkl64 Platform is nominated as a SoC infrastructure that supports 4G/3G/2G
> standards based on ARMv8 multiple core architecture.Now we have only one
> SoC(SC9836) based on this Platform in developing.
>
> This patchset adds Sharkl64 support in arm64 device tree and the serial driver
> of SC9836-UART.
>
> This patchset also has patches which address "sprd" prefix and DT compatible
> strings for nodes which appear un-documented.
>
> This version code was tesed on Fast Mode.
This concerns me a bit because fast models are extremely lenient w.r.t.
the management of clocks and regulators. Are you sure you have
everything you need for your UART described?
> We use boot-wrapper-aarch64 as the bootloader.
Which version of boot-wrapper-aarch64 are you using?
Upstream does not implement PSCI 0.2, but its --enable-psci option will
inject PSCI 0.1 compatible properties, which leads me to suspect that
your DT is misleading. The boot wrapper should also program CNTFRQ_EL0
correctly regardless.
What do you intend to use on real hardware?
Thanks,
Mark.
>
> Changes from v2:
> * Addressed review comments:
> - Added a specific compitible string 'sc9836-uart' for the serial
> - Added a full serial driver
> - Added the property 'clock-frequency' for timer node in dtsi.
> - Replaceed the old macro prefix 'UART_' with 'SPRD_' in the
> Spreadtrum serial driver code.
> * Revised the name of SoC and board from 'sharkl3' to 'sc9836'
> * Used dual-license for DTS files
> * Added a menuconfig 'ARCH_SPRD' in arch/arm64/Kconfig
>
> Changes from v1:
> * Addressed review comments:
> - Added "sprd" prefix to vendor-prefixes.txt
> - Created serial/sprd-serial.txt and remove the properties for serial-sprd
> from of-serial.txt to it.
> - Renamed of-serial.txt to 8250.txt according to Arnd's review comments
> - Splited and revised .dts for Sharkl64 Platform
> - Changed to PSCI method for cpu power management
> - Revised Kconfig Makefile to match the alphabetical ordering
> - Renamed serial-sprd-earlycon.c to serial-sprd.c
>
> Chunyan Zhang (3):
> Documentation: DT: Renamed of-serial.txt to 8250.txt
> Documentation: DT: Add bindings for Spreadtrum SoC Platform
> tty/serial: Add Spreadtrum sc9836-uart driver support
>
> Zhizhou Zhang (2):
> arm64: dts: Add support for Spreadtrum SC9836 SoC in dts and Makefile
> arm64: Add support for Spreadtrum's Sharkl64 Platform in Kconfig and
> defconfig
>
> Documentation/devices.txt | 3 +
> Documentation/devicetree/bindings/arm/sprd.txt | 11 +
> .../bindings/serial/{of-serial.txt => 8250.txt} | 0
> .../devicetree/bindings/serial/sprd-uart.txt | 6 +
> .../devicetree/bindings/vendor-prefixes.txt | 1 +
> arch/arm64/Kconfig | 17 +
> arch/arm64/boot/dts/Makefile | 1 +
> arch/arm64/boot/dts/sprd-sc9836-openphone.dts | 85 +++
> arch/arm64/boot/dts/sprd-sc9836.dtsi | 103 +++
> arch/arm64/boot/dts/sprd-sharkl64.dtsi | 105 +++
> arch/arm64/configs/defconfig | 2 +
> drivers/tty/serial/Kconfig | 23 +
> drivers/tty/serial/Makefile | 1 +
> drivers/tty/serial/sprd_serial.c | 752 ++++++++++++++++++++
> include/uapi/linux/serial_core.h | 3 +
> 15 files changed, 1113 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/arm/sprd.txt
> rename Documentation/devicetree/bindings/serial/{of-serial.txt => 8250.txt} (100%)
> create mode 100644 Documentation/devicetree/bindings/serial/sprd-uart.txt
> create mode 100644 arch/arm64/boot/dts/sprd-sc9836-openphone.dts
> create mode 100644 arch/arm64/boot/dts/sprd-sc9836.dtsi
> create mode 100644 arch/arm64/boot/dts/sprd-sharkl64.dtsi
> create mode 100644 drivers/tty/serial/sprd_serial.c
>
> --
> 1.7.9.5
>
>
^ permalink raw reply
* Re: [PATCH v3 1/5] Documentation: DT: Renamed of-serial.txt to 8250.txt
From: Lyra Zhang @ 2014-11-27 12:08 UTC (permalink / raw)
To: Mark Rutland
Cc: Chunyan Zhang, grant.likely@linaro.org, robh+dt@kernel.org,
Catalin Marinas, gregkh@linuxfoundation.org,
ijc+devicetree@hellion.org.uk, jslaby@suse.cz,
galak@codeaurora.org, m-karicheri2@ti.com, Pawel Moll,
artagnon@gmail.com, rrichter@cavium.com, Will Deacon,
arnd@arndb.de, gnomes@lxorguk.ukuu.org.uk, corbet@lwn.net,
jason@lakedaemon.net, broonie@kernel.org, heiko@sntech.de,
"florian.vaussard@epfl.ch" <flo>
In-Reply-To: <20141127113819.GD857@leverpostej>
2014-11-27 19:38 GMT+08:00 Mark Rutland <mark.rutland@arm.com>:
> On Tue, Nov 25, 2014 at 12:16:54PM +0000, Chunyan Zhang wrote:
>> The file of-serial.txt was only for 8250 compatible UART implementations,
>> so renamed it to 8250.txt to avoid confusing other persons.
>> This is recommended by Arnd, see:
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/291455.html
>>
>> Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
>
> My prior Ack [1] still applies (given you've just changed the way the
> patch was generated, as Arnd and I suggested).
>
OK, I'll add in v4.
> Mark.
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/295152.html
>
>> ---
>> .../bindings/serial/{of-serial.txt => 8250.txt} | 0
>> 1 file changed, 0 insertions(+), 0 deletions(-)
>> rename Documentation/devicetree/bindings/serial/{of-serial.txt => 8250.txt} (100%)
>>
>> diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/8250.txt
>> similarity index 100%
>> rename from Documentation/devicetree/bindings/serial/of-serial.txt
>> rename to Documentation/devicetree/bindings/serial/8250.txt
>> --
>> 1.7.9.5
>>
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH v3 3/5] arm64: dts: Add support for Spreadtrum SC9836 SoC in dts and Makefile
From: Catalin Marinas @ 2014-11-27 12:12 UTC (permalink / raw)
To: Mark Rutland
Cc: Chunyan Zhang, grant.likely@linaro.org, robh+dt@kernel.org,
gregkh@linuxfoundation.org, ijc+devicetree@hellion.org.uk,
jslaby@suse.cz, galak@codeaurora.org, broonie@linaro.org,
m-karicheri2@ti.com, Pawel Moll, artagnon@gmail.com,
rrichter@cavium.com, Will Deacon, arnd@arndb.de,
gnomes@lxorguk.ukuu.org.uk, corbet@lwn.net, jason@lakedaemon.net,
broonie@kernel.org, heiko@sntech.de,
"shawn.guo@freescale.com" <shaw>
In-Reply-To: <20141127115042.GE857@leverpostej>
On Thu, Nov 27, 2014 at 11:50:43AM +0000, Mark Rutland wrote:
> On Tue, Nov 25, 2014 at 12:16:56PM +0000, Chunyan Zhang wrote:
> > +
> > + timer {
> > + compatible = "arm,armv8-timer";
> > + interrupts = <1 13 0xff01>,
> > + <1 14 0xff01>,
> > + <1 11 0xff01>,
> > + <1 10 0xff01>;
> > + clock-frequency = <26000000>;
>
> Please remove the clock-frequency property. Your FW should initialise
> CNTFRQ_EL0 on all CPUs (certainly PSCI 0.2 requires that you do this).
Since this comes up regularly, I think we need a dev_warn() in the arch
timer driver when CONFIG_ARM64.
--
Catalin
^ permalink raw reply
* [PATCH v5 06/45] virtio: add virtio 1.0 feature bit
From: Michael S. Tsirkin @ 2014-11-27 12:30 UTC (permalink / raw)
To: linux-kernel
Cc: thuth, rusty, linux-api, virtualization, dahi, pbonzini,
David Miller
In-Reply-To: <1417091078-24611-1-git-send-email-mst@redhat.com>
Based on original patches by Rusty Russell, Thomas Huth
and Cornelia Huck.
Note: at this time, we do not negotiate this feature bit
in core, drivers have to declare VERSION_1 support explicitly.
For this reason we treat this bit as a device bit
and not as a transport bit for now.
After all drivers are converted, we will be able to
move VERSION_1 to core and drop it from all drivers.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
include/uapi/linux/virtio_config.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h
index 3ce768c..80e7381 100644
--- a/include/uapi/linux/virtio_config.h
+++ b/include/uapi/linux/virtio_config.h
@@ -54,4 +54,7 @@
/* Can the device handle any descriptor layout? */
#define VIRTIO_F_ANY_LAYOUT 27
+/* v1.0 compliant. */
+#define VIRTIO_F_VERSION_1 32
+
#endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */
--
MST
^ permalink raw reply related
* [PATCH v5 07/45] virtio: memory access APIs
From: Michael S. Tsirkin @ 2014-11-27 12:30 UTC (permalink / raw)
To: linux-kernel
Cc: David Miller, cornelia.huck, rusty, nab, pbonzini, thuth, dahi,
Rusty Russell, Greg Kroah-Hartman, Alexei Starovoitov,
stephen hemminger, =?UTF-8?q?Piotr=20Kr=C3=B3l?=, Anup Patel,
Bjarke Istrup Pedersen, virtualization, linux-api
In-Reply-To: <1417091078-24611-1-git-send-email-mst@redhat.com>
virtio 1.0 makes all memory structures LE, so
we need APIs to conditionally do a byteswap on BE
architectures.
To make it easier to check code statically,
add virtio specific types for multi-byte integers
in memory.
Add low level wrappers that do a byteswap conditionally, these will be
useful e.g. for vhost. Add high level wrappers that
query device endian-ness and act accordingly.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/linux/virtio_byteorder.h | 59 +++++++++++++++++++++++++++++++++++++++
include/linux/virtio_config.h | 32 +++++++++++++++++++++
include/uapi/linux/virtio_ring.h | 45 ++++++++++++++---------------
include/uapi/linux/virtio_types.h | 46 ++++++++++++++++++++++++++++++
include/uapi/linux/Kbuild | 1 +
5 files changed, 161 insertions(+), 22 deletions(-)
create mode 100644 include/linux/virtio_byteorder.h
create mode 100644 include/uapi/linux/virtio_types.h
diff --git a/include/linux/virtio_byteorder.h b/include/linux/virtio_byteorder.h
new file mode 100644
index 0000000..51865d0
--- /dev/null
+++ b/include/linux/virtio_byteorder.h
@@ -0,0 +1,59 @@
+#ifndef _LINUX_VIRTIO_BYTEORDER_H
+#define _LINUX_VIRTIO_BYTEORDER_H
+#include <linux/types.h>
+#include <uapi/linux/virtio_types.h>
+
+/*
+ * Low-level memory accessors for handling virtio in modern little endian and in
+ * compatibility native endian format.
+ */
+
+static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
+{
+ if (little_endian)
+ return le16_to_cpu((__force __le16)val);
+ else
+ return (__force u16)val;
+}
+
+static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
+{
+ if (little_endian)
+ return (__force __virtio16)cpu_to_le16(val);
+ else
+ return (__force __virtio16)val;
+}
+
+static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
+{
+ if (little_endian)
+ return le32_to_cpu((__force __le32)val);
+ else
+ return (__force u32)val;
+}
+
+static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
+{
+ if (little_endian)
+ return (__force __virtio32)cpu_to_le32(val);
+ else
+ return (__force __virtio32)val;
+}
+
+static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
+{
+ if (little_endian)
+ return le64_to_cpu((__force __le64)val);
+ else
+ return (__force u64)val;
+}
+
+static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
+{
+ if (little_endian)
+ return (__force __virtio64)cpu_to_le64(val);
+ else
+ return (__force __virtio64)val;
+}
+
+#endif /* _LINUX_VIRTIO_BYTEORDER */
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 022d904..b9cd689 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -4,6 +4,7 @@
#include <linux/err.h>
#include <linux/bug.h>
#include <linux/virtio.h>
+#include <linux/virtio_byteorder.h>
#include <uapi/linux/virtio_config.h>
/**
@@ -152,6 +153,37 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
return 0;
}
+/* Memory accessors */
+static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
+{
+ return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+}
+
+static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
+{
+ return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+}
+
+static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
+{
+ return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+}
+
+static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
+{
+ return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+}
+
+static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
+{
+ return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+}
+
+static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
+{
+ return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+}
+
/* Config space accessors. */
#define virtio_cread(vdev, structname, member, ptr) \
do { \
diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
index a99f9b7..61c818a 100644
--- a/include/uapi/linux/virtio_ring.h
+++ b/include/uapi/linux/virtio_ring.h
@@ -32,6 +32,7 @@
*
* Copyright Rusty Russell IBM Corporation 2007. */
#include <linux/types.h>
+#include <linux/virtio_types.h>
/* This marks a buffer as continuing via the next field. */
#define VRING_DESC_F_NEXT 1
@@ -61,32 +62,32 @@
/* Virtio ring descriptors: 16 bytes. These can chain together via "next". */
struct vring_desc {
/* Address (guest-physical). */
- __u64 addr;
+ __virtio64 addr;
/* Length. */
- __u32 len;
+ __virtio32 len;
/* The flags as indicated above. */
- __u16 flags;
+ __virtio16 flags;
/* We chain unused descriptors via this, too */
- __u16 next;
+ __virtio16 next;
};
struct vring_avail {
- __u16 flags;
- __u16 idx;
- __u16 ring[];
+ __virtio16 flags;
+ __virtio16 idx;
+ __virtio16 ring[];
};
/* u32 is used here for ids for padding reasons. */
struct vring_used_elem {
/* Index of start of used descriptor chain. */
- __u32 id;
+ __virtio32 id;
/* Total length of the descriptor chain which was used (written to) */
- __u32 len;
+ __virtio32 len;
};
struct vring_used {
- __u16 flags;
- __u16 idx;
+ __virtio16 flags;
+ __virtio16 idx;
struct vring_used_elem ring[];
};
@@ -109,25 +110,25 @@ struct vring {
* struct vring_desc desc[num];
*
* // A ring of available descriptor heads with free-running index.
- * __u16 avail_flags;
- * __u16 avail_idx;
- * __u16 available[num];
- * __u16 used_event_idx;
+ * __virtio16 avail_flags;
+ * __virtio16 avail_idx;
+ * __virtio16 available[num];
+ * __virtio16 used_event_idx;
*
* // Padding to the next align boundary.
* char pad[];
*
* // A ring of used descriptor heads with free-running index.
- * __u16 used_flags;
- * __u16 used_idx;
+ * __virtio16 used_flags;
+ * __virtio16 used_idx;
* struct vring_used_elem used[num];
- * __u16 avail_event_idx;
+ * __virtio16 avail_event_idx;
* };
*/
/* We publish the used event index at the end of the available ring, and vice
* versa. They are at the end for backwards compatibility. */
#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
-#define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num])
+#define vring_avail_event(vr) (*(__virtio16 *)&(vr)->used->ring[(vr)->num])
static inline void vring_init(struct vring *vr, unsigned int num, void *p,
unsigned long align)
@@ -135,15 +136,15 @@ static inline void vring_init(struct vring *vr, unsigned int num, void *p,
vr->num = num;
vr->desc = p;
vr->avail = p + num*sizeof(struct vring_desc);
- vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__u16)
+ vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__virtio16)
+ align-1) & ~(align - 1));
}
static inline unsigned vring_size(unsigned int num, unsigned long align)
{
- return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
+ return ((sizeof(struct vring_desc) * num + sizeof(__virtio16) * (3 + num)
+ align - 1) & ~(align - 1))
- + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
+ + sizeof(__virtio16) * 3 + sizeof(struct vring_used_elem) * num;
}
/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */
diff --git a/include/uapi/linux/virtio_types.h b/include/uapi/linux/virtio_types.h
new file mode 100644
index 0000000..e845e8c
--- /dev/null
+++ b/include/uapi/linux/virtio_types.h
@@ -0,0 +1,46 @@
+#ifndef _UAPI_LINUX_VIRTIO_TYPES_H
+#define _UAPI_LINUX_VIRTIO_TYPES_H
+/* Type definitions for virtio implementations.
+ *
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ */
+#include <linux/types.h>
+
+/*
+ * __virtio{16,32,64} have the following meaning:
+ * - __u{16,32,64} for virtio devices in legacy mode, accessed in native endian
+ * - __le{16,32,64} for standard-compliant virtio devices
+ */
+
+typedef __u16 __bitwise__ __virtio16;
+typedef __u32 __bitwise__ __virtio32;
+typedef __u64 __bitwise__ __virtio64;
+
+#endif /* _UAPI_LINUX_VIRTIO_TYPES_H */
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 4c94f31..44a5581 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -423,6 +423,7 @@ header-y += virtio_blk.h
header-y += virtio_config.h
header-y += virtio_console.h
header-y += virtio_ids.h
+header-y += virtio_types.h
header-y += virtio_net.h
header-y += virtio_pci.h
header-y += virtio_ring.h
--
MST
^ permalink raw reply related
* [PATCH v5 11/45] virtio: set FEATURES_OK
From: Michael S. Tsirkin @ 2014-11-27 12:31 UTC (permalink / raw)
To: linux-kernel
Cc: thuth, rusty, linux-api, virtualization, dahi, pbonzini,
David Miller
In-Reply-To: <1417091078-24611-1-git-send-email-mst@redhat.com>
set FEATURES_OK as per virtio 1.0 spec
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/uapi/linux/virtio_config.h | 2 ++
drivers/virtio/virtio.c | 29 ++++++++++++++++++++++-------
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h
index 80e7381..4d05671 100644
--- a/include/uapi/linux/virtio_config.h
+++ b/include/uapi/linux/virtio_config.h
@@ -38,6 +38,8 @@
#define VIRTIO_CONFIG_S_DRIVER 2
/* Driver has used its parts of the config, and is happy */
#define VIRTIO_CONFIG_S_DRIVER_OK 4
+/* Driver has finished configuring features */
+#define VIRTIO_CONFIG_S_FEATURES_OK 8
/* We've given up on this device. */
#define VIRTIO_CONFIG_S_FAILED 0x80
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index d213567..6faa014 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -160,6 +160,7 @@ static int virtio_dev_probe(struct device *_d)
struct virtio_device *dev = dev_to_virtio(_d);
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
u64 device_features;
+ unsigned status;
/* We have a driver! */
add_status(dev, VIRTIO_CONFIG_S_DRIVER);
@@ -183,18 +184,32 @@ static int virtio_dev_probe(struct device *_d)
dev->config->finalize_features(dev);
+ if (virtio_has_feature(dev, VIRTIO_F_VERSION_1)) {
+ add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
+ status = dev->config->get_status(dev);
+ if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
+ dev_err(_d, "virtio: device refuses features: %x\n",
+ status);
+ err = -ENODEV;
+ goto err;
+ }
+ }
+
err = drv->probe(dev);
if (err)
- add_status(dev, VIRTIO_CONFIG_S_FAILED);
- else {
- add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
- if (drv->scan)
- drv->scan(dev);
+ goto err;
- virtio_config_enable(dev);
- }
+ add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+ if (drv->scan)
+ drv->scan(dev);
+
+ virtio_config_enable(dev);
+ return 0;
+err:
+ add_status(dev, VIRTIO_CONFIG_S_FAILED);
return err;
+
}
static int virtio_dev_remove(struct device *_d)
--
MST
^ permalink raw reply related
* [PATCH v5 14/45] virtio_net: v1.0 endianness
From: Michael S. Tsirkin @ 2014-11-27 12:31 UTC (permalink / raw)
To: linux-kernel
Cc: thuth, rusty, netdev, virtualization, dahi, linux-api, pbonzini,
David Miller
In-Reply-To: <1417091078-24611-1-git-send-email-mst@redhat.com>
Based on patches by Rusty Russell, Cornelia Huck.
Note: more code changes are needed for 1.0 support
(due to different header size).
So we don't advertize support for 1.0 yet.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/uapi/linux/virtio_net.h | 15 ++++++++-------
drivers/net/virtio_net.c | 33 ++++++++++++++++++++-------------
2 files changed, 28 insertions(+), 20 deletions(-)
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index 172a7f0..b5f1677 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -28,6 +28,7 @@
#include <linux/types.h>
#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
+#include <linux/virtio_types.h>
#include <linux/if_ether.h>
/* The feature bitmap for virtio net */
@@ -84,17 +85,17 @@ struct virtio_net_hdr {
#define VIRTIO_NET_HDR_GSO_TCPV6 4 // GSO frame, IPv6 TCP
#define VIRTIO_NET_HDR_GSO_ECN 0x80 // TCP has ECN set
__u8 gso_type;
- __u16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */
- __u16 gso_size; /* Bytes to append to hdr_len per frame */
- __u16 csum_start; /* Position to start checksumming from */
- __u16 csum_offset; /* Offset after that to place checksum */
+ __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */
+ __virtio16 gso_size; /* Bytes to append to hdr_len per frame */
+ __virtio16 csum_start; /* Position to start checksumming from */
+ __virtio16 csum_offset; /* Offset after that to place checksum */
};
/* This is the version of the header to use when the MRG_RXBUF
* feature has been negotiated. */
struct virtio_net_hdr_mrg_rxbuf {
struct virtio_net_hdr hdr;
- __u16 num_buffers; /* Number of merged rx buffers */
+ __virtio16 num_buffers; /* Number of merged rx buffers */
};
/*
@@ -149,7 +150,7 @@ typedef __u8 virtio_net_ctrl_ack;
* VIRTIO_NET_F_CTRL_MAC_ADDR feature is available.
*/
struct virtio_net_ctrl_mac {
- __u32 entries;
+ __virtio32 entries;
__u8 macs[][ETH_ALEN];
} __attribute__((packed));
@@ -193,7 +194,7 @@ struct virtio_net_ctrl_mac {
* specified.
*/
struct virtio_net_ctrl_mq {
- __u16 virtqueue_pairs;
+ __virtio16 virtqueue_pairs;
};
#define VIRTIO_NET_CTRL_MQ 4
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index b0bc8ea..c07e030 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -347,13 +347,14 @@ err:
}
static struct sk_buff *receive_mergeable(struct net_device *dev,
+ struct virtnet_info *vi,
struct receive_queue *rq,
unsigned long ctx,
unsigned int len)
{
void *buf = mergeable_ctx_to_buf_address(ctx);
struct skb_vnet_hdr *hdr = buf;
- int num_buf = hdr->mhdr.num_buffers;
+ u16 num_buf = virtio16_to_cpu(rq->vq->vdev, hdr->mhdr.num_buffers);
struct page *page = virt_to_head_page(buf);
int offset = buf - page_address(page);
unsigned int truesize = max(len, mergeable_ctx_to_buf_truesize(ctx));
@@ -369,7 +370,9 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
ctx = (unsigned long)virtqueue_get_buf(rq->vq, &len);
if (unlikely(!ctx)) {
pr_debug("%s: rx error: %d buffers out of %d missing\n",
- dev->name, num_buf, hdr->mhdr.num_buffers);
+ dev->name, num_buf,
+ virtio16_to_cpu(rq->vq->vdev,
+ hdr->mhdr.num_buffers));
dev->stats.rx_length_errors++;
goto err_buf;
}
@@ -454,7 +457,7 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
}
if (vi->mergeable_rx_bufs)
- skb = receive_mergeable(dev, rq, (unsigned long)buf, len);
+ skb = receive_mergeable(dev, vi, rq, (unsigned long)buf, len);
else if (vi->big_packets)
skb = receive_big(dev, rq, buf, len);
else
@@ -473,8 +476,8 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
if (hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
pr_debug("Needs csum!\n");
if (!skb_partial_csum_set(skb,
- hdr->hdr.csum_start,
- hdr->hdr.csum_offset))
+ virtio16_to_cpu(vi->vdev, hdr->hdr.csum_start),
+ virtio16_to_cpu(vi->vdev, hdr->hdr.csum_offset)))
goto frame_err;
} else if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -514,7 +517,8 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
if (hdr->hdr.gso_type & VIRTIO_NET_HDR_GSO_ECN)
skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
- skb_shinfo(skb)->gso_size = hdr->hdr.gso_size;
+ skb_shinfo(skb)->gso_size = virtio16_to_cpu(vi->vdev,
+ hdr->hdr.gso_size);
if (skb_shinfo(skb)->gso_size == 0) {
net_warn_ratelimited("%s: zero gso size.\n", dev->name);
goto frame_err;
@@ -876,16 +880,19 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
if (skb->ip_summed == CHECKSUM_PARTIAL) {
hdr->hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
- hdr->hdr.csum_start = skb_checksum_start_offset(skb);
- hdr->hdr.csum_offset = skb->csum_offset;
+ hdr->hdr.csum_start = cpu_to_virtio16(vi->vdev,
+ skb_checksum_start_offset(skb));
+ hdr->hdr.csum_offset = cpu_to_virtio16(vi->vdev,
+ skb->csum_offset);
} else {
hdr->hdr.flags = 0;
hdr->hdr.csum_offset = hdr->hdr.csum_start = 0;
}
if (skb_is_gso(skb)) {
- hdr->hdr.hdr_len = skb_headlen(skb);
- hdr->hdr.gso_size = skb_shinfo(skb)->gso_size;
+ hdr->hdr.hdr_len = cpu_to_virtio16(vi->vdev, skb_headlen(skb));
+ hdr->hdr.gso_size = cpu_to_virtio16(vi->vdev,
+ skb_shinfo(skb)->gso_size);
if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
@@ -1112,7 +1119,7 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ))
return 0;
- s.virtqueue_pairs = queue_pairs;
+ s.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
sg_init_one(&sg, &s, sizeof(s));
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
@@ -1189,7 +1196,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
sg_init_table(sg, 2);
/* Store the unicast list and count in the front of the buffer */
- mac_data->entries = uc_count;
+ mac_data->entries = cpu_to_virtio32(vi->vdev, uc_count);
i = 0;
netdev_for_each_uc_addr(ha, dev)
memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
@@ -1200,7 +1207,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
/* multicast list and count fill the end */
mac_data = (void *)&mac_data->macs[uc_count][0];
- mac_data->entries = mc_count;
+ mac_data->entries = cpu_to_virtio32(vi->vdev, mc_count);
i = 0;
netdev_for_each_mc_addr(ha, dev)
memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
--
MST
^ permalink raw reply related
* [PATCH v5 15/45] virtio_blk: v1.0 support
From: Michael S. Tsirkin @ 2014-11-27 12:31 UTC (permalink / raw)
To: linux-kernel
Cc: David Miller, cornelia.huck, rusty, nab, pbonzini, thuth, dahi,
Rusty Russell, virtualization, linux-api
In-Reply-To: <1417091078-24611-1-git-send-email-mst@redhat.com>
Based on patch by Cornelia Huck.
Note: for consistency, and to avoid sparse errors,
convert all fields, even those no longer in use
for virtio v1.0.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/uapi/linux/virtio_blk.h | 15 ++++-----
drivers/block/virtio_blk.c | 70 ++++++++++++++++++++++++-----------------
2 files changed, 49 insertions(+), 36 deletions(-)
diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_blk.h
index 9ad67b2..247c8ba 100644
--- a/include/uapi/linux/virtio_blk.h
+++ b/include/uapi/linux/virtio_blk.h
@@ -28,6 +28,7 @@
#include <linux/types.h>
#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
+#include <linux/virtio_types.h>
/* Feature bits */
#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
@@ -114,18 +115,18 @@ struct virtio_blk_config {
/* This is the first element of the read scatter-gather list. */
struct virtio_blk_outhdr {
/* VIRTIO_BLK_T* */
- __u32 type;
+ __virtio32 type;
/* io priority. */
- __u32 ioprio;
+ __virtio32 ioprio;
/* Sector (ie. 512 byte offset) */
- __u64 sector;
+ __virtio64 sector;
};
struct virtio_scsi_inhdr {
- __u32 errors;
- __u32 data_len;
- __u32 sense_len;
- __u32 residual;
+ __virtio32 errors;
+ __virtio32 data_len;
+ __virtio32 sense_len;
+ __virtio32 residual;
};
/* And this is the final byte of the write scatter-gather list. */
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index c6a27d5..f601f16 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -80,7 +80,7 @@ static int __virtblk_add_req(struct virtqueue *vq,
{
struct scatterlist hdr, status, cmd, sense, inhdr, *sgs[6];
unsigned int num_out = 0, num_in = 0;
- int type = vbr->out_hdr.type & ~VIRTIO_BLK_T_OUT;
+ __virtio32 type = vbr->out_hdr.type & ~cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT);
sg_init_one(&hdr, &vbr->out_hdr, sizeof(vbr->out_hdr));
sgs[num_out++] = &hdr;
@@ -91,19 +91,19 @@ static int __virtblk_add_req(struct virtqueue *vq,
* block, and before the normal inhdr we put the sense data and the
* inhdr with additional status information.
*/
- if (type == VIRTIO_BLK_T_SCSI_CMD) {
+ if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) {
sg_init_one(&cmd, vbr->req->cmd, vbr->req->cmd_len);
sgs[num_out++] = &cmd;
}
if (have_data) {
- if (vbr->out_hdr.type & VIRTIO_BLK_T_OUT)
+ if (vbr->out_hdr.type & cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT))
sgs[num_out++] = data_sg;
else
sgs[num_out + num_in++] = data_sg;
}
- if (type == VIRTIO_BLK_T_SCSI_CMD) {
+ if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) {
sg_init_one(&sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE);
sgs[num_out + num_in++] = &sense;
sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr));
@@ -119,12 +119,13 @@ static int __virtblk_add_req(struct virtqueue *vq,
static inline void virtblk_request_done(struct request *req)
{
struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
+ struct virtio_blk *vblk = req->q->queuedata;
int error = virtblk_result(vbr);
if (req->cmd_type == REQ_TYPE_BLOCK_PC) {
- req->resid_len = vbr->in_hdr.residual;
- req->sense_len = vbr->in_hdr.sense_len;
- req->errors = vbr->in_hdr.errors;
+ req->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual);
+ req->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
+ req->errors = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors);
} else if (req->cmd_type == REQ_TYPE_SPECIAL) {
req->errors = (error != 0);
}
@@ -173,25 +174,25 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req,
vbr->req = req;
if (req->cmd_flags & REQ_FLUSH) {
- vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
+ vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_FLUSH);
vbr->out_hdr.sector = 0;
- vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
+ vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req));
} else {
switch (req->cmd_type) {
case REQ_TYPE_FS:
vbr->out_hdr.type = 0;
- vbr->out_hdr.sector = blk_rq_pos(vbr->req);
- vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
+ vbr->out_hdr.sector = cpu_to_virtio64(vblk->vdev, blk_rq_pos(vbr->req));
+ vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req));
break;
case REQ_TYPE_BLOCK_PC:
- vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
+ vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_SCSI_CMD);
vbr->out_hdr.sector = 0;
- vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
+ vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req));
break;
case REQ_TYPE_SPECIAL:
- vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID;
+ vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_GET_ID);
vbr->out_hdr.sector = 0;
- vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
+ vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req));
break;
default:
/* We don't put anything else in the queue. */
@@ -204,9 +205,9 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req,
num = blk_rq_map_sg(hctx->queue, vbr->req, vbr->sg);
if (num) {
if (rq_data_dir(vbr->req) == WRITE)
- vbr->out_hdr.type |= VIRTIO_BLK_T_OUT;
+ vbr->out_hdr.type |= cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_OUT);
else
- vbr->out_hdr.type |= VIRTIO_BLK_T_IN;
+ vbr->out_hdr.type |= cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_IN);
}
spin_lock_irqsave(&vblk->vqs[qid].lock, flags);
@@ -476,7 +477,8 @@ static int virtblk_get_cache_mode(struct virtio_device *vdev)
struct virtio_blk_config, wce,
&writeback);
if (err)
- writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE);
+ writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE) ||
+ virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
return writeback;
}
@@ -821,25 +823,35 @@ static const struct virtio_device_id id_table[] = {
{ 0 },
};
-static unsigned int features[] = {
+static unsigned int features_legacy[] = {
VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY,
VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_SCSI,
VIRTIO_BLK_F_WCE, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
VIRTIO_BLK_F_MQ,
+}
+;
+static unsigned int features[] = {
+ VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY,
+ VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
+ VIRTIO_BLK_F_TOPOLOGY,
+ VIRTIO_BLK_F_MQ,
+ VIRTIO_F_VERSION_1,
};
static struct virtio_driver virtio_blk = {
- .feature_table = features,
- .feature_table_size = ARRAY_SIZE(features),
- .driver.name = KBUILD_MODNAME,
- .driver.owner = THIS_MODULE,
- .id_table = id_table,
- .probe = virtblk_probe,
- .remove = virtblk_remove,
- .config_changed = virtblk_config_changed,
+ .feature_table = features,
+ .feature_table_size = ARRAY_SIZE(features),
+ .feature_table_legacy = features_legacy,
+ .feature_table_size_legacy = ARRAY_SIZE(features_legacy),
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = id_table,
+ .probe = virtblk_probe,
+ .remove = virtblk_remove,
+ .config_changed = virtblk_config_changed,
#ifdef CONFIG_PM_SLEEP
- .freeze = virtblk_freeze,
- .restore = virtblk_restore,
+ .freeze = virtblk_freeze,
+ .restore = virtblk_restore,
#endif
};
--
MST
^ permalink raw reply related
* [PATCH v5 36/45] tun: move internal flag defines out of uapi
From: Michael S. Tsirkin @ 2014-11-27 12:33 UTC (permalink / raw)
To: linux-kernel
Cc: David Miller, cornelia.huck, rusty, nab, pbonzini, thuth, dahi,
Jason Wang, Zhi Yong Wu, Herbert Xu, Tom Herbert, Masatake YAMATO,
Xi Wang, netdev, linux-api
In-Reply-To: <1417091078-24611-1-git-send-email-mst@redhat.com>
TUN_ flags are internal and never exposed
to userspace. Any application using it is almost
certainly buggy.
Move them out to tun.c, we'll remove them in follow-up patches.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/uapi/linux/if_tun.h | 16 ++--------
drivers/net/tun.c | 74 ++++++++++++++-------------------------------
2 files changed, 26 insertions(+), 64 deletions(-)
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index e9502dd..277a260 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -22,21 +22,11 @@
/* Read queue size */
#define TUN_READQ_SIZE 500
-
-/* TUN device flags */
-#define TUN_TUN_DEV 0x0001
-#define TUN_TAP_DEV 0x0002
+/* TUN device type flags: deprecated. Use IFF_TUN/IFF_TAP instead. */
+#define TUN_TUN_DEV IFF_TUN
+#define TUN_TAP_DEV IFF_TAP
#define TUN_TYPE_MASK 0x000f
-#define TUN_FASYNC 0x0010
-#define TUN_NOCHECKSUM 0x0020
-#define TUN_NO_PI 0x0040
-/* This flag has no real effect */
-#define TUN_ONE_QUEUE 0x0080
-#define TUN_PERSIST 0x0100
-#define TUN_VNET_HDR 0x0200
-#define TUN_TAP_MQ 0x0400
-
/* Ioctl defines */
#define TUNSETNOCSUM _IOW('T', 200, int)
#define TUNSETDEBUG _IOW('T', 201, int)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 9dd3746..bc89d07 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -103,6 +103,21 @@ do { \
} while (0)
#endif
+/* TUN device flags */
+
+/* IFF_ATTACH_QUEUE is never stored in device flags,
+ * overload it to mean fasync when stored there.
+ */
+#define TUN_FASYNC IFF_ATTACH_QUEUE
+#define TUN_NO_PI IFF_NO_PI
+/* This flag has no real effect */
+#define TUN_ONE_QUEUE IFF_ONE_QUEUE
+#define TUN_PERSIST IFF_PERSIST
+#define TUN_VNET_HDR IFF_VNET_HDR
+#define TUN_TAP_MQ IFF_MULTI_QUEUE
+
+#define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \
+ IFF_MULTI_QUEUE)
#define GOODCOPY_LEN 128
#define FLT_EXACT_COUNT 8
@@ -1521,32 +1536,7 @@ static struct proto tun_proto = {
static int tun_flags(struct tun_struct *tun)
{
- int flags = 0;
-
- if (tun->flags & TUN_TUN_DEV)
- flags |= IFF_TUN;
- else
- flags |= IFF_TAP;
-
- if (tun->flags & TUN_NO_PI)
- flags |= IFF_NO_PI;
-
- /* This flag has no real effect. We track the value for backwards
- * compatibility.
- */
- if (tun->flags & TUN_ONE_QUEUE)
- flags |= IFF_ONE_QUEUE;
-
- if (tun->flags & TUN_VNET_HDR)
- flags |= IFF_VNET_HDR;
-
- if (tun->flags & TUN_TAP_MQ)
- flags |= IFF_MULTI_QUEUE;
-
- if (tun->flags & TUN_PERSIST)
- flags |= IFF_PERSIST;
-
- return flags;
+ return tun->flags & (TUN_FEATURES | IFF_PERSIST | IFF_TUN | IFF_TAP);
}
static ssize_t tun_show_flags(struct device *dev, struct device_attribute *attr,
@@ -1706,28 +1696,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun_debug(KERN_INFO, tun, "tun_set_iff\n");
- if (ifr->ifr_flags & IFF_NO_PI)
- tun->flags |= TUN_NO_PI;
- else
- tun->flags &= ~TUN_NO_PI;
-
- /* This flag has no real effect. We track the value for backwards
- * compatibility.
- */
- if (ifr->ifr_flags & IFF_ONE_QUEUE)
- tun->flags |= TUN_ONE_QUEUE;
- else
- tun->flags &= ~TUN_ONE_QUEUE;
-
- if (ifr->ifr_flags & IFF_VNET_HDR)
- tun->flags |= TUN_VNET_HDR;
- else
- tun->flags &= ~TUN_VNET_HDR;
-
- if (ifr->ifr_flags & IFF_MULTI_QUEUE)
- tun->flags |= TUN_TAP_MQ;
- else
- tun->flags &= ~TUN_TAP_MQ;
+ tun->flags = (tun->flags & ~TUN_FEATURES) |
+ (ifr->ifr_flags & TUN_FEATURES);
/* Make sure persistent devices do not get stuck in
* xoff state.
@@ -1890,9 +1860,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
if (cmd == TUNGETFEATURES) {
/* Currently this just means: "what IFF flags are valid?".
* This is needed because we never checked for invalid flags on
- * TUNSETIFF. */
- return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
- IFF_VNET_HDR | IFF_MULTI_QUEUE,
+ * TUNSETIFF. Why do we report IFF_TUN and IFF_TAP which are
+ * not legal for TUNSETIFF here? It's probably a bug, but it
+ * doesn't seem to be worth fixing.
+ */
+ return put_user(IFF_TUN | IFF_TAP | TUN_FEATURES,
(unsigned int __user*)argp);
} else if (cmd == TUNSETQUEUE)
return tun_set_queue(file, &ifr);
--
MST
^ permalink raw reply related
* [PATCH v5 38/45] tun: add VNET_LE flag
From: Michael S. Tsirkin @ 2014-11-27 12:33 UTC (permalink / raw)
To: linux-kernel
Cc: David Miller, cornelia.huck, rusty, nab, pbonzini, thuth, dahi,
netdev, linux-api
In-Reply-To: <1417091078-24611-1-git-send-email-mst@redhat.com>
virtio 1.0 modified virtio net header format,
making all fields little endian.
Users can tweak header format before submitting it to tun,
but this means more data copies where none were necessary.
And if the iovec is in RO memory, this means we might
need to split iovec also means we might in theory overflow
iovec max size.
This patch adds a simpler way for applications to handle this,
using new "little endian" flag in tun.
As a result, tun simply byte-swaps header fields as appropriate.
This is a NOP on LE architectures.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/uapi/linux/if_tun.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index 277a260..18b2403 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -57,6 +57,7 @@
#define IFF_ONE_QUEUE 0x2000
#define IFF_VNET_HDR 0x4000
#define IFF_TUN_EXCL 0x8000
+#define IFF_VNET_LE 0x10000
#define IFF_MULTI_QUEUE 0x0100
#define IFF_ATTACH_QUEUE 0x0200
#define IFF_DETACH_QUEUE 0x0400
--
MST
^ permalink raw reply related
* [PATCH v5 43/45] virtio_scsi: export to userspace
From: Michael S. Tsirkin @ 2014-11-27 12:33 UTC (permalink / raw)
To: linux-kernel
Cc: David Miller, cornelia.huck, rusty, nab, pbonzini, thuth, dahi,
Rusty Russell, Greg Kroah-Hartman, Alexei Starovoitov,
Andy Grover, Sakari Ailus, David Drysdale,
=?UTF-8?q?Piotr=20Kr=C3=B3l?=, stephen hemminger, linux-api,
virtualization
In-Reply-To: <1417091078-24611-1-git-send-email-mst@redhat.com>
Replace uXX by __uXX and _packed by __attribute((packed))
as seems to be the norm for userspace headers.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/uapi/linux/virtio_scsi.h | 74 ++++++++++++++++++++--------------------
include/uapi/linux/Kbuild | 1 +
2 files changed, 38 insertions(+), 37 deletions(-)
diff --git a/include/uapi/linux/virtio_scsi.h b/include/uapi/linux/virtio_scsi.h
index af44864..42b9370 100644
--- a/include/uapi/linux/virtio_scsi.h
+++ b/include/uapi/linux/virtio_scsi.h
@@ -34,78 +34,78 @@
/* SCSI command request, followed by data-out */
struct virtio_scsi_cmd_req {
- u8 lun[8]; /* Logical Unit Number */
+ __u8 lun[8]; /* Logical Unit Number */
__virtio64 tag; /* Command identifier */
- u8 task_attr; /* Task attribute */
- u8 prio; /* SAM command priority field */
- u8 crn;
- u8 cdb[VIRTIO_SCSI_CDB_SIZE];
-} __packed;
+ __u8 task_attr; /* Task attribute */
+ __u8 prio; /* SAM command priority field */
+ __u8 crn;
+ __u8 cdb[VIRTIO_SCSI_CDB_SIZE];
+} __attribute__((packed));
/* SCSI command request, followed by protection information */
struct virtio_scsi_cmd_req_pi {
- u8 lun[8]; /* Logical Unit Number */
+ __u8 lun[8]; /* Logical Unit Number */
__virtio64 tag; /* Command identifier */
- u8 task_attr; /* Task attribute */
- u8 prio; /* SAM command priority field */
- u8 crn;
+ __u8 task_attr; /* Task attribute */
+ __u8 prio; /* SAM command priority field */
+ __u8 crn;
__virtio32 pi_bytesout; /* DataOUT PI Number of bytes */
__virtio32 pi_bytesin; /* DataIN PI Number of bytes */
- u8 cdb[VIRTIO_SCSI_CDB_SIZE];
-} __packed;
+ __u8 cdb[VIRTIO_SCSI_CDB_SIZE];
+} __attribute__((packed));
/* Response, followed by sense data and data-in */
struct virtio_scsi_cmd_resp {
__virtio32 sense_len; /* Sense data length */
__virtio32 resid; /* Residual bytes in data buffer */
__virtio16 status_qualifier; /* Status qualifier */
- u8 status; /* Command completion status */
- u8 response; /* Response values */
- u8 sense[VIRTIO_SCSI_SENSE_SIZE];
-} __packed;
+ __u8 status; /* Command completion status */
+ __u8 response; /* Response values */
+ __u8 sense[VIRTIO_SCSI_SENSE_SIZE];
+} __attribute__((packed));
/* Task Management Request */
struct virtio_scsi_ctrl_tmf_req {
__virtio32 type;
__virtio32 subtype;
- u8 lun[8];
+ __u8 lun[8];
__virtio64 tag;
-} __packed;
+} __attribute__((packed));
struct virtio_scsi_ctrl_tmf_resp {
- u8 response;
-} __packed;
+ __u8 response;
+} __attribute__((packed));
/* Asynchronous notification query/subscription */
struct virtio_scsi_ctrl_an_req {
__virtio32 type;
- u8 lun[8];
+ __u8 lun[8];
__virtio32 event_requested;
-} __packed;
+} __attribute__((packed));
struct virtio_scsi_ctrl_an_resp {
__virtio32 event_actual;
- u8 response;
-} __packed;
+ __u8 response;
+} __attribute__((packed));
struct virtio_scsi_event {
__virtio32 event;
- u8 lun[8];
+ __u8 lun[8];
__virtio32 reason;
-} __packed;
+} __attribute__((packed));
struct virtio_scsi_config {
- u32 num_queues;
- u32 seg_max;
- u32 max_sectors;
- u32 cmd_per_lun;
- u32 event_info_size;
- u32 sense_size;
- u32 cdb_size;
- u16 max_channel;
- u16 max_target;
- u32 max_lun;
-} __packed;
+ __u32 num_queues;
+ __u32 seg_max;
+ __u32 max_sectors;
+ __u32 cmd_per_lun;
+ __u32 event_info_size;
+ __u32 sense_size;
+ __u32 cdb_size;
+ __u16 max_channel;
+ __u16 max_target;
+ __u32 max_lun;
+} __attribute__((packed));
/* Feature Bits */
#define VIRTIO_SCSI_F_INOUT 0
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 44a5581..e61947c 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -428,6 +428,7 @@ header-y += virtio_net.h
header-y += virtio_pci.h
header-y += virtio_ring.h
header-y += virtio_rng.h
+header-y += virtio_scsi.h
header=y += vm_sockets.h
header-y += vt.h
header-y += wait.h
--
MST
^ permalink raw reply related
* Re: [PATCH v3 5/5] tty/serial: Add Spreadtrum sc9836-uart driver support
From: Arnd Bergmann @ 2014-11-27 12:57 UTC (permalink / raw)
To: Lyra Zhang
Cc: Murali Karicheri, Chunyan Zhang, Grant Likely,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, Catalin Marinas,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org,
jslaby-AlSwsSmVLrQ@public.gmane.org, Kumar Gala, Mark Rutland,
Pawel Moll, Ramkumar Ramachandra,
rrichter-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org, Will Deacon,
gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io, Jonathan Corbet,
jason-NLaQJdtUoK4Be96aLqz0jA, Mark Brown, Heiko Stübner,
florian.vaussard-p8DiymsW2f8, andrew-g2DYL2Zd6BY, Hayato Suzuki,
Orson Zhai
In-Reply-To: <CAAfSe-uMqy7zwiEK+nDoMPw_oni8L_vq7oW2Me5AY8z8KGpjwQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Thursday 27 November 2014 19:59:46 Lyra Zhang wrote:
> 2014-11-27 2:29 GMT+08:00 Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>:
> > On 11/25/2014 07:16 AM, Chunyan Zhang wrote:
> >>
> >> Add a full sc9836-uart driver for SC9836 SoC which is based on the
>
> >> +#include<linux/clk.h>
> >
> > How about sorting this includes? asm/irq.h go first followed linux/ in
> > alphabatical order?
>
> >> +static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
> >> +{
> >> + struct uart_port *port = (struct uart_port *)dev_id;
> >> + u32 ims;
> >> +
> >> + ims = serial_in(port, SPRD_IMSR);
> >> +
> >> + serial_out(port, SPRD_ICLR, ~0);
> >> +
> >> + if (ims& (SPRD_IMSR_RX_FIFO_FULL |
> >> + SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) {
> >> + sprd_rx(irq, port);
> >> + }
> >> + if (ims& SPRD_IMSR_TX_FIFO_EMPTY)
> >> + sprd_tx(irq, port);
> >> +
> >> + return IRQ_HANDLED;
> >
> > You are always returning IRQ_HANDLED and this is registered as a SHARED irq.
> > Is there a chance this handler is called and the irq event doesn't
> > belong to this device?
> >
> > Murali
>
> You are right, this is not a SHARED irq. I'll pass 0 for irqflags when
> called 'devm_request_irq' in the next version patch.
I think you could also add
if (!ims)
return IRQ_NONE;
which would make it work on shared interrupt lines.
Arnd
^ permalink raw reply
* Re: [PATCH v3 3/5] arm64: dts: Add support for Spreadtrum SC9836 SoC in dts and Makefile
From: Mark Rutland @ 2014-11-27 13:43 UTC (permalink / raw)
To: Catalin Marinas
Cc: gnomes@lxorguk.ukuu.org.uk, heiko@sntech.de, broonie@linaro.org,
Will Deacon, andrew@lunn.ch, linux-api@vger.kernel.org,
Chunyan Zhang, artagnon@gmail.com, lanqing.liu@spreadtrum.com,
arnd@arndb.de, zhang.lyra@gmail.com, corbet@lwn.net,
jslaby@suse.cz, zhizhou.zhang@spreadtrum.com,
geng.ren@spreadtrum.com, m-karicheri2@ti.com,
linux-arm-kernel@lists.infradead.org,
linux-serial@vger.kernel.org, grant.likely
In-Reply-To: <20141127121214.GF11511@e104818-lin.cambridge.arm.com>
On Thu, Nov 27, 2014 at 12:12:15PM +0000, Catalin Marinas wrote:
> On Thu, Nov 27, 2014 at 11:50:43AM +0000, Mark Rutland wrote:
> > On Tue, Nov 25, 2014 at 12:16:56PM +0000, Chunyan Zhang wrote:
> > > +
> > > + timer {
> > > + compatible = "arm,armv8-timer";
> > > + interrupts = <1 13 0xff01>,
> > > + <1 14 0xff01>,
> > > + <1 11 0xff01>,
> > > + <1 10 0xff01>;
> > > + clock-frequency = <26000000>;
> >
> > Please remove the clock-frequency property. Your FW should initialise
> > CNTFRQ_EL0 on all CPUs (certainly PSCI 0.2 requires that you do this).
>
> Since this comes up regularly, I think we need a dev_warn() in the arch
> timer driver when CONFIG_ARM64.
I'll ack such a patch ;)
Mark.
^ permalink raw reply
* [RFC] LSM/Smack namespace work in progress
From: Lukasz Pawelczyk @ 2014-11-27 14:01 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra, James Morris, Serge E. Hallyn,
Serge Hallyn, Lukasz Pawelczyk, Al Viro, Paul Moore, Kees Cook,
Miklos Szeredi, Jeff Kirsher, Nikolay Aleksandrov, Mark Rustad,
David Howells, Andrew Morton, Oleg Nesterov, Juri Lelli,
Daeseok Youn, David Rientjes, Dario Faggioli, Alex Thorlton,
Matthew Dempsky, Davidlohr Bueso
Cc: Lukasz Pawelczyk
Hello,
I'm in the process of writing a Smack namespace that is based on LSM
namespace hooks that I'm implementing as well. The work is almost
finished and the patches are currently undergoing an internal review.
Smack namespace was designed with collaboration of Smack maintainer
Casey Schaufler.
Meanwhile I'd like to request some comments about the LSM hooks patch
I have here. I realize that maybe it's difficult to evaluate this
without live usage example (that Smack namespace will server as) but
at this point any comments would be great.
Smack namespace have been successfully implemented using these hooks
and to put some context to it I paste here a preliminary kernel
documentation on what Smack namespace wants to achieve.
LSM hooks themselves are documented in the security.h file inside the
patch.
======================================================================
=== What is Smack namespace ===
Smack namespace was developed to make it possible for Smack to work
nicely with Linux containers where there is a full operating system
with its own init inside the namespace. Such a system working with
Smack expects to have at least partially working SMACK_MAC_ADMIN to be
able to change labels of processes and files. This is required to be
able to securely start applications under the control of Smack and
manage their access rights.
It was implemented using LSM namespace hooks that were developed
together with Smack namespace.
=== Design ideas ===
"Smack namespace" is rather "Smack labels namespace" as not the whole
MAC is namespaced, only the labels. There is a great analogy between
Smack labels namespace and the user namespace part that remaps UIDs.
The idea is to create a map of labels for a namespace so the namespace
is only allowed to use those labels. Smack rules are always the same
as in the init namespace (limited only by what labels are mapped) and
cannot be manipulated from the child namespace. The map is actually
only for labels' names. The underlying structures for labels remain
the same. The filesystem also stores the "unmapped" labels from the
init namespace.
Let's say we have those labels in the init namespace:
label1
label2
label3
and those rules:
label1 label2 rwx
label1 label3 rwx
label2 label3 rwx
We create a map for a namespace:
label1 -> mapped1
label2 -> mapped2
This means that 'label3' is completely invisible in the namespace. As if
it didn't exist. All the rules that include it are ignored.
Effectively in the namespace we have only one rule:
mapped1 mapped2 rwx
Which in reality is:
label1 label2 rwx
All requests to access an object with a 'label3' will be denied. If it
ever comes to a situation where 'label3' would have to be printed
(e.g. reading an exec or mmap label from a file to which we have
access) then huh sign '?' will be printed instead.
All the operations in the namespace on the remaining labels will have
to be performed using their mapped names. Things like changing own
process's label, changing filesystem label. Labels will also be
printed with their mapped names.
You cannot import new labels in a namespace. Every operation that
would do so in an init namespace will return an error in the child
namespace. You cannot assign an unmapped or not existing label to an
object. You can only operate on labels that have been explicitly
mapped.
=== Capabilities ===
Smack related capabilities work to some extent. In several places
where capabilities are checked compatibility with Smack namespace has
been introduced. Capabilities are of course also limited to operate
only on mapped labels.
CAP_MAC_OVERRIDE works fully, will allow you to ignore Smack access
rules, but only between objects that have labels mapped. So in the
example above having this CAP will allow e.g. label2 to write to
label1, but will not allow any access to label3.
With CAP_MAC_ADMIN the following operations has been allowed inside
the namespace:
- setting and removing xattr on files, including the security ones
- setting process's own label (/proc/self/attr/current)
- mounting in a privileged Smack mode, which means one can specify
additional mount options like: smackfsdef, smackfsfloor etc.
Again this is also allowed only on the mapped labels. Labels on the
filesystem will be stored in unmapped form so they are preserved
through reboots.
Such a namespace construct allows e.g. systemd (that supports Smack)
working in a container to assign labels properly to daemons and other
processes.
=== Usage ===
Smack namespace is written using LSM hooks. It's a normal namespace
that behaves similarly to all the others existing right now.
You can create a new Smack/LSM namespace using e.g. unshare(). The
labels' map is in a file /proc/$PID/attr_map. By default it's empty so
it has to be filled before any other operation is performed (as no
mapped labels equals no labels inside a namespace equals all the
operations will not be permitted).
Due to the way Smack works only CAP_MAC_ADMIN from the init_user_ns is
allowed to fill the map. That means that for now an unprivileged user
in theory is allowed to create the namespace but it will not allow for
any operation inside. An administrator intervention to fill the
labels' maps is required. The possibility similar to user namespace
where a process could at least remap its own label will be
re-investigated later on.
The attr_map write format is:
unmapped_label mapped_label
When reading the file it shows a current map for a namespace the
process in question is in in the format:
unmapped_label -> mapped_label
Writing to the map file is not disabled after the first write as in
user namespace. For Smack we have no means to map ranges of labels,
hence it can really be advantageous to be able to expand the map later
on. But you can only add to the map. You cannot remove already mapped
labels. You cannot change the already existing mappings. Also mappings
has to be 1-1. All tries to create a map where either the unmapped or
the mapped label already exists in the map will be denied.
setns is also allowed, but the label of a process that is calling
setns has to be already mapped in the target Smack namespace for the
call to succeed.
=== Special labels ===
Smack is using some special labels that have built-in rules. Things
like floor '_', dash '^', star '*', etc. Those labels are not
automatically mapped to the namespace. Moreover, you can choose to map
a different label from the init namespace to behave e.g. like floor
inside the namespace.
Let's say we have no rules and those labels in the init namespace:
_
floor_to_be
label
Both label and floor_to_be can read objects with _. But they have no
access rights to each other.
Now let's create a map like this:
_ ordinary_label
floor_to_be _
label mapped
Right now label 'mapped' can read label '_' which means that
effectively inside this namespace label 'label' has gained read access
to the 'floor_to_be'. The label 'ordinary_label' is exactly it, an
ordinary label that the built-in rules no longer apply to inside the
namespace.
To sum up special labels in the namespace behave the same as in the
init namespace. Not the original special labels though, but the ones
we map to specials. This is the only case where a namespace can have
access rights the init namespace does not have (like the 'label' to
'floor_to_be' in the example above).
=== Current limitations ===
The Smack namespace is not hierarchical yet. It is possible to create
a Smack namespace within the Smack namespace but the creating
namespace will be denied the right to fill the map. Only CAP_MAC_ADMIN
in the init_user_ns can do that now. When hierarchy will be
implemented the process creating another namespace will be allowed to
map only labels that it has permission to itself (those that it has
in its own map).
Special files inside the virtual smackfs needs to be reviewed whether
it's beneficial to have some of their functionality namespaced as well
(e.g. onlycap, syslog. ambient, etc). This would increase
CAP_MAC_ADMIN privileges inside the namespace.
Lukasz Pawelczyk (1):
lsm: namespace hooks
fs/proc/namespaces.c | 4 ++
include/linux/lsm_namespace.h | 68 +++++++++++++++++++
include/linux/nsproxy.h | 2 +
include/linux/proc_ns.h | 2 +
include/linux/security.h | 80 +++++++++++++++++++++++
include/uapi/linux/sched.h | 3 +-
kernel/fork.c | 2 +-
kernel/nsproxy.c | 22 ++++++-
security/Kconfig | 8 +++
security/Makefile | 1 +
security/capability.c | 33 ++++++++++
security/lsm_namespace.c | 147 ++++++++++++++++++++++++++++++++++++++++++
security/security.c | 42 ++++++++++++
13 files changed, 408 insertions(+), 6 deletions(-)
create mode 100644 include/linux/lsm_namespace.h
create mode 100644 security/lsm_namespace.c
--
1.9.3
^ permalink raw reply
* [RFC] lsm: namespace hooks
From: Lukasz Pawelczyk @ 2014-11-27 14:01 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra, James Morris, Serge E. Hallyn,
Serge Hallyn, Lukasz Pawelczyk, Al Viro, Paul Moore, Kees Cook,
Miklos Szeredi, Jeff Kirsher, Nikolay Aleksandrov, Mark Rustad,
David Howells, Andrew Morton, Oleg Nesterov, Juri Lelli,
Daeseok Youn, David Rientjes, Dario Faggioli, Alex Thorlton,
Matthew Dempsky, Davidlohr Bueso
Cc: Lukasz Pawelczyk
In-Reply-To: <1417096866-25563-1-git-send-email-l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
This commit implements an empty LSM namespace that provides 5 hooks for
LSM modules to implement. Using those an LSM module can implement its
own namespace. The first one to take advantage of this mechanism is
Smack.
Look into the comments in the security.h below for info about specific
hooks.
Signed-off-by: Lukasz Pawelczyk <l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
fs/proc/namespaces.c | 4 ++
include/linux/lsm_namespace.h | 68 +++++++++++++++++++
include/linux/nsproxy.h | 2 +
include/linux/proc_ns.h | 2 +
include/linux/security.h | 80 +++++++++++++++++++++++
include/uapi/linux/sched.h | 3 +-
kernel/fork.c | 2 +-
kernel/nsproxy.c | 22 ++++++-
security/Kconfig | 8 +++
security/Makefile | 1 +
security/capability.c | 33 ++++++++++
security/lsm_namespace.c | 147 ++++++++++++++++++++++++++++++++++++++++++
security/security.c | 42 ++++++++++++
13 files changed, 408 insertions(+), 6 deletions(-)
create mode 100644 include/linux/lsm_namespace.h
create mode 100644 security/lsm_namespace.c
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index 8902609..266e8d8 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -12,10 +12,14 @@
#include <linux/ipc_namespace.h>
#include <linux/pid_namespace.h>
#include <linux/user_namespace.h>
+#include <linux/lsm_namespace.h>
#include "internal.h"
static const struct proc_ns_operations *ns_entries[] = {
+#ifdef CONFIG_SECURITY_NS
+ &lsmns_operations,
+#endif
#ifdef CONFIG_NET_NS
&netns_operations,
#endif
diff --git a/include/linux/lsm_namespace.h b/include/linux/lsm_namespace.h
new file mode 100644
index 0000000..7caf3db
--- /dev/null
+++ b/include/linux/lsm_namespace.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics.
+ *
+ * LSM namespaces
+ *
+ * Author(s):
+ * Lukasz Pawelczyk <l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * This program is free software, you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_LSM_S_H
+#define _LINUX_LSM_S_H
+
+#include <linux/sched.h>
+#include <linux/kref.h>
+
+struct lsm_namespace {
+ struct kref kref;
+ struct user_namespace *user_ns;
+ unsigned int proc_inum;
+ /* for LSM usage */
+ void *private;
+};
+
+extern struct lsm_namespace init_lsm_ns;
+
+#ifdef CONFIG_SECURITY_NS
+
+struct lsm_namespace *copy_lsm_ns(unsigned long flags,
+ struct user_namespace *user_ns,
+ struct lsm_namespace *ns);
+void free_lsm_ns(struct kref *kref);
+
+static inline struct lsm_namespace *get_lsm_ns(struct lsm_namespace *ns)
+{
+ kref_get(&ns->kref);
+ return ns;
+}
+
+static inline void put_lsm_ns(struct lsm_namespace *ns)
+{
+ kref_put(&ns->kref, free_lsm_ns);
+}
+
+#else /* CONFIG_SECURITY_NS */
+
+static inline struct lsm_namespace *copy_lsm_ns(unsigned long flags,
+ struct user_namespace *user_ns,
+ struct lsm_namespace *ns)
+{
+ return ns;
+}
+
+static inline struct lsm_namespace *get_lsm_ns(struct lsm_namespace *ns)
+{
+ return ns;
+}
+
+static inline void put_lsm_ns(struct lsm_namespace *ns)
+{
+}
+
+#endif /* CONFIG_SECURITY_NS */
+
+#endif /* _LINUX_LSM_S_H */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index b4ec59d..58c7de1 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -8,6 +8,7 @@ struct mnt_namespace;
struct uts_namespace;
struct ipc_namespace;
struct pid_namespace;
+struct lsm_namespace;
struct fs_struct;
/*
@@ -33,6 +34,7 @@ struct nsproxy {
struct mnt_namespace *mnt_ns;
struct pid_namespace *pid_ns_for_children;
struct net *net_ns;
+ struct lsm_namespace *lsm_ns;
};
extern struct nsproxy init_nsproxy;
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 34a1e10..b5eaa50 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -27,6 +27,7 @@ extern const struct proc_ns_operations ipcns_operations;
extern const struct proc_ns_operations pidns_operations;
extern const struct proc_ns_operations userns_operations;
extern const struct proc_ns_operations mntns_operations;
+extern const struct proc_ns_operations lsmns_operations;
/*
* We always define these enumerators
@@ -37,6 +38,7 @@ enum {
PROC_UTS_INIT_INO = 0xEFFFFFFEU,
PROC_USER_INIT_INO = 0xEFFFFFFDU,
PROC_PID_INIT_INO = 0xEFFFFFFCU,
+ PROC_LSM_INIT_INO = 0xEFFFFFFBU,
};
#ifdef CONFIG_PROC_FS
diff --git a/include/linux/security.h b/include/linux/security.h
index 3b3aeb1..82a6ece 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -144,6 +144,7 @@ extern unsigned long dac_mmap_min_addr;
/* forward declares to avoid warnings */
struct sched_param;
struct request_sock;
+struct lsm_namespace;
/* bprm->unsafe reasons */
#define LSM_UNSAFE_SHARE 1
@@ -1400,6 +1401,37 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* audit_rule_init.
* @rule contains the allocated rule
*
+ * @lsmns_init:
+ * Initialize initial LSM namespace. This function should allocate and
+ * fill the private part of the init_lsm_ns.
+ *
+ * @lsmns_allow:
+ * Run during a request to create/copy new lsm namespace while creating
+ * new nsproxy structure. Returning failure here will block the whole
+ * operation requested from userspace (e.g. unshare() or clone()).
+ * This function can be effectively used to disallow new namespaces
+ * creation.
+ * @flags contains flags passed to the userspace syscall (e.g. CLONE_*)
+ * @user_ns points to the associated user namespace
+ * @old_ns pints to the lsm namespace under which the operation happens
+ * Return 0 to allow or -ERRNO to disallow.
+ *
+ * @lsmns_setns:
+ * Run during a setns syscall to add a process to an already existing
+ * lsm namespace. Returning failure here will block the operation
+ * requested from userspace (setns() with CLONE_NEWLSM).
+ * @nsproxy contains a nsproxy to which the lsm namespace will be assigned.
+ * @ns contains lsm namespace that is to be incorporated to the nsproxy.
+ *
+ * @lsmns_create:
+ * Allocates and fills the private part of a new lsm namespace.
+ * @ns points to a newly created lsm namespace.
+ * Return a pointer to a namespace or ERR_PTR(-ERRNO) on error.
+ *
+ * @lsmns_free:
+ * Deallocates the private part of a new lsm namespace.
+ * @ns points to a lsm namespace about to be destroyed.
+ *
* @inode_notifysecctx:
* Notify the security module of what the security context of an inode
* should be. Initializes the incore security context managed by the
@@ -1729,6 +1761,15 @@ struct security_operations {
struct audit_context *actx);
void (*audit_rule_free) (void *lsmrule);
#endif /* CONFIG_AUDIT */
+
+#ifdef CONFIG_SECURITY_NS
+ void (*lsmns_init)(void);
+ int (*lsmns_allow)(unsigned long flags, struct user_namespace *user_ns,
+ struct lsm_namespace *old_ns);
+ int (*lsmns_setns)(struct nsproxy *nsproxy, struct lsm_namespace *ns);
+ int (*lsmns_create)(struct lsm_namespace *ns);
+ void (*lsmns_free)(struct lsm_namespace *ns);
+#endif /* CONFIG_SECURITY_NS */
};
/* prototypes */
@@ -3116,6 +3157,45 @@ static inline void security_audit_rule_free(void *lsmrule)
#endif /* CONFIG_SECURITY */
#endif /* CONFIG_AUDIT */
+#ifdef CONFIG_SECURITY_NS
+
+void security_lsmns_init(void);
+int security_lsmns_allow(unsigned long flags, struct user_namespace *user_ns,
+ struct lsm_namespace *old_ns);
+int security_lsmns_setns(struct nsproxy *nsproxy, struct lsm_namespace *ns);
+int security_lsmns_create(struct lsm_namespace *ns);
+void security_lsmns_free(struct lsm_namespace *ns);
+
+#else /* CONFIG_SECURITY_NS */
+
+static inline void security_lsmns_init(void)
+{
+}
+
+static inline int security_lsmns_allow(unsigned long flags,
+ struct user_namespace *user_ns,
+ struct lsm_namespace *old_ns)
+{
+ return 0;
+}
+
+static inline int security_lsmns_setns(struct nsproxy *nsproxy,
+ struct lsm_namespace *ns)
+{
+ return 0;
+}
+
+static inline int security_lsmns_create(struct lsm_namespace *ns)
+{
+ return 0;
+}
+
+static inline void security_lsmns_free(struct lsm_namespace *ns)
+{
+}
+
+#endif /* CONFIG_SECURITY_NS */
+
#ifdef CONFIG_SECURITYFS
extern struct dentry *securityfs_create_file(const char *name, umode_t mode,
diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
index 34f9d73..5ac7fb9 100644
--- a/include/uapi/linux/sched.h
+++ b/include/uapi/linux/sched.h
@@ -21,8 +21,7 @@
#define CLONE_DETACHED 0x00400000 /* Unused, ignored */
#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
-/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
- and is now available for re-use. */
+#define CLONE_NEWLSM 0x02000000 /* New LSM namespace */
#define CLONE_NEWUTS 0x04000000 /* New utsname group? */
#define CLONE_NEWIPC 0x08000000 /* New ipcs */
#define CLONE_NEWUSER 0x10000000 /* New user namespace */
diff --git a/kernel/fork.c b/kernel/fork.c
index ed4bc33..a5ac809 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1796,7 +1796,7 @@ static int check_unshare_flags(unsigned long unshare_flags)
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|
- CLONE_NEWUSER|CLONE_NEWPID))
+ CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWLSM))
return -EINVAL;
/*
* Not implemented, but pretend it works if there is nothing to
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 8e78110..841228d 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -25,6 +25,7 @@
#include <linux/proc_ns.h>
#include <linux/file.h>
#include <linux/syscalls.h>
+#include <linux/lsm_namespace.h>
static struct kmem_cache *nsproxy_cachep;
@@ -39,6 +40,9 @@ struct nsproxy init_nsproxy = {
#ifdef CONFIG_NET
.net_ns = &init_net,
#endif
+#ifdef CONFIG_SECURITY
+ .lsm_ns = &init_lsm_ns,
+#endif
};
static inline struct nsproxy *create_nsproxy(void)
@@ -67,6 +71,12 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
if (!new_nsp)
return ERR_PTR(-ENOMEM);
+ new_nsp->lsm_ns = copy_lsm_ns(flags, user_ns, tsk->nsproxy->lsm_ns);
+ if (IS_ERR(new_nsp->lsm_ns)) {
+ err = PTR_ERR(new_nsp->lsm_ns);
+ goto out_lsm;
+ }
+
new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
if (IS_ERR(new_nsp->mnt_ns)) {
err = PTR_ERR(new_nsp->mnt_ns);
@@ -113,6 +123,9 @@ out_uts:
if (new_nsp->mnt_ns)
put_mnt_ns(new_nsp->mnt_ns);
out_ns:
+ if (new_nsp->lsm_ns)
+ put_lsm_ns(new_nsp->lsm_ns);
+out_lsm:
kmem_cache_free(nsproxy_cachep, new_nsp);
return ERR_PTR(err);
}
@@ -128,7 +141,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
struct nsproxy *new_ns;
if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
- CLONE_NEWPID | CLONE_NEWNET)))) {
+ CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWLSM)))) {
get_nsproxy(old_ns);
return 0;
}
@@ -157,6 +170,8 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
void free_nsproxy(struct nsproxy *ns)
{
+ if (ns->lsm_ns)
+ put_lsm_ns(ns->lsm_ns);
if (ns->mnt_ns)
put_mnt_ns(ns->mnt_ns);
if (ns->uts_ns)
@@ -165,7 +180,8 @@ void free_nsproxy(struct nsproxy *ns)
put_ipc_ns(ns->ipc_ns);
if (ns->pid_ns_for_children)
put_pid_ns(ns->pid_ns_for_children);
- put_net(ns->net_ns);
+ if (ns->net_ns)
+ put_net(ns->net_ns);
kmem_cache_free(nsproxy_cachep, ns);
}
@@ -180,7 +196,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
int err = 0;
if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
- CLONE_NEWNET | CLONE_NEWPID)))
+ CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWLSM)))
return 0;
user_ns = new_cred ? new_cred->user_ns : current_user_ns();
diff --git a/security/Kconfig b/security/Kconfig
index beb86b5..7b2118b 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -70,6 +70,14 @@ config SECURITY_PATH
implement pathname based access controls.
If you are unsure how to answer this question, answer N.
+config SECURITY_NS
+ bool "Security namespace for LSM modules"
+ depends on SECURITY
+ help
+ This enables security namespaces for Linux Security Modules.
+ The implementation is specific to currently selected LSM module.
+ If you are unsure how to answer this question, answer N.
+
config INTEL_TXT
bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
depends on HAVE_INTEL_TXT
diff --git a/security/Makefile b/security/Makefile
index 05f1c93..f333265 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/
obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/
obj-$(CONFIG_SECURITY_YAMA) += yama/
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
+obj-$(CONFIG_SECURITY_NS) += lsm_namespace.o
# Object integrity file lists
subdir-$(CONFIG_INTEGRITY) += integrity
diff --git a/security/capability.c b/security/capability.c
index a74fde6..e043cc9 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -919,6 +919,32 @@ static void cap_audit_rule_free(void *lsmrule)
}
#endif /* CONFIG_AUDIT */
+#ifdef CONFIG_SECURITY_NS
+void cap_lsmns_init(void)
+{
+}
+
+int cap_lsmns_allow(unsigned long flags, struct user_namespace *user_ns,
+ struct lsm_namespace *old_ns)
+{
+ return 0;
+}
+
+int cap_lsmns_setns(struct nsproxy *nsproxy, struct lsm_namespace *ns)
+{
+ return 0;
+}
+
+int cap_lsmns_create(struct lsm_namespace *ns)
+{
+ return 0;
+}
+
+void cap_lsmns_free(struct lsm_namespace *ns)
+{
+}
+#endif /* CONFIG_SECURITY_NS */
+
#define set_to_cap_if_null(ops, function) \
do { \
if (!ops->function) { \
@@ -1134,4 +1160,11 @@ void __init security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null(ops, audit_rule_match);
set_to_cap_if_null(ops, audit_rule_free);
#endif
+#ifdef CONFIG_SECURITY_NS
+ set_to_cap_if_null(ops, lsmns_init);
+ set_to_cap_if_null(ops, lsmns_allow);
+ set_to_cap_if_null(ops, lsmns_setns);
+ set_to_cap_if_null(ops, lsmns_create);
+ set_to_cap_if_null(ops, lsmns_free);
+#endif
}
diff --git a/security/lsm_namespace.c b/security/lsm_namespace.c
new file mode 100644
index 0000000..8f7ec3b
--- /dev/null
+++ b/security/lsm_namespace.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics.
+ *
+ * LSM namespaces
+ *
+ * Author(s):
+ * Lukasz Pawelczyk <l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * This program is free software, you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/lsm_namespace.h>
+#include <linux/user_namespace.h>
+#include <linux/nsproxy.h>
+#include <linux/proc_ns.h>
+#include <linux/slab.h>
+#include <linux/security.h>
+
+
+/* private functions */
+
+static struct lsm_namespace *create_lsm_ns(struct user_namespace *user_ns,
+ struct lsm_namespace *old_ns)
+{
+ struct lsm_namespace *ns;
+ int err;
+
+ ns = kmalloc(sizeof(struct lsm_namespace), GFP_KERNEL);
+ if (ns == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ err = proc_alloc_inum(&ns->proc_inum);
+ if (err)
+ goto freeout;
+
+ kref_init(&ns->kref);
+ ns->user_ns = get_user_ns(user_ns);
+ ns->private = NULL;
+
+ err = security_lsmns_create(ns);
+ if (err) {
+ put_user_ns(user_ns);
+ goto freeout;
+ }
+
+ return ns;
+
+freeout:
+ kfree(ns);
+ return ERR_PTR(err);
+}
+
+/* public functions */
+
+struct lsm_namespace *copy_lsm_ns(unsigned long flags,
+ struct user_namespace *user_ns,
+ struct lsm_namespace *ns)
+{
+ int err;
+
+ err = security_lsmns_allow(flags, user_ns, ns);
+ if (err)
+ return ERR_PTR(err);
+
+ if (!(flags & CLONE_NEWLSM))
+ return get_lsm_ns(ns);
+ return create_lsm_ns(user_ns, ns);
+}
+
+void free_lsm_ns(struct kref *kref)
+{
+ struct lsm_namespace *ns;
+
+ ns = container_of(kref, struct lsm_namespace, kref);
+
+ security_lsmns_free(ns);
+
+ put_user_ns(ns->user_ns);
+ proc_free_inum(ns->proc_inum);
+ kfree(ns);
+}
+
+/* proc_ns_operations hooks */
+
+static void *lsmns_get(struct task_struct *task)
+{
+ struct lsm_namespace *ns = NULL;
+ struct nsproxy *nsproxy;
+
+ task_lock(task);
+ nsproxy = task->nsproxy;
+ if (nsproxy)
+ ns = get_lsm_ns(nsproxy->lsm_ns);
+ task_unlock(task);
+
+ return ns;
+}
+
+static void lsmns_put(void *ns)
+{
+ put_lsm_ns(ns);
+}
+
+static int lsmns_install(struct nsproxy *nsproxy, void *ns)
+{
+ struct lsm_namespace *new = ns;
+ int err;
+
+ if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) ||
+ !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
+ return -EPERM;
+
+ err = security_lsmns_setns(nsproxy, new);
+ if (err)
+ return err;
+
+ put_lsm_ns(nsproxy->lsm_ns);
+ nsproxy->lsm_ns = get_lsm_ns(new);
+
+ return 0;
+}
+
+static unsigned int lsmns_inum(void *ns)
+{
+ struct lsm_namespace *lsm_ns = ns;
+
+ return lsm_ns->proc_inum;
+}
+
+const struct proc_ns_operations lsmns_operations = {
+ .name = "lsm",
+ .type = CLONE_NEWLSM,
+ .get = lsmns_get,
+ .put = lsmns_put,
+ .install = lsmns_install,
+ .inum = lsmns_inum,
+};
+
+static __init int lsm_namespaces_init(void)
+{
+ security_lsmns_init();
+
+ return 0;
+}
+subsys_initcall(lsm_namespaces_init);
diff --git a/security/security.c b/security/security.c
index e41b1a8..200365f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -25,10 +25,22 @@
#include <linux/mount.h>
#include <linux/personality.h>
#include <linux/backing-dev.h>
+#include <linux/lsm_namespace.h>
+#include <linux/proc_ns.h>
#include <net/flow.h>
#define MAX_LSM_EVM_XATTR 2
+struct lsm_namespace init_lsm_ns = {
+ .kref = {
+ .refcount = ATOMIC_INIT(1),
+ },
+ .user_ns = &init_user_ns,
+ .proc_inum = PROC_LSM_INIT_INO,
+ /* module specific and to be initialized in lsmns_init() */
+ .private = NULL,
+};
+
/* Boot-time LSM user choice */
static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY;
@@ -1472,3 +1484,33 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
}
#endif /* CONFIG_AUDIT */
+
+#ifdef CONFIG_SECURITY_NS
+
+void security_lsmns_init(void)
+{
+ security_ops->lsmns_init();
+}
+
+int security_lsmns_allow(unsigned long flags, struct user_namespace *user_ns,
+ struct lsm_namespace *old_ns)
+{
+ return security_ops->lsmns_allow(flags, user_ns, old_ns);
+}
+
+int security_lsmns_setns(struct nsproxy *nsproxy, struct lsm_namespace *ns)
+{
+ return security_ops->lsmns_setns(nsproxy, ns);
+}
+
+int security_lsmns_create(struct lsm_namespace *ns)
+{
+ return security_ops->lsmns_create(ns);
+}
+
+void security_lsmns_free(struct lsm_namespace *ns)
+{
+ security_ops->lsmns_free(ns);
+}
+
+#endif /* CONFIG_SECURITY_NS */
--
1.9.3
^ permalink raw reply related
* Re: [RFC] lsm: namespace hooks
From: Richard Weinberger @ 2014-11-27 14:18 UTC (permalink / raw)
To: Lukasz Pawelczyk
Cc: Vladimir Davydov, Miklos Szeredi, Lukasz Pawelczyk, LKML,
David Howells, Davidlohr Bueso, Mark Rustad, Matthew Dempsky,
Daeseok Youn, Ingo Molnar, Jeff Kirsher, David Rientjes,
Alex Thorlton, Juri Lelli, Kees Cook, Nikolay Aleksandrov,
Dario Faggioli, Al Viro, James Morris, open list:ABI/API,
Linux Containers, Oleg Nesterov, Paul Moore
In-Reply-To: <1417096866-25563-2-git-send-email-l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
On Thu, Nov 27, 2014 at 3:01 PM, Lukasz Pawelczyk
<l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> extern struct dentry *securityfs_create_file(const char *name, umode_t mode,
> diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
> index 34f9d73..5ac7fb9 100644
> --- a/include/uapi/linux/sched.h
> +++ b/include/uapi/linux/sched.h
> @@ -21,8 +21,7 @@
> #define CLONE_DETACHED 0x00400000 /* Unused, ignored */
> #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
> #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
> -/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
> - and is now available for re-use. */
> +#define CLONE_NEWLSM 0x02000000 /* New LSM namespace */
FYI, CLONE_NEWCGROUP also claims last flag [1].
As it looks we will get more and more namespaces, more than clone() can handle.
[1] https://lkml.org/lkml/2014/7/17/588
--
Thanks,
//richard
^ permalink raw reply
* Re: [RFC] lsm: namespace hooks
From: Lukasz Pawelczyk @ 2014-11-27 14:35 UTC (permalink / raw)
To: Richard Weinberger
Cc: Vladimir Davydov, Miklos Szeredi, Lukasz Pawelczyk, LKML,
David Howells, Davidlohr Bueso, Mark Rustad, Matthew Dempsky,
Daeseok Youn, Ingo Molnar, Jeff Kirsher, David Rientjes,
Alex Thorlton, Juri Lelli, Kees Cook, Nikolay Aleksandrov,
Dario Faggioli, Al Viro, James Morris, open list:ABI/API,
Linux Containers, Oleg Nesterov, Paul Moore
In-Reply-To: <CAFLxGvzw4N4QFv5Vg1dDf9pdRe+Szbevmqn5QNwjLHN4xrokCg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On czw, 2014-11-27 at 15:18 +0100, Richard Weinberger wrote:
> On Thu, Nov 27, 2014 at 3:01 PM, Lukasz Pawelczyk
> <l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> > -/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
> > - and is now available for re-use. */
> > +#define CLONE_NEWLSM 0x02000000 /* New LSM namespace */
>
> FYI, CLONE_NEWCGROUP also claims last flag [1].
Yes, I'm perfectly aware of that. I've seen those patches.
This is RFC for now and CGROUP NS is not merged yet. I'll rebase when
time comes.
> As it looks we will get more and more namespaces, more than clone() can handle.
>
> [1] https://lkml.org/lkml/2014/7/17/588
>
--
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
* Re: [RFC] lsm: namespace hooks
From: Richard Weinberger @ 2014-11-27 14:38 UTC (permalink / raw)
To: Lukasz Pawelczyk, Richard Weinberger
Cc: Vladimir Davydov, Miklos Szeredi, Lukasz Pawelczyk, LKML,
David Howells, Davidlohr Bueso, Mark Rustad, Matthew Dempsky,
Daeseok Youn, Ingo Molnar, Jeff Kirsher, David Rientjes,
Alex Thorlton, Juri Lelli, Kees Cook, Nikolay Aleksandrov,
Dario Faggioli, Al Viro, James Morris, ABI/API, Linux Containers,
Oleg Nesterov, Paul Moore
In-Reply-To: <1417098928.1805.15.camel-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Am 27.11.2014 um 15:35 schrieb Lukasz Pawelczyk:
> On czw, 2014-11-27 at 15:18 +0100, Richard Weinberger wrote:
>> On Thu, Nov 27, 2014 at 3:01 PM, Lukasz Pawelczyk
>> <l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
>>> -/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
>>> - and is now available for re-use. */
>>> +#define CLONE_NEWLSM 0x02000000 /* New LSM namespace */
>>
>> FYI, CLONE_NEWCGROUP also claims last flag [1].
>
> Yes, I'm perfectly aware of that. I've seen those patches.
> This is RFC for now and CGROUP NS is not merged yet. I'll rebase when
> time comes.
Just wanted to indicate that we run out of constants. :)
Thanks,
//richard
^ permalink raw reply
* Re: [RFC] lsm: namespace hooks
From: Lukasz Pawelczyk @ 2014-11-27 14:44 UTC (permalink / raw)
To: Richard Weinberger
Cc: Vladimir Davydov, Miklos Szeredi, Lukasz Pawelczyk, LKML,
David Howells, Mark Rustad, Matthew Dempsky, Daeseok Youn,
Ingo Molnar, Jeff Kirsher, David Rientjes, Alex Thorlton,
Juri Lelli, Kees Cook, Richard Weinberger, Nikolay Aleksandrov,
Dario Faggioli, Al Viro, James Morris, open list:ABI/API,
Linux Containers, Oleg Nesterov, Paul
In-Reply-To: <54773757.8090905-/L3Ra7n9ekc@public.gmane.org>
On czw, 2014-11-27 at 15:38 +0100, Richard Weinberger wrote:
> Am 27.11.2014 um 15:35 schrieb Lukasz Pawelczyk:
> > On czw, 2014-11-27 at 15:18 +0100, Richard Weinberger wrote:
> >> On Thu, Nov 27, 2014 at 3:01 PM, Lukasz Pawelczyk
> >> <l.pawelczyk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> >>> -/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
> >>> - and is now available for re-use. */
> >>> +#define CLONE_NEWLSM 0x02000000 /* New LSM namespace */
> >>
> >> FYI, CLONE_NEWCGROUP also claims last flag [1].
> >
> > Yes, I'm perfectly aware of that. I've seen those patches.
> > This is RFC for now and CGROUP NS is not merged yet. I'll rebase when
> > time comes.
>
> Just wanted to indicate that we run out of constants. :)
True, the last one is 0x80000000. I did not notice that. Thanks for
pointing out.
Any suggestion on what can be done here? New syscal with flags2?
--
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
* Re: [PATCH v17 1/7] mm: support madvise(MADV_FREE)
From: Michal Hocko @ 2014-11-27 14:47 UTC (permalink / raw)
To: Minchan Kim
Cc: Andrew Morton, linux-kernel, linux-mm, Michael Kerrisk, linux-api,
Hugh Dickins, Johannes Weiner, Rik van Riel, KOSAKI Motohiro,
Mel Gorman, Jason Evans, zhangyanfei, Kirill A. Shutemov,
Kirill A. Shutemov
In-Reply-To: <1413799924-17946-2-git-send-email-minchan@kernel.org>
[Late but I didn't get to this soone - I hope this is still up-to-date
version]
On Mon 20-10-14 19:11:58, Minchan Kim wrote:
> Linux doesn't have an ability to free pages lazy while other OS
> already have been supported that named by madvise(MADV_FREE).
>
> The gain is clear that kernel can discard freed pages rather than
> swapping out or OOM if memory pressure happens.
>
> Without memory pressure, freed pages would be reused by userspace
> without another additional overhead(ex, page fault + allocation
> + zeroing).
>
> How to work is following as.
>
> When madvise syscall is called, VM clears dirty bit of ptes of
> the range. If memory pressure happens, VM checks dirty bit of
> page table and if it found still "clean", it means it's a
> "lazyfree pages" so VM could discard the page instead of swapping out.
> Once there was store operation for the page before VM peek a page
> to reclaim, dirty bit is set so VM can swap out the page instead of
> discarding.
Is there any patch for madvise man page? I guess the semantic will be
same/similar to FreeBSD:
http://www.freebsd.org/cgi/man.cgi?query=madvise&sektion=2
I guess the changelog should be more specific that this is only for the
private MAP_ANON mappings (same applies to the patch for man).
> Firstly, heavy users would be general allocators(ex, jemalloc,
> tcmalloc and hope glibc supports it) and jemalloc/tcmalloc already
> have supported the feature for other OS(ex, FreeBSD)
>
[...]
>
> Cc: Michael Kerrisk <mtk.manpages@gmail.com>
> Cc: Linux API <linux-api@vger.kernel.org>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Johannes Weiner <hannes@cmpxchg.org>
> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> Cc: Mel Gorman <mgorman@suse.de>
> Cc: Jason Evans <je@fb.com>
> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Acked-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
> Acked-by: Rik van Riel <riel@redhat.com>
> Signed-off-by: Minchan Kim <minchan@kernel.org>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
[...]
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [tpmdd-devel] [PATCH v7 04/10] tpm: rename chip->dev to chip->pdev
From: Jarkko Sakkinen @ 2014-11-27 14:51 UTC (permalink / raw)
To: Stefan Berger
Cc: Peter Huewe, Ashley Lai, Marcel Selhorst,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
josh.triplett-ral2JQCrhuEAvxtiuMwx3w,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
jason.gunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/,
trousers-tech-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <5474F855.7080207-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
On Tue, Nov 25, 2014 at 04:44:53PM -0500, Stefan Berger wrote:
> On 11/11/2014 08:45 AM, Jarkko Sakkinen wrote:
> >Rename chip->dev to chip->pdev to make it explicit that this not the
> >character device but actually represents the platform device.
> >
> >Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> >
>
>
> >diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> >index 69f4003..b3a7c76 100644
> >--- a/drivers/char/tpm/tpm.h
> >+++ b/drivers/char/tpm/tpm.h
> >@@ -98,7 +98,7 @@ struct tpm_vendor_specific {
> > #define TPM_PPI_VERSION_LEN 3
> >
> > struct tpm_chip {
> >- struct device *dev; /* Device stuff */
> >+ struct device *pdev; /* Device stuff */
> > const struct tpm_class_ops *ops;
> >
> > int dev_num; /* /dev/tpm# */
>
> So this is the core requiring the renamings. I assume you got them all and
> none were hidden in #if's or so.
Yup, I basically did :argdo %s/chip->dev/chip->pdev/g for *.[ch].
> Reviewed-by: Stefan Berger <stefanb-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
/Jarkko
^ 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