All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yuji Shimada <shimada-yxb@necst.nec.co.jp>
To: Keir Fraser <keir.fraser@eu.citrix.com>,
	Kouya Shimura <kouya@jp.fujitsu.com>,
	xen-devel@lists.xensource.com
Subject: [PATCH 1/3] save/restore PCI configuration space in pciback.
Date: Wed, 22 Apr 2009 11:18:54 +0900	[thread overview]
Message-ID: <20090422111410.32A7.27C06F64@necst.nec.co.jp> (raw)
In-Reply-To: <20090422105816.32A4.27C06F64@necst.nec.co.jp>

This patch enables saving/restoring PCI configuration space in
pciback.

The timing of saving/restoring configuration space is like below.

  When pciback is bound to devices.
   - Pciback saves configuration space.

  When pciback is unbound to devices.
   - Pciback restores configuration space.

  When guest OS boots or a device is hotadded.
   - Pciback restores configuration space.
   - Pciback changes state of backend device to Initialised/Reconfigured.
   - Xend waits for the transition to Initialised/Reconfigured.

  When guest OS shutdowns or a device is hotremoved.
   - Pciback restores configuration space.
   - Xend resets devices.
     * If D-state of the device is not D0, the state is changed to D0
       before resetting the device.
   - Xend deassigns devices.

  * Essentially, devices should be reset before configuration space is
    restored. But it needs big modifications. Applying these patches,
    configuration space is restored when guest OS boots, a device is
    hotadded or pciback is unbound. So it has no matter.

The following registers are saved/restored by pciback.

  Configuration Space
   - Base Address Register set
   - Cache-line size Register
   - Latency timer Register
   - Enable SERR Bit / Enable PERR Bit in Control Register
   - Device Control Register (PCI Express Capability)
   - Link Control Register (PCI Express Capability)
   - Device Control 2 Register (PCI Express Capability)
   - Link Control 2 Register (PCI Express Capability)

  AER
   - Uncorrectable Error Mask Register
   - Uncorrectable Error Severity Register
   - Correctable Error Mask Register
   - Advanced Error Capabilities and Control Register

Thanks,
--
Yuji Shimada


Signed-off-by: Yuji Shimada <shimada-yxb@necst.nec.co.jp>

diff -r 366c31f3ab4b drivers/xen/pciback/Makefile
--- a/drivers/xen/pciback/Makefile	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/Makefile	Tue Apr 21 16:48:25 2009 +0900
@@ -5,6 +5,7 @@
 	     conf_space_capability.o \
 	     conf_space_capability_vpd.o \
 	     conf_space_capability_pm.o \
+	     conf_space_capability_exp.o \
              conf_space_quirks.o
 pciback-$(CONFIG_PCI_MSI) += conf_space_capability_msi.o
 pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
diff -r 366c31f3ab4b drivers/xen/pciback/conf_space.c
--- a/drivers/xen/pciback/conf_space.c	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/conf_space.c	Tue Apr 21 16:48:25 2009 +0900
@@ -375,6 +375,18 @@
 	cfg_entry->field = field;
 	cfg_entry->base_offset = base_offset;
 
+	/* When the size of the registers is different, by a version of the PCI,
+	 * "is_need" function can prevent addition to the list of an unnecessary
+	 * register.
+	 */
+	if (field->is_need) {
+		err = field->is_need(dev, base_offset);
+		if (!err) {
+			kfree(cfg_entry);
+			goto out;
+		}
+	}
+
 	/* silently ignore duplicate fields */
 	err = pciback_field_is_dup(dev,OFFSET(cfg_entry));
 	if (err)
@@ -433,3 +445,69 @@
 {
 	return pciback_config_capability_init();
 }
+
+/* save AER one register */
+static int pciback_aer_save_one_register(struct pci_dev *dev, int offset)
+{
+	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
+	return pci_read_config_dword(dev, (dev_data->config.aer_base + offset),
+		(u32*)&dev_data->config.config_aer[offset]);
+}
+
+/* save AER registers */
+int pciback_aer_reg_save(struct pci_dev *dev)
+{
+	int err = 0;
+
+	/* after reset, following register values should be restored.
+	 * So, save them.
+	 */
+	err = pciback_aer_save_one_register(dev, PCI_ERR_UNCOR_MASK);
+	if (err)
+		goto out;
+	err = pciback_aer_save_one_register(dev, PCI_ERR_UNCOR_SEVER);
+	if (err)
+		goto out;
+	err = pciback_aer_save_one_register(dev, PCI_ERR_COR_MASK);
+	if (err)
+		goto out;
+	err = pciback_aer_save_one_register(dev, PCI_ERR_CAP);
+
+      out:
+	return err;
+}
+
+/* restore AER one register */
+static int pciback_aer_restore_one_register(struct pci_dev *dev, int offset)
+{
+	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
+	return pci_write_config_dword(dev,
+				 (dev_data->config.aer_base + offset),
+				  *((u32*)&dev_data->config.config[offset]));
+}
+
+/* restore AER registers */
+int pciback_aer_reg_restore(struct pci_dev *dev)
+{
+	int err = 0;
+
+	/* the following registers should be reconfigured to correct values
+	 * after reset. restore them.
+	 * other registers should not be reconfigured after reset
+	 * if there is no reason
+	 */
+	err = pciback_aer_restore_one_register(dev, PCI_ERR_UNCOR_MASK);
+	if (err)
+		goto out;
+	err = pciback_aer_restore_one_register(dev, PCI_ERR_UNCOR_SEVER);
+	if (err)
+		goto out;
+	err = pciback_aer_restore_one_register(dev, PCI_ERR_COR_MASK);
+	if (err)
+		goto out;
+	err = pciback_aer_restore_one_register(dev, PCI_ERR_CAP);
+
+      out:
+	return err;
+}
+
diff -r 366c31f3ab4b drivers/xen/pciback/conf_space.h
--- a/drivers/xen/pciback/conf_space.h	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/conf_space.h	Tue Apr 21 16:48:25 2009 +0900
@@ -27,6 +27,10 @@
 			       void *data);
 typedef int (*conf_byte_read) (struct pci_dev * dev, int offset, u8 * value,
 			       void *data);
+typedef int (*conf_dword_restore)(struct pci_dev *dev, int offset, u32 data);
+typedef int (*conf_word_restore)(struct pci_dev *dev, int offset, u16 data);
+typedef int (*conf_byte_restore)(struct pci_dev *dev, int offset, u8 data);
+typedef int (*conf_field_is_need)(struct pci_dev *dev, int offset);
 
 /* These are the fields within the configuration space which we
  * are interested in intercepting reads/writes to and changing their
@@ -44,16 +48,20 @@
 		struct {
 			conf_dword_write write;
 			conf_dword_read read;
+			conf_dword_restore restore;
 		} dw;
 		struct {
 			conf_word_write write;
 			conf_word_read read;
+			conf_word_restore restore;
 		} w;
 		struct {
 			conf_byte_write write;
 			conf_byte_read read;
+			conf_byte_restore restore;
 		} b;
 	} u;
+	conf_field_is_need is_need;
 	struct list_head list;
 };
 
@@ -123,4 +131,22 @@
 int pciback_config_header_add_fields(struct pci_dev *dev);
 int pciback_config_capability_add_fields(struct pci_dev *dev);
 
+static inline int pciback_restore_config_dword(struct pci_dev *dev, int offset,
+					      u32 data)
+{
+	return pci_write_config_dword(dev, offset, data);
+}
+
+static inline int pciback_restore_config_word(struct pci_dev *dev, int offset,
+					      u16 data)
+{
+	return pci_write_config_word(dev, offset, data);
+}
+
+static inline int pciback_restore_config_byte(struct pci_dev *dev, int offset,
+				       u8 data)
+{
+	return pci_write_config_byte(dev, offset, data);
+}
+
 #endif				/* __XEN_PCIBACK_CONF_SPACE_H__ */
diff -r 366c31f3ab4b drivers/xen/pciback/conf_space_capability.c
--- a/drivers/xen/pciback/conf_space_capability.c	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/conf_space_capability.c	Tue Apr 21 16:48:25 2009 +0900
@@ -59,11 +59,13 @@
 
 extern struct pciback_config_capability pciback_config_capability_vpd;
 extern struct pciback_config_capability pciback_config_capability_pm;
+extern struct pciback_config_capability pciback_config_capability_exp;
 
 int pciback_config_capability_init(void)
 {
 	register_capability(&pciback_config_capability_vpd);
 	register_capability(&pciback_config_capability_pm);
+	register_capability(&pciback_config_capability_exp);
 
 	return 0;
 }
diff -r 366c31f3ab4b drivers/xen/pciback/conf_space_capability_exp.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/pciback/conf_space_capability_exp.c	Tue Apr 21 16:48:25 2009 +0900
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, NEC Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+/*
+ * PCI Backend -- Configuration overlay for PCI Express capability
+ */
+#include <linux/pci.h>
+#include "conf_space.h"
+#include "conf_space_capability.h"
+
+/* PCI express version 1.0 does not have the registers over offset 24H */
+static int pciback_exp_is_need_config2(struct pci_dev *dev, int base_offset)
+{
+	u16 cap;
+	pci_read_config_word(dev, base_offset + PCI_EXP_FLAGS, &cap);
+	if ((cap & PCI_EXP_FLAGS_VERS) == 1)
+		return 0;
+	else
+		return 1;
+}
+
+static const struct config_field caplist_exp[] = {
+	{
+		.offset      = PCI_EXP_DEVCTL,
+		.size        = 2,
+		.u.w.restore = pciback_restore_config_word,
+	},
+	{
+		.offset      = PCI_EXP_LNKCTL,
+		.size        = 2,
+		.u.w.restore = pciback_restore_config_word,
+	},
+	{
+		.offset      = PCI_EXP_DEVCTL2,
+		.size        = 2,
+		.u.w.restore = pciback_restore_config_word,
+		.is_need     = pciback_exp_is_need_config2,
+	},
+	{
+		.offset      = PCI_EXP_LNKCTL2,
+		.size        = 2,
+		.u.w.restore = pciback_restore_config_word,
+		.is_need     = pciback_exp_is_need_config2,
+	},
+	{}
+};
+
+struct pciback_config_capability pciback_config_capability_exp = {
+	.capability = PCI_CAP_ID_EXP,
+	.fields = caplist_exp,
+};
+
diff -r 366c31f3ab4b drivers/xen/pciback/conf_space_capability_pm.c
--- a/drivers/xen/pciback/conf_space_capability_pm.c	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/conf_space_capability_pm.c	Tue Apr 21 16:48:25 2009 +0900
@@ -94,6 +94,27 @@
 	return ERR_PTR(err);
 }
 
+/* restore Power Management Control/Status register */
+static int pm_ctrl_restore(struct pci_dev *dev, int offset, u16 data)
+{
+	int err;
+	u16 value;
+
+	err = pci_read_config_word(dev, offset, &value);
+	if (err)
+		goto out;
+
+	/* No need to restore, just clear PME Enable and PME Status bit
+	 * Note: register type of PME Status bit is RW1C, so clear by writing 1b
+	 */
+	value = (value & ~PCI_PM_CTRL_PME_ENABLE) | PCI_PM_CTRL_PME_STATUS;
+
+	err = pci_write_config_word(dev, offset, value);
+
+      out:
+	return err;
+}
+
 static const struct config_field caplist_pm[] = {
 	{
 		.offset     = PCI_PM_PMC,
@@ -106,6 +127,7 @@
 		.init       = pm_ctrl_init,
 		.u.w.read   = pciback_read_config_word,
 		.u.w.write  = pm_ctrl_write,
+		.u.w.restore = pm_ctrl_restore,
 	},
 	{
 		.offset     = PCI_PM_PPB_EXTENSIONS,
diff -r 366c31f3ab4b drivers/xen/pciback/conf_space_header.c
--- a/drivers/xen/pciback/conf_space_header.c	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/conf_space_header.c	Tue Apr 21 16:48:25 2009 +0900
@@ -210,12 +210,34 @@
 	return err;
 }
 
+#define CONF_COMMAND_MASK (PCI_COMMAND_PARITY | PCI_COMMAND_SERR)
+
+static int command_restore(struct pci_dev *dev, int offset, u16 data)
+{
+	int err;
+	u16 tmp_val;
+
+	err = pci_read_config_word(dev, offset, &tmp_val);
+	if (err)
+		goto out;
+
+	tmp_val &= ~CONF_COMMAND_MASK;
+	tmp_val |= (data & CONF_COMMAND_MASK);
+
+	err = pci_write_config_word(dev, offset, tmp_val);
+
+      out:
+	return err;
+}
+
+
 static const struct config_field header_common[] = {
 	{
 	 .offset    = PCI_COMMAND,
 	 .size      = 2,
 	 .u.w.read  = pciback_read_config_word,
 	 .u.w.write = command_write,
+	 .u.w.restore = command_restore,
 	},
 	{
 	 .offset    = PCI_INTERRUPT_LINE,
@@ -233,11 +255,13 @@
 	 .size      = 1,
 	 .u.b.read  = pciback_read_config_byte,
 	 .u.b.write = pciback_write_config_byte,
+	 .u.b.restore = pciback_restore_config_byte,
 	},
 	{
 	 .offset    = PCI_LATENCY_TIMER,
 	 .size      = 1,
 	 .u.b.read  = pciback_read_config_byte,
+	 .u.b.restore = pciback_restore_config_byte,
 	},
 	{
 	 .offset    = PCI_BIST,
@@ -257,6 +281,7 @@
 	 .release    = bar_release, 			\
 	 .u.dw.read  = bar_read, 			\
 	 .u.dw.write = bar_write, 			\
+	 .u.dw.restore = pciback_restore_config_dword,	\
 	 }
 
 #define CFG_FIELD_ROM(reg_offset) 			\
@@ -268,6 +293,7 @@
 	 .release    = bar_release, 			\
 	 .u.dw.read  = bar_read, 			\
 	 .u.dw.write = rom_write, 			\
+	 .u.dw.restore = pciback_restore_config_dword,	\
 	 }
 
 static const struct config_field header_0[] = {
diff -r 366c31f3ab4b drivers/xen/pciback/pci_stub.c
--- a/drivers/xen/pciback/pci_stub.c	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/pci_stub.c	Tue Apr 21 16:48:25 2009 +0900
@@ -135,6 +135,91 @@
 	return psdev;
 }
 
+int pcistub_save_config_space(struct pci_dev *dev)
+{
+	int err = 0;
+	int offset;
+	u8  value;
+	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
+
+	/* save configuration space */
+	for (offset = 0; offset < 256; offset++) {
+		err = pci_read_config_byte(dev, offset, &value);
+		if (err) {
+			dev_err(&dev->dev, 
+				"(%s) Read error in config space[%x]!\n",
+				__func__, offset);
+			goto out;
+		}
+		dev_data->config.config[offset] = value;
+	}
+	dev_dbg(&dev->dev, "Save real configuration space \n");
+
+	dev_data->config.aer_base = 
+			(u32)pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+	if (!dev_data->config.aer_base)
+		goto out;
+
+	/* save advanced error reporting registers */
+	err = pciback_aer_reg_save(dev);
+	dev_dbg(&dev->dev, "Save advanced error reporting[%d]\n", err);
+
+      out:
+	return err;
+}
+
+int pcistub_restore_config_space(struct pci_dev *dev)
+{
+	int err = 0;
+	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
+	struct config_field_entry *cfg_entry;
+	const struct config_field *field;
+	int offset;
+
+	/* Restore configuration space */
+	list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
+		field = cfg_entry->field;
+		offset = OFFSET(cfg_entry);
+		switch (field->size) {
+		case 1:
+			if (!field->u.b.restore)
+				continue;
+			err = field->u.b.restore(dev,
+				offset, dev_data->config.config[offset]);
+			break;
+		case 2:
+			if (!field->u.w.restore)
+				continue;
+			err = field->u.w.restore(dev, offset,
+				*((u16 *)&dev_data->config.config[offset]));
+			break;
+		case 4:
+			if (!field->u.dw.restore)
+				continue;
+			err = field->u.dw.restore(dev, offset,
+				*((u32 *)&dev_data->config.config[offset]));
+			break;
+		}
+		if (err) {
+			dev_err(&dev->dev, 
+				"(%s) Restore error<%d> in config space"
+				"at offset 0x%x!\n", __func__, err, offset);
+			goto out;
+		}
+	}
+	dev_dbg(&dev->dev, "Restore base configuration space \n");
+
+	if (!dev_data->config.aer_base)
+		goto out;
+
+	/* restore advanced error reporting registers */
+	err = pciback_aer_reg_restore(dev);
+	dev_dbg(&dev->dev, "Restore advanced error reporting\n");
+
+      out:
+	return err;
+}
+
 static struct pci_dev *pcistub_device_get_pci_dev(struct pciback_device *pdev,
 						  struct pcistub_device *psdev)
 {
@@ -292,6 +377,10 @@
 	}
 	pci_set_drvdata(dev, dev_data);
 
+	/* Save configuration space */
+	dev_dbg(&dev->dev, "Save configuration space\n");
+	pcistub_save_config_space(dev);
+
 	dev_dbg(&dev->dev, "initializing config\n");
 
 	init_waitqueue_head(&aer_wait_queue);
diff -r 366c31f3ab4b drivers/xen/pciback/pciback.h
--- a/drivers/xen/pciback/pciback.h	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/pciback.h	Tue Apr 21 16:48:25 2009 +0900
@@ -44,10 +44,17 @@
 	struct work_struct op_work;
 };
 
+struct pciback_config {
+	u8  config[256];
+	u32 aer_base;
+	u8  config_aer[72];
+};
+
 struct pciback_dev_data {
 	struct list_head config_fields;
 	int permissive;
 	int warned_on_write;
+	struct pciback_config config;
 };
 
 /* Get/Put PCI Devices that are hidden from the PCI Backend Domain */
@@ -122,5 +129,12 @@
 extern int verbose_request;
 
 void test_and_schedule_op(struct pciback_device *pdev);
+
+extern int pciback_aer_reg_save(struct pci_dev *dev);
+extern int pciback_aer_reg_restore(struct pci_dev *dev);
+
+extern int pcistub_save_config_space(struct pci_dev *dev);
+extern int pcistub_restore_config_space(struct pci_dev *dev);
+
 #endif
 
diff -r 366c31f3ab4b drivers/xen/pciback/pciback_ops.c
--- a/drivers/xen/pciback/pciback_ops.c	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/pciback_ops.c	Tue Apr 21 16:48:25 2009 +0900
@@ -20,6 +20,9 @@
 {
 	u16 cmd;
 
+	/* restore configuration space */
+	pcistub_restore_config_space(dev);
+
 	/* Disable devices (but not bridges) */
 	if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
 		pci_disable_device(dev);
diff -r 366c31f3ab4b drivers/xen/pciback/xenbus.c
--- a/drivers/xen/pciback/xenbus.c	Tue Apr 14 11:17:47 2009 +0100
+++ b/drivers/xen/pciback/xenbus.c	Tue Apr 21 16:48:25 2009 +0900
@@ -43,6 +43,30 @@
 	return pdev;
 }
 
+static int pciback_reinit_device(struct pciback_device *pdev,
+			       int domain, int bus, int slot, int func)
+{
+	int err = 0;
+	struct pci_dev *dev;
+
+	dev_dbg(&pdev->xdev->dev, "Reinitializing dom %x bus %x slot %x"
+		" func %x\n", domain, bus, slot, func);
+
+	dev = pciback_get_pci_dev(pdev, domain, bus, PCI_DEVFN(slot, func));
+	if (!dev) {
+		err = -EINVAL;
+		dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device "
+			"(%04x:%02x:%02x.%01x)! not owned by this domain\n",
+			domain, bus, slot, func);
+		goto out;
+	}
+
+	pciback_reset_device(dev);
+	
+      out:
+	return err;
+}
+
 static void pciback_disconnect(struct pciback_device *pdev)
 {
 	spin_lock(&pdev->dev_lock);
@@ -394,6 +418,15 @@
 			if (err)
 				goto out;
 
+			err = pciback_reinit_device(pdev, domain, bus, slot,
+						  func);
+			if (err) {
+				xenbus_dev_fatal(pdev->xdev, err,
+						 "Error reinitialize pci device"
+						 "configuration");
+				goto out;
+			}
+
 			/* Publish pci roots. */
 			err = pciback_publish_pci_roots(pdev, pciback_publish_pci_root);
 			if (err) {
@@ -575,6 +608,14 @@
 		if (err)
 			goto out;
 
+		err = pciback_reinit_device(pdev, domain, bus, slot, func);
+		if (err) {
+			xenbus_dev_fatal(pdev->xdev, err,
+					 "Error reinitialize pci device "
+					 "configuration");
+			goto out;
+		}
+
 		/* Switch substate of this device. */
 		l = snprintf(state_str, sizeof(state_str), "state-%d", i);
 		if (unlikely(l >= (sizeof(state_str) - 1))) {
@@ -627,6 +668,10 @@
 		pciback_setup_backend(pdev);
 		break;
 
+	case XenbusStateReconfiguring:
+		pciback_reconfigure(pdev);
+		break;
+
 	default:
 		break;
 	}

  reply	other threads:[~2009-04-22  2:18 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-22  2:11 [PATCH 0/3] save/restore PCI configuration space in pciback Yuji Shimada
2009-04-22  2:18 ` Yuji Shimada [this message]
2009-04-22  2:20 ` [PATCH 2/3] remove saving/restoring method in Xend Yuji Shimada
2009-04-22  2:50   ` Masaki Kanno
2009-04-22  8:18     ` [PATCH 2/3 v2] " Yuji Shimada
2009-04-22 10:38   ` [PATCH 2/3] " Ian Pratt
2009-04-23  2:57     ` Yuji Shimada
2009-04-23  7:22       ` Keir Fraser
2009-04-23  8:27         ` Yuji Shimada
2009-04-23  9:01           ` Keir Fraser
2009-04-24  8:38             ` Yuji Shimada
2009-04-24  8:40             ` [PATCH 0/2] modify the order of resetting/deassigning device Yuji Shimada
2009-04-24  8:43               ` [PATCH 1/2] " Yuji Shimada
2009-04-24  8:43               ` [PATCH 2/2] ioemu: don't call xc_deassign_device() Yuji Shimada
2009-04-28  6:02                 ` Yuji Shimada
2009-04-22  2:20 ` [PATCH 3/3] ioemu: remove power state transition and xc_deassign_device() Yuji Shimada

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=20090422111410.32A7.27C06F64@necst.nec.co.jp \
    --to=shimada-yxb@necst.nec.co.jp \
    --cc=keir.fraser@eu.citrix.com \
    --cc=kouya@jp.fujitsu.com \
    --cc=xen-devel@lists.xensource.com \
    /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.