All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: linux-kernel@vger.kernel.org, somlo@cmu.edu, qemu-devel@nongnu.org
Subject: Re: [PATCH v6 5/5] fw_cfg: write vmcoreinfo details
Date: Thu, 16 Nov 2017 18:05:10 +0200	[thread overview]
Message-ID: <20171116180302-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <183118826.40770917.1510839263526.JavaMail.zimbra@redhat.com>

On Thu, Nov 16, 2017 at 08:34:23AM -0500, Marc-André Lureau wrote:
> Hi
> 
> ----- Original Message -----
> > On Mon, Nov 13, 2017 at 08:29:58PM +0100, Marc-André Lureau wrote:
> > > If the "etc/vmcoreinfo" fw_cfg file is present and we are not running
> > > the kdump kernel, write the addr/size of the vmcoreinfo ELF note.
> > > 
> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > Reviewed-by: Gabriel Somlo <somlo@cmu.edu>
> > > ---
> > >  drivers/firmware/qemu_fw_cfg.c | 87
> > >  +++++++++++++++++++++++++++++++++++++++++-
> > >  1 file changed, 86 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/firmware/qemu_fw_cfg.c
> > > b/drivers/firmware/qemu_fw_cfg.c
> > > index 2ac4cd869fe6..7a70e7a549f6 100644
> > > --- a/drivers/firmware/qemu_fw_cfg.c
> > > +++ b/drivers/firmware/qemu_fw_cfg.c
> > > @@ -35,6 +35,8 @@
> > >  #include <linux/ioport.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/dma-mapping.h>
> > > +#include <linux/crash_core.h>
> > > +#include <linux/crash_dump.h>
> > >  
> > >  MODULE_AUTHOR("Gabriel L. Somlo <somlo@cmu.edu>");
> > >  MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> > > @@ -59,6 +61,8 @@ MODULE_LICENSE("GPL");
> > >  /* fw_cfg "file name" is up to 56 characters (including terminating nul)
> > >  */
> > >  #define FW_CFG_MAX_FILE_PATH 56
> > >  
> > > +#define VMCOREINFO_FORMAT_ELF 0x1
> > > +
> > >  /* platform device for dma mapping */
> > >  static struct device *dev;
> > >  
> > > @@ -127,7 +131,8 @@ static ssize_t fw_cfg_dma_transfer(void *address, u32
> > > length, u32 control)
> > >  	dma_addr_t dma;
> > >  	ssize_t ret = length;
> > >  	enum dma_data_direction dir =
> > > -		(control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0);
> > > +		(control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0) |
> > > +		(control & FW_CFG_DMA_CTL_WRITE ? DMA_TO_DEVICE : 0);
> > >  
> > >  	if (address && length) {
> > >  		dma_addr = dma_map_single(dev, address, length, dir);
> > > @@ -225,6 +230,48 @@ static ssize_t fw_cfg_read_blob(u16 key,
> > >  	return ret;
> > >  }
> > >  
> > > +#ifdef CONFIG_CRASH_CORE
> > > +/* write chunk of given fw_cfg blob (caller responsible for sanity-check)
> > > */
> > > +static ssize_t fw_cfg_write_blob(u16 key,
> > > +				 void *buf, loff_t pos, size_t count)
> > > +{
> > > +	u32 glk = -1U;
> > > +	acpi_status status;
> > > +	ssize_t ret = count;
> > > +
> > > +	/* If we have ACPI, ensure mutual exclusion against any potential
> > > +	 * device access by the firmware, e.g. via AML methods:
> > > +	 */
> > > +	status = acpi_acquire_global_lock(ACPI_WAIT_FOREVER, &glk);
> > > +	if (ACPI_FAILURE(status) && status != AE_NOT_CONFIGURED) {
> > > +		/* Should never get here */
> > > +		WARN(1, "%s: Failed to lock ACPI!\n", __func__);
> > > +		memset(buf, 0, count);
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	mutex_lock(&fw_cfg_dev_lock);
> > > +	if (pos == 0) {
> > > +		ret = fw_cfg_dma_transfer(buf, count, key << 16
> > > +					  | FW_CFG_DMA_CTL_SELECT
> > > +					  | FW_CFG_DMA_CTL_WRITE);
> > > +	} else {
> > > +		iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
> > > +		ret = fw_cfg_dma_transfer(NULL, pos, FW_CFG_DMA_CTL_SKIP);
> > > +		if (ret < 0)
> > > +			goto end;
> > > +		ret = fw_cfg_dma_transfer(buf, count, FW_CFG_DMA_CTL_WRITE);
> > > +	}
> > > +
> > > +end:
> > > +	mutex_unlock(&fw_cfg_dev_lock);
> > > +
> > > +	acpi_release_global_lock(glk);
> > > +
> > > +	return ret;
> > > +}
> > > +#endif /* CONFIG_CRASH_CORE */
> > > +
> > >  /* clean up fw_cfg device i/o */
> > >  static void fw_cfg_io_cleanup(void)
> > >  {
> > > @@ -343,6 +390,37 @@ struct fw_cfg_sysfs_entry {
> > >  	struct list_head list;
> > >  };
> > >  
> > > +#ifdef CONFIG_CRASH_CORE
> > > +static ssize_t write_vmcoreinfo(const struct fw_cfg_file *f)
> > > +{
> > > +	struct vmci {
> > > +		__le16 host_format;
> > > +		__le16 guest_format;
> > > +		__le32 size;
> > > +		__le64 paddr;
> > > +	} __packed;
> > > +	struct vmci *data;
> > > +	ssize_t ret;
> > > +
> > > +	data = kmalloc(sizeof(struct vmci), GFP_KERNEL | GFP_DMA);
> > > +	if (!data)
> > > +		return -ENOMEM;
> > 
> > It's a small bit of data - you can just keep it in a global variable,
> > this way failures won't be an issue.
> 
> It would still need to be allocated

No - you can just make it a global variable.

> with GFP_DMA.

Are you sure?

 * GFP_DMA exists for historical reasons and should be avoided where possible.
 *   The flags indicates that the caller requires that the lowest zone be
 *   used (ZONE_DMA or 16M on x86-64). Ideally, this would be removed but
 *   it would require careful auditing as some users really require it and
 *   others use the flag to avoid lowmem reserves in ZONE_DMA and treat the
 *   lowest zone as a type of emergency reserve.


> Since it's a one time thing, this is just moving the problem isn't it?

Isn't the timeout just moving the problem too?
Avoiding memory corruption is a priority.

> > 
> > > +
> > > +	/* spare ourself reading host format support for now since we
> > > +	 * don't know what else to format - host may ignore ours
> > > +	 */
> > > +	*data = (struct vmci) {
> > > +		.guest_format = cpu_to_le16(VMCOREINFO_FORMAT_ELF),
> > > +		.size = cpu_to_le32(VMCOREINFO_NOTE_SIZE),
> > > +		.paddr = cpu_to_le64(paddr_vmcoreinfo_note())
> > > +	};
> > > +	ret = fw_cfg_write_blob(f->select, data, 0, sizeof(struct vmci));
> > > +
> > > +	kfree(data);
> > > +	return ret;
> > > +}
> > > +#endif /* CONFIG_CRASH_CORE */
> > > +
> > >  /* get fw_cfg_sysfs_entry from kobject member */
> > >  static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj)
> > >  {
> > > @@ -582,6 +660,13 @@ static int fw_cfg_register_file(const struct
> > > fw_cfg_file *f)
> > >  	int err;
> > >  	struct fw_cfg_sysfs_entry *entry;
> > >  
> > > +#ifdef CONFIG_CRASH_CORE
> > > +	if (strcmp(f->name, "etc/vmcoreinfo") == 0 && !is_kdump_kernel()) {
> > > +		if (write_vmcoreinfo(f) < 0)
> > > +			pr_warn("fw_cfg: failed to write vmcoreinfo");
> > > +	}
> > > +#endif
> > > +
> > >  	/* allocate new entry */
> > >  	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > >  	if (!entry)
> > > --
> > > 2.15.0.125.g8f49766d64
> > 

WARNING: multiple messages have this Message-ID (diff)
From: "Michael S. Tsirkin" <mst@redhat.com>
To: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: linux-kernel@vger.kernel.org, somlo@cmu.edu, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v6 5/5] fw_cfg: write vmcoreinfo details
Date: Thu, 16 Nov 2017 18:05:10 +0200	[thread overview]
Message-ID: <20171116180302-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <183118826.40770917.1510839263526.JavaMail.zimbra@redhat.com>

On Thu, Nov 16, 2017 at 08:34:23AM -0500, Marc-André Lureau wrote:
> Hi
> 
> ----- Original Message -----
> > On Mon, Nov 13, 2017 at 08:29:58PM +0100, Marc-André Lureau wrote:
> > > If the "etc/vmcoreinfo" fw_cfg file is present and we are not running
> > > the kdump kernel, write the addr/size of the vmcoreinfo ELF note.
> > > 
> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > Reviewed-by: Gabriel Somlo <somlo@cmu.edu>
> > > ---
> > >  drivers/firmware/qemu_fw_cfg.c | 87
> > >  +++++++++++++++++++++++++++++++++++++++++-
> > >  1 file changed, 86 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/firmware/qemu_fw_cfg.c
> > > b/drivers/firmware/qemu_fw_cfg.c
> > > index 2ac4cd869fe6..7a70e7a549f6 100644
> > > --- a/drivers/firmware/qemu_fw_cfg.c
> > > +++ b/drivers/firmware/qemu_fw_cfg.c
> > > @@ -35,6 +35,8 @@
> > >  #include <linux/ioport.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/dma-mapping.h>
> > > +#include <linux/crash_core.h>
> > > +#include <linux/crash_dump.h>
> > >  
> > >  MODULE_AUTHOR("Gabriel L. Somlo <somlo@cmu.edu>");
> > >  MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> > > @@ -59,6 +61,8 @@ MODULE_LICENSE("GPL");
> > >  /* fw_cfg "file name" is up to 56 characters (including terminating nul)
> > >  */
> > >  #define FW_CFG_MAX_FILE_PATH 56
> > >  
> > > +#define VMCOREINFO_FORMAT_ELF 0x1
> > > +
> > >  /* platform device for dma mapping */
> > >  static struct device *dev;
> > >  
> > > @@ -127,7 +131,8 @@ static ssize_t fw_cfg_dma_transfer(void *address, u32
> > > length, u32 control)
> > >  	dma_addr_t dma;
> > >  	ssize_t ret = length;
> > >  	enum dma_data_direction dir =
> > > -		(control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0);
> > > +		(control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0) |
> > > +		(control & FW_CFG_DMA_CTL_WRITE ? DMA_TO_DEVICE : 0);
> > >  
> > >  	if (address && length) {
> > >  		dma_addr = dma_map_single(dev, address, length, dir);
> > > @@ -225,6 +230,48 @@ static ssize_t fw_cfg_read_blob(u16 key,
> > >  	return ret;
> > >  }
> > >  
> > > +#ifdef CONFIG_CRASH_CORE
> > > +/* write chunk of given fw_cfg blob (caller responsible for sanity-check)
> > > */
> > > +static ssize_t fw_cfg_write_blob(u16 key,
> > > +				 void *buf, loff_t pos, size_t count)
> > > +{
> > > +	u32 glk = -1U;
> > > +	acpi_status status;
> > > +	ssize_t ret = count;
> > > +
> > > +	/* If we have ACPI, ensure mutual exclusion against any potential
> > > +	 * device access by the firmware, e.g. via AML methods:
> > > +	 */
> > > +	status = acpi_acquire_global_lock(ACPI_WAIT_FOREVER, &glk);
> > > +	if (ACPI_FAILURE(status) && status != AE_NOT_CONFIGURED) {
> > > +		/* Should never get here */
> > > +		WARN(1, "%s: Failed to lock ACPI!\n", __func__);
> > > +		memset(buf, 0, count);
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	mutex_lock(&fw_cfg_dev_lock);
> > > +	if (pos == 0) {
> > > +		ret = fw_cfg_dma_transfer(buf, count, key << 16
> > > +					  | FW_CFG_DMA_CTL_SELECT
> > > +					  | FW_CFG_DMA_CTL_WRITE);
> > > +	} else {
> > > +		iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
> > > +		ret = fw_cfg_dma_transfer(NULL, pos, FW_CFG_DMA_CTL_SKIP);
> > > +		if (ret < 0)
> > > +			goto end;
> > > +		ret = fw_cfg_dma_transfer(buf, count, FW_CFG_DMA_CTL_WRITE);
> > > +	}
> > > +
> > > +end:
> > > +	mutex_unlock(&fw_cfg_dev_lock);
> > > +
> > > +	acpi_release_global_lock(glk);
> > > +
> > > +	return ret;
> > > +}
> > > +#endif /* CONFIG_CRASH_CORE */
> > > +
> > >  /* clean up fw_cfg device i/o */
> > >  static void fw_cfg_io_cleanup(void)
> > >  {
> > > @@ -343,6 +390,37 @@ struct fw_cfg_sysfs_entry {
> > >  	struct list_head list;
> > >  };
> > >  
> > > +#ifdef CONFIG_CRASH_CORE
> > > +static ssize_t write_vmcoreinfo(const struct fw_cfg_file *f)
> > > +{
> > > +	struct vmci {
> > > +		__le16 host_format;
> > > +		__le16 guest_format;
> > > +		__le32 size;
> > > +		__le64 paddr;
> > > +	} __packed;
> > > +	struct vmci *data;
> > > +	ssize_t ret;
> > > +
> > > +	data = kmalloc(sizeof(struct vmci), GFP_KERNEL | GFP_DMA);
> > > +	if (!data)
> > > +		return -ENOMEM;
> > 
> > It's a small bit of data - you can just keep it in a global variable,
> > this way failures won't be an issue.
> 
> It would still need to be allocated

No - you can just make it a global variable.

> with GFP_DMA.

Are you sure?

 * GFP_DMA exists for historical reasons and should be avoided where possible.
 *   The flags indicates that the caller requires that the lowest zone be
 *   used (ZONE_DMA or 16M on x86-64). Ideally, this would be removed but
 *   it would require careful auditing as some users really require it and
 *   others use the flag to avoid lowmem reserves in ZONE_DMA and treat the
 *   lowest zone as a type of emergency reserve.


> Since it's a one time thing, this is just moving the problem isn't it?

Isn't the timeout just moving the problem too?
Avoiding memory corruption is a priority.

> > 
> > > +
> > > +	/* spare ourself reading host format support for now since we
> > > +	 * don't know what else to format - host may ignore ours
> > > +	 */
> > > +	*data = (struct vmci) {
> > > +		.guest_format = cpu_to_le16(VMCOREINFO_FORMAT_ELF),
> > > +		.size = cpu_to_le32(VMCOREINFO_NOTE_SIZE),
> > > +		.paddr = cpu_to_le64(paddr_vmcoreinfo_note())
> > > +	};
> > > +	ret = fw_cfg_write_blob(f->select, data, 0, sizeof(struct vmci));
> > > +
> > > +	kfree(data);
> > > +	return ret;
> > > +}
> > > +#endif /* CONFIG_CRASH_CORE */
> > > +
> > >  /* get fw_cfg_sysfs_entry from kobject member */
> > >  static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj)
> > >  {
> > > @@ -582,6 +660,13 @@ static int fw_cfg_register_file(const struct
> > > fw_cfg_file *f)
> > >  	int err;
> > >  	struct fw_cfg_sysfs_entry *entry;
> > >  
> > > +#ifdef CONFIG_CRASH_CORE
> > > +	if (strcmp(f->name, "etc/vmcoreinfo") == 0 && !is_kdump_kernel()) {
> > > +		if (write_vmcoreinfo(f) < 0)
> > > +			pr_warn("fw_cfg: failed to write vmcoreinfo");
> > > +	}
> > > +#endif
> > > +
> > >  	/* allocate new entry */
> > >  	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > >  	if (!entry)
> > > --
> > > 2.15.0.125.g8f49766d64
> > 

  reply	other threads:[~2017-11-16 16:05 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-13 19:29 [PATCH v6 0/5] fw_cfg: add DMA operations & etc/vmcoreinfo support Marc-André Lureau
2017-11-13 19:29 ` [Qemu-devel] " Marc-André Lureau
2017-11-13 19:29 ` [PATCH v6 1/5] fw_cfg: fix the command line module name Marc-André Lureau
2017-11-13 19:29   ` [Qemu-devel] " Marc-André Lureau
2017-11-13 19:29 ` [PATCH v6 2/5] fw_cfg: add DMA register Marc-André Lureau
2017-11-13 19:29   ` [Qemu-devel] " Marc-André Lureau
2017-11-13 19:29 ` [PATCH v6 3/5] fw_cfg: do DMA read operation Marc-André Lureau
2017-11-13 19:29   ` [Qemu-devel] " Marc-André Lureau
2017-11-15 17:27   ` Michael S. Tsirkin
2017-11-15 17:27     ` [Qemu-devel] " Michael S. Tsirkin
2017-11-16 13:17     ` Marc-André Lureau
2017-11-16 13:17       ` [Qemu-devel] " Marc-André Lureau
2017-11-16 16:09       ` Michael S. Tsirkin
2017-11-16 16:09         ` [Qemu-devel] " Michael S. Tsirkin
2017-11-13 19:29 ` [PATCH v6 4/5] crash: export paddr_vmcoreinfo_note() Marc-André Lureau
2017-11-13 19:29   ` [Qemu-devel] " Marc-André Lureau
2017-11-14  6:39   ` Dave Young
2017-11-14  6:39     ` [Qemu-devel] " Dave Young
2017-11-14  6:39     ` Dave Young
2017-11-14  6:49   ` Baoquan He
2017-11-14  6:49     ` [Qemu-devel] " Baoquan He
2017-11-13 19:29 ` [PATCH v6 5/5] fw_cfg: write vmcoreinfo details Marc-André Lureau
2017-11-13 19:29   ` [Qemu-devel] " Marc-André Lureau
2017-11-16  1:57   ` Michael S. Tsirkin
2017-11-16  1:57     ` [Qemu-devel] " Michael S. Tsirkin
2017-11-16 13:34     ` Marc-André Lureau
2017-11-16 13:34       ` [Qemu-devel] " Marc-André Lureau
2017-11-16 16:05       ` Michael S. Tsirkin [this message]
2017-11-16 16:05         ` Michael S. Tsirkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171116180302-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcandre.lureau@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=somlo@cmu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.