Re: [RFC]Pid conversion between pid namespace
Hi, On Fri, Jul 25, 2014 at 05:34:43PM +, Serge Hallyn wrote: > Quoting chenhanx...@cn.fujitsu.com (chenhanx...@cn.fujitsu.com): > > Hi, > > > > > -Original Message- > > > From: Serge Hallyn [mailto:serge.hal...@ubuntu.com] > > > Sent: Tuesday, July 15, 2014 12:16 PM > > > To: Chen, Hanxiao/陈 晗霄 > > > Subject: Re: [RFC]Pid conversion between pid namespace > > > > A-2) syscall pid_t getnspid(pid_t query_pid, pid_t observer_pid) > > > > pros: > > > > - ns procfs free, easy to use. > > > > We could get rid of mounted ns procfs. > > > > > > > > cons: > > > > - may find multiple results in nested ns. > > > > We wished the new API could tell us the exact answer. > > > > But if getnspid return more than one results will bring > > > > trouble to admins, > > > > > > (See below for more, but) the question being posed to getnspid has > > > precisely > > > one answer. > > > > > > > they had to make another decision. > > > > Or we marked the deepest level for translation as > > > > prerequisite. > > > > > > > > -based on current pidns, no reference ns. > > > > > > Hm, no. The intent here was that > > > > > > observer_pid would be in current ns > > > query_pid would be in observer_pid's ns. > > > > > > So this would be ideal for "I got a pid in a logfile created by rsyslog in > > > a nested contaner, what is the logged pid in my pidns." > > > > > > Taking a set of tasks (like a container with nesting) and bulding a tree > > > of all pids shouldn't be too difficult either. Start with the init pid, > > > call getnspid($pid, $init_pid) for every $pid in the container; to figure > > > out whether any $pid is itself a nested init_pid, we can compare the > > > /proc/$$/ns/pid, as well as look at getnspid($pid, $pid). > > I'm a little confused in this section: > > > > Ex: > > init_pid_nsns1 ns2 > > t1 2 > > t2 `- 3 1 > > t3 `- 4 `- 51 > > t4 `-6 `-8 `-9 > > t5 `-10 `-9 `-10 > > > > For getnspid($pid, $init_pid), > > Does init_pid means container's init_pid such as 3 for t2? > > Right, if you're in init_pid_ns and making the query, then > you'd pass 3. Sorry for jumping in, but I'm not quite understanding the purpose of $init_pid here, does it identify the ns which the process to be queried is in? Also see my questions below: 1. Given the example above, what's the return of getnspid(9, 3)? Is it 6(task t4) or 10(task t5)? 2. if there is a process in ns1 which is a child of process 1 has pid 10, but not in ns2, like below: init_pid_ns ns1 ns2 t1 2 t2 `- 31 t3 `- 4+- 51 t4 `-6 | `-8 `-9 t5 `-10 | `-9 `-10 t6 `-11`-10 then what is the return of getnspid(10, 3)? Regards, Hu > > > > In nested containers, does this syscall work as: > > getnspid(9, 4) -> (6, 8, 9) > > No, assuming the querying task is in init_pid_ns, > getnspid(9, 4) would return 6. > > 4 is the observer pid given in the querier's own pidns, so > it refers to t3. 9 is the pid being queried, in the oberver's > pidns, so it revers to t4. The result is, the pid in our own > pidns. > > Does that help clarify at all? I'm not sure whether the problem is that > I didn't explain well enough from the start, or whether this just shows > that the API is one only its mother could love :) > > -serge > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC]Pid conversion between pid namespace
Hi, On Fri, Jul 25, 2014 at 05:34:43PM +, Serge Hallyn wrote: Quoting chenhanx...@cn.fujitsu.com (chenhanx...@cn.fujitsu.com): Hi, -Original Message- From: Serge Hallyn [mailto:serge.hal...@ubuntu.com] Sent: Tuesday, July 15, 2014 12:16 PM To: Chen, Hanxiao/陈 晗霄 Subject: Re: [RFC]Pid conversion between pid namespace A-2) syscall pid_t getnspid(pid_t query_pid, pid_t observer_pid) pros: - ns procfs free, easy to use. We could get rid of mounted ns procfs. cons: - may find multiple results in nested ns. We wished the new API could tell us the exact answer. But if getnspid return more than one results will bring trouble to admins, (See below for more, but) the question being posed to getnspid has precisely one answer. they had to make another decision. Or we marked the deepest level for translation as prerequisite. -based on current pidns, no reference ns. Hm, no. The intent here was that observer_pid would be in current ns query_pid would be in observer_pid's ns. So this would be ideal for I got a pid in a logfile created by rsyslog in a nested contaner, what is the logged pid in my pidns. Taking a set of tasks (like a container with nesting) and bulding a tree of all pids shouldn't be too difficult either. Start with the init pid, call getnspid($pid, $init_pid) for every $pid in the container; to figure out whether any $pid is itself a nested init_pid, we can compare the /proc/$$/ns/pid, as well as look at getnspid($pid, $pid). I'm a little confused in this section: Ex: init_pid_nsns1 ns2 t1 2 t2 `- 3 1 t3 `- 4 `- 51 t4 `-6 `-8 `-9 t5 `-10 `-9 `-10 For getnspid($pid, $init_pid), Does init_pid means container's init_pid such as 3 for t2? Right, if you're in init_pid_ns and making the query, then you'd pass 3. Sorry for jumping in, but I'm not quite understanding the purpose of $init_pid here, does it identify the ns which the process to be queried is in? Also see my questions below: 1. Given the example above, what's the return of getnspid(9, 3)? Is it 6(task t4) or 10(task t5)? 2. if there is a process in ns1 which is a child of process 1 has pid 10, but not in ns2, like below: init_pid_ns ns1 ns2 t1 2 t2 `- 31 t3 `- 4+- 51 t4 `-6 | `-8 `-9 t5 `-10 | `-9 `-10 t6 `-11`-10 then what is the return of getnspid(10, 3)? Regards, Hu In nested containers, does this syscall work as: getnspid(9, 4) - (6, 8, 9) No, assuming the querying task is in init_pid_ns, getnspid(9, 4) would return 6. 4 is the observer pid given in the querier's own pidns, so it refers to t3. 9 is the pid being queried, in the oberver's pidns, so it revers to t4. The result is, the pid in our own pidns. Does that help clarify at all? I'm not sure whether the problem is that I didn't explain well enough from the start, or whether this just shows that the API is one only its mother could love :) -serge -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] mem-hotplug: Introduce MMOP_OFFLINE to replace the hard coding -1.
On Fri, Jun 06, 2014 at 11:58:54AM +0800, Tang Chen wrote: > In store_mem_state(), we have: > .. > 334 else if (!strncmp(buf, "offline", min_t(int, count, 7))) > 335 online_type = -1; > .. > 355 case -1: > 356 ret = device_offline(>dev); > 357 break; > .. > > Here, "offline" is hard coded as -1. > > This patch does the following renaming: > ONLINE_KEEP -> MMOP_ONLINE_KEEP > ONLINE_KERNEL -> MMOP_ONLINE_KERNEL > ONLINE_MOVABLE -> MMOP_ONLINE_MOVABLE > > and introduce MMOP_OFFLINE = -1 to avoid hard coding. > > Signed-off-by: Tang Chen > --- > drivers/base/memory.c | 16 > include/linux/memory_hotplug.h | 9 + > mm/memory_hotplug.c| 9 ++--- > 3 files changed, 19 insertions(+), 15 deletions(-) > > diff --git a/drivers/base/memory.c b/drivers/base/memory.c > index fa664b9..0f3fa8c 100644 > --- a/drivers/base/memory.c > +++ b/drivers/base/memory.c > @@ -294,7 +294,7 @@ static int memory_subsys_online(struct device *dev) >* attribute and need to set the online_type. >*/ > if (mem->online_type < 0) > - mem->online_type = ONLINE_KEEP; > + mem->online_type = MMOP_ONLINE_KEEP; > > ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); > > @@ -326,22 +326,22 @@ store_mem_state(struct device *dev, > return ret; > > if (sysfs_streq(buf, "online_kernel")) > - online_type = ONLINE_KERNEL; > + online_type = MMOP_ONLINE_KERNEL; > else if (sysfs_streq(buf, "online_movable")) > - online_type = ONLINE_MOVABLE; > + online_type = MMOP_ONLINE_MOVABLE; > else if (sysfs_streq(buf, "online")) > - online_type = ONLINE_KEEP; > + online_type = MMOP_ONLINE_KEEP; > else if (sysfs_streq(buf, "offline")) > - online_type = -1; > + online_type = MMOP_OFFLINE; > else { > ret = -EINVAL; > goto err; > } > > switch (online_type) { > - case ONLINE_KERNEL: > - case ONLINE_MOVABLE: > - case ONLINE_KEEP: > + case MMOP_ONLINE_KERNEL: > + case MMOP_ONLINE_MOVABLE: > + case MMOP_ONLINE_KEEP: There is a `case -1' several lines below should have been converted. > /* >* mem->online_type is not protected so there can be a >* race here. However, when racing online, the first > diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h > index 4ca3d95..b4240cf 100644 > --- a/include/linux/memory_hotplug.h > +++ b/include/linux/memory_hotplug.h > @@ -26,11 +26,12 @@ enum { > MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE = NODE_INFO, > }; > > -/* Types for control the zone type of onlined memory */ > +/* Types for control the zone type of onlined and offlined memory */ > enum { > - ONLINE_KEEP, > - ONLINE_KERNEL, > - ONLINE_MOVABLE, > + MMOP_OFFLINE = -1, > + MMOP_ONLINE_KEEP, > + MMOP_ONLINE_KERNEL, > + MMOP_ONLINE_MOVABLE, > }; > > /* > diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c > index a650db2..6075f04 100644 > --- a/mm/memory_hotplug.c > +++ b/mm/memory_hotplug.c > @@ -907,19 +907,22 @@ int __ref online_pages(unsigned long pfn, unsigned long > nr_pages, int online_typ >*/ > zone = page_zone(pfn_to_page(pfn)); > > - if ((zone_idx(zone) > ZONE_NORMAL || online_type == ONLINE_MOVABLE) && > + if ((zone_idx(zone) > ZONE_NORMAL || > + online_type == MMOP_ONLINE_MOVABLE) && > !can_online_high_movable(zone)) { > unlock_memory_hotplug(); > return -EINVAL; > } > > - if (online_type == ONLINE_KERNEL && zone_idx(zone) == ZONE_MOVABLE) { > + if (online_type == MMOP_ONLINE_KERNEL && > + zone_idx(zone) == ZONE_MOVABLE) { > if (move_pfn_range_left(zone - 1, zone, pfn, pfn + nr_pages)) { > unlock_memory_hotplug(); > return -EINVAL; > } > } > - if (online_type == ONLINE_MOVABLE && zone_idx(zone) == ZONE_MOVABLE - > 1) { > + if (online_type == MMOP_ONLINE_MOVABLE && > + zone_idx(zone) == ZONE_MOVABLE - 1) { > if (move_pfn_range_right(zone, zone + 1, pfn, pfn + nr_pages)) { > unlock_memory_hotplug(); > return -EINVAL; > -- > 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] mem-hotplug: Introduce MMOP_OFFLINE to replace the hard coding -1.
On Fri, Jun 06, 2014 at 11:58:54AM +0800, Tang Chen wrote: In store_mem_state(), we have: .. 334 else if (!strncmp(buf, offline, min_t(int, count, 7))) 335 online_type = -1; .. 355 case -1: 356 ret = device_offline(mem-dev); 357 break; .. Here, offline is hard coded as -1. This patch does the following renaming: ONLINE_KEEP - MMOP_ONLINE_KEEP ONLINE_KERNEL - MMOP_ONLINE_KERNEL ONLINE_MOVABLE - MMOP_ONLINE_MOVABLE and introduce MMOP_OFFLINE = -1 to avoid hard coding. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- drivers/base/memory.c | 16 include/linux/memory_hotplug.h | 9 + mm/memory_hotplug.c| 9 ++--- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index fa664b9..0f3fa8c 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -294,7 +294,7 @@ static int memory_subsys_online(struct device *dev) * attribute and need to set the online_type. */ if (mem-online_type 0) - mem-online_type = ONLINE_KEEP; + mem-online_type = MMOP_ONLINE_KEEP; ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); @@ -326,22 +326,22 @@ store_mem_state(struct device *dev, return ret; if (sysfs_streq(buf, online_kernel)) - online_type = ONLINE_KERNEL; + online_type = MMOP_ONLINE_KERNEL; else if (sysfs_streq(buf, online_movable)) - online_type = ONLINE_MOVABLE; + online_type = MMOP_ONLINE_MOVABLE; else if (sysfs_streq(buf, online)) - online_type = ONLINE_KEEP; + online_type = MMOP_ONLINE_KEEP; else if (sysfs_streq(buf, offline)) - online_type = -1; + online_type = MMOP_OFFLINE; else { ret = -EINVAL; goto err; } switch (online_type) { - case ONLINE_KERNEL: - case ONLINE_MOVABLE: - case ONLINE_KEEP: + case MMOP_ONLINE_KERNEL: + case MMOP_ONLINE_MOVABLE: + case MMOP_ONLINE_KEEP: There is a `case -1' several lines below should have been converted. /* * mem-online_type is not protected so there can be a * race here. However, when racing online, the first diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 4ca3d95..b4240cf 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -26,11 +26,12 @@ enum { MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE = NODE_INFO, }; -/* Types for control the zone type of onlined memory */ +/* Types for control the zone type of onlined and offlined memory */ enum { - ONLINE_KEEP, - ONLINE_KERNEL, - ONLINE_MOVABLE, + MMOP_OFFLINE = -1, + MMOP_ONLINE_KEEP, + MMOP_ONLINE_KERNEL, + MMOP_ONLINE_MOVABLE, }; /* diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index a650db2..6075f04 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -907,19 +907,22 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ */ zone = page_zone(pfn_to_page(pfn)); - if ((zone_idx(zone) ZONE_NORMAL || online_type == ONLINE_MOVABLE) + if ((zone_idx(zone) ZONE_NORMAL || + online_type == MMOP_ONLINE_MOVABLE) !can_online_high_movable(zone)) { unlock_memory_hotplug(); return -EINVAL; } - if (online_type == ONLINE_KERNEL zone_idx(zone) == ZONE_MOVABLE) { + if (online_type == MMOP_ONLINE_KERNEL + zone_idx(zone) == ZONE_MOVABLE) { if (move_pfn_range_left(zone - 1, zone, pfn, pfn + nr_pages)) { unlock_memory_hotplug(); return -EINVAL; } } - if (online_type == ONLINE_MOVABLE zone_idx(zone) == ZONE_MOVABLE - 1) { + if (online_type == MMOP_ONLINE_MOVABLE + zone_idx(zone) == ZONE_MOVABLE - 1) { if (move_pfn_range_right(zone, zone + 1, pfn, pfn + nr_pages)) { unlock_memory_hotplug(); return -EINVAL; -- 1.8.3.1 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] doc: fix a typo about irq affinity
smp_affinity holds bitmask and smp_affinity_list holds list. So we should write a list to smp_affinity_list, instead of smp_affinity. Signed-off-by: Hu Tao --- Documentation/IRQ-affinity.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/IRQ-affinity.txt b/Documentation/IRQ-affinity.txt index 7890fae..01a6751 100644 --- a/Documentation/IRQ-affinity.txt +++ b/Documentation/IRQ-affinity.txt @@ -57,8 +57,8 @@ i.e counters for the CPU0-3 did not change. Here is an example of limiting that same irq (44) to cpus 1024 to 1031: -[root@moon 44]# echo 1024-1031 > smp_affinity -[root@moon 44]# cat smp_affinity +[root@moon 44]# echo 1024-1031 > smp_affinity_list +[root@moon 44]# cat smp_affinity_list 1024-1031 Note that to do this with a bitmask would require 32 bitmasks of zero -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] doc: fix a typo about irq affinity
smp_affinity holds bitmask and smp_affinity_list holds list. So we should write a list to smp_affinity_list, instead of smp_affinity. Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- Documentation/IRQ-affinity.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/IRQ-affinity.txt b/Documentation/IRQ-affinity.txt index 7890fae..01a6751 100644 --- a/Documentation/IRQ-affinity.txt +++ b/Documentation/IRQ-affinity.txt @@ -57,8 +57,8 @@ i.e counters for the CPU0-3 did not change. Here is an example of limiting that same irq (44) to cpus 1024 to 1031: -[root@moon 44]# echo 1024-1031 smp_affinity -[root@moon 44]# cat smp_affinity +[root@moon 44]# echo 1024-1031 smp_affinity_list +[root@moon 44]# cat smp_affinity_list 1024-1031 Note that to do this with a bitmask would require 32 bitmasks of zero -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
On Tue, Mar 05, 2013 at 09:26:18AM +0100, Paolo Bonzini wrote: > Il 05/03/2013 04:17, Hu Tao ha scritto: > > Will > > > > if (runstate_check(RUN_STATE_INTERNAL_ERROR) || > > runstate_check(RUN_STATE_SHUTDOWN) || > > runstate_check(RUN_STATE_GUEST_PANICKED)) { > > runstate_set(RUN_STATE_PAUSED); > > } > > > > be OK? Or I must be misunderstanding you. > > > > Please move > >return (runstate_check(RUN_STATE_INTERNAL_ERROR) || >runstate_check(RUN_STATE_SHUTDOWN) || >runstate_check(RUN_STATE_GUEST_PANICKED)); > > to a separate function (runstate_needs_reset for example), so that you > can reuse it in the two or three places that need it. See it now. Thanks! -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 0/8] pv event interface between host and guest
Hi, On Mon, Mar 04, 2013 at 11:05:37AM +0100, Paolo Bonzini wrote: > Il 03/03/2013 10:17, Gleb Natapov ha scritto: > > On Thu, Feb 28, 2013 at 08:13:10PM +0800, Hu Tao wrote: > >> This series implements a new interface, kvm pv event, to notify host when > >> some events happen in guest. Right now there is one supported event: guest > >> panic. > >> > > What other event do you have in mind? Is interface generic enough to > > accommodate future, yet unknown, events. It allows to pass only one > > integer specifying even type, what if additional info is needed? My be > > stop pretending that device is generic and make it do once thing but do > > it well? For generic even passing interface (whatever it may be needed > > for) much more powerful virtio should be used. > > > > On implementation itself I do not understand why is this kvm specific. > > The only thing that makes it so is that you hook device initialization > > into guest kvm initialization code, but this is obviously incorrect. > > What stops QEMU tcg or Xen from reusing the same device for the same > > purpose except the artificial limitation in a guest. > > Agreed. > > > Reading data from a random ioports is not how you discover platform > > devices in 21 century (and the data you read from unassigned port is not > > guarantied to be zero, it may depend on QEMU version), you use ACPI for > > that and Marcelo already pointed that to you. Having little knowledge of > > ACPI (we all do) is not a good reason to not doing it. We probably need > > to reserve QEMU specific ACPI Plug and Play hardware ID to define our own > > devices. After that you will be able to create device with _HID(QEMU0001) > > in DSDT that supplies address information (ioport to use) and capability > > supported. > > Please also document this HID in a new file in the QEMU docs/ directory. > > > Guest uses acpi_get_devices() to discover a platform device by > > its name (QEMU0001). Then you put the driver for the platform device > > into drivers/platform/x86/ and QEMU/kvm/Xen all will be able to use it. > > Just to clarify it for Hu Tao, the read from a random ioport is how the > ACPI code will detect presence of the device. > > Something like this should work (in SeaBIOS's src/acpi-dsdt-isa.dsl): > > Device(PEVT) { > Name(_HID, EisaId("QEMU0001")) > OperationRegion(PEOR, SystemIO, 0x505, 0x01) > Field(PEOR, ByteAcc, NoLock, Preserve) { > PEPT, 8, > } > > Method(_STA, 0, NotSerialized) { > Store(PEPT, Local0) > If (LEqual(Local0, Zero)) { > Return (0x00) > } Else { > Return (0x0F) > } > } IIUC, here _STA reads from ioport 0x505, if the result is 0, then the device is not present. Otherwise, the device is present. But as Gleb said, ''the data you read from unassigned port is not guarantied to be zero, it may depend on QEMU version''. What should I do to tell if the device is present or not correctly? > > Name(_CRS, ResourceTemplate() { > IO(Decode16, 0x505, 0x505, 0x01, 0x01) > }) > } > > Please test this with a QEMU option like "-M pc-1.4". The device should > _not_ be detected if you're doing it right. because there is no corresponding device driver? > > > On QEMU side of things I cannot comment much on how QOMified the device > > is (it should be), > > Please make the device target-independent. It can be used on non-x86 > architectures that have I/O ports. You should make the port > configurable using a property (DEFINE_PROPERTY_INT16 or something like > that), with a default of 0x505. OK. > > All the panicked_action is not necessary in my opinion. We have it for > watchdogs, but that's really a legacy thing. Let libvirt do it, and > always make the guest panic perform the PANICKED_PAUSE action. OK. > > If you do it properly, a lot (really a lot) of code will go away. Thanks! > > > I hope other reviews will verify it, but I noticed > > that device is only initialized for PIIX, what about Q35? > > Yup. > > Paolo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 0/8] pv event interface between host and guest
On Sun, Mar 03, 2013 at 11:17:38AM +0200, Gleb Natapov wrote: > On Thu, Feb 28, 2013 at 08:13:10PM +0800, Hu Tao wrote: > > This series implements a new interface, kvm pv event, to notify host when > > some events happen in guest. Right now there is one supported event: guest > > panic. > > > What other event do you have in mind? Is interface generic enough to > accommodate future, yet unknown, events. It allows to pass only one > integer specifying even type, what if additional info is needed? My be guest crash, lockup, or warning.[1] But the first purpose is to do panic notification(panic event). Since at the point the guest is panicked, I think it's better to keep the interface as simple as possible. [1] http://wiki.qemu.org/Features/PVCrashDetection > stop pretending that device is generic and make it do once thing but do you mean make the interface just do panic notification? > it well? For generic even passing interface (whatever it may be needed > for) much more powerful virtio should be used. > > On implementation itself I do not understand why is this kvm specific. > The only thing that makes it so is that you hook device initialization > into guest kvm initialization code, but this is obviously incorrect. > What stops QEMU tcg or Xen from reusing the same device for the same > purpose except the artificial limitation in a guest. > > Reading data from a random ioports is not how you discover platform > devices in 21 century (and the data you read from unassigned port is not > guarantied to be zero, it may depend on QEMU version), you use ACPI for > that and Marcelo already pointed that to you. Having little knowledge of > ACPI (we all do) is not a good reason to not doing it. We probably need > to reserve QEMU specific ACPI Plug and Play hardware ID to define our own Do we have to request the ID from some orgnazation? > devices. After that you will be able to create device with _HID(QEMU0001) QMU0001, I think. EISA ID requires it to have only 3 letters for PNP ID. > in DSDT that supplies address information (ioport to use) and capability > supported. Guest uses acpi_get_devices() to discover a platform device by > its name (QEMU0001). Then you put the driver for the platform device > into drivers/platform/x86/ and QEMU/kvm/Xen all will be able to use it. Thanks for the information! > > On QEMU side of things I cannot comment much on how QOMified the device > is (it should be), I hope other reviews will verify it, but I noticed > that device is only initialized for PIIX, what about Q35? > > -- > Gleb. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 0/8] pv event interface between host and guest
On Sun, Mar 03, 2013 at 11:17:38AM +0200, Gleb Natapov wrote: On Thu, Feb 28, 2013 at 08:13:10PM +0800, Hu Tao wrote: This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. What other event do you have in mind? Is interface generic enough to accommodate future, yet unknown, events. It allows to pass only one integer specifying even type, what if additional info is needed? My be guest crash, lockup, or warning.[1] But the first purpose is to do panic notification(panic event). Since at the point the guest is panicked, I think it's better to keep the interface as simple as possible. [1] http://wiki.qemu.org/Features/PVCrashDetection stop pretending that device is generic and make it do once thing but do you mean make the interface just do panic notification? it well? For generic even passing interface (whatever it may be needed for) much more powerful virtio should be used. On implementation itself I do not understand why is this kvm specific. The only thing that makes it so is that you hook device initialization into guest kvm initialization code, but this is obviously incorrect. What stops QEMU tcg or Xen from reusing the same device for the same purpose except the artificial limitation in a guest. Reading data from a random ioports is not how you discover platform devices in 21 century (and the data you read from unassigned port is not guarantied to be zero, it may depend on QEMU version), you use ACPI for that and Marcelo already pointed that to you. Having little knowledge of ACPI (we all do) is not a good reason to not doing it. We probably need to reserve QEMU specific ACPI Plug and Play hardware ID to define our own Do we have to request the ID from some orgnazation? devices. After that you will be able to create device with _HID(QEMU0001) QMU0001, I think. EISA ID requires it to have only 3 letters for PNP ID. in DSDT that supplies address information (ioport to use) and capability supported. Guest uses acpi_get_devices() to discover a platform device by its name (QEMU0001). Then you put the driver for the platform device into drivers/platform/x86/ and QEMU/kvm/Xen all will be able to use it. Thanks for the information! On QEMU side of things I cannot comment much on how QOMified the device is (it should be), I hope other reviews will verify it, but I noticed that device is only initialized for PIIX, what about Q35? -- Gleb. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 0/8] pv event interface between host and guest
Hi, On Mon, Mar 04, 2013 at 11:05:37AM +0100, Paolo Bonzini wrote: Il 03/03/2013 10:17, Gleb Natapov ha scritto: On Thu, Feb 28, 2013 at 08:13:10PM +0800, Hu Tao wrote: This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. What other event do you have in mind? Is interface generic enough to accommodate future, yet unknown, events. It allows to pass only one integer specifying even type, what if additional info is needed? My be stop pretending that device is generic and make it do once thing but do it well? For generic even passing interface (whatever it may be needed for) much more powerful virtio should be used. On implementation itself I do not understand why is this kvm specific. The only thing that makes it so is that you hook device initialization into guest kvm initialization code, but this is obviously incorrect. What stops QEMU tcg or Xen from reusing the same device for the same purpose except the artificial limitation in a guest. Agreed. Reading data from a random ioports is not how you discover platform devices in 21 century (and the data you read from unassigned port is not guarantied to be zero, it may depend on QEMU version), you use ACPI for that and Marcelo already pointed that to you. Having little knowledge of ACPI (we all do) is not a good reason to not doing it. We probably need to reserve QEMU specific ACPI Plug and Play hardware ID to define our own devices. After that you will be able to create device with _HID(QEMU0001) in DSDT that supplies address information (ioport to use) and capability supported. Please also document this HID in a new file in the QEMU docs/ directory. Guest uses acpi_get_devices() to discover a platform device by its name (QEMU0001). Then you put the driver for the platform device into drivers/platform/x86/ and QEMU/kvm/Xen all will be able to use it. Just to clarify it for Hu Tao, the read from a random ioport is how the ACPI code will detect presence of the device. Something like this should work (in SeaBIOS's src/acpi-dsdt-isa.dsl): Device(PEVT) { Name(_HID, EisaId(QEMU0001)) OperationRegion(PEOR, SystemIO, 0x505, 0x01) Field(PEOR, ByteAcc, NoLock, Preserve) { PEPT, 8, } Method(_STA, 0, NotSerialized) { Store(PEPT, Local0) If (LEqual(Local0, Zero)) { Return (0x00) } Else { Return (0x0F) } } IIUC, here _STA reads from ioport 0x505, if the result is 0, then the device is not present. Otherwise, the device is present. But as Gleb said, ''the data you read from unassigned port is not guarantied to be zero, it may depend on QEMU version''. What should I do to tell if the device is present or not correctly? Name(_CRS, ResourceTemplate() { IO(Decode16, 0x505, 0x505, 0x01, 0x01) }) } Please test this with a QEMU option like -M pc-1.4. The device should _not_ be detected if you're doing it right. because there is no corresponding device driver? On QEMU side of things I cannot comment much on how QOMified the device is (it should be), Please make the device target-independent. It can be used on non-x86 architectures that have I/O ports. You should make the port configurable using a property (DEFINE_PROPERTY_INT16 or something like that), with a default of 0x505. OK. All the panicked_action is not necessary in my opinion. We have it for watchdogs, but that's really a legacy thing. Let libvirt do it, and always make the guest panic perform the PANICKED_PAUSE action. OK. If you do it properly, a lot (really a lot) of code will go away. Thanks! I hope other reviews will verify it, but I noticed that device is only initialized for PIIX, what about Q35? Yup. Paolo -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
On Tue, Mar 05, 2013 at 09:26:18AM +0100, Paolo Bonzini wrote: Il 05/03/2013 04:17, Hu Tao ha scritto: Will if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN) || runstate_check(RUN_STATE_GUEST_PANICKED)) { runstate_set(RUN_STATE_PAUSED); } be OK? Or I must be misunderstanding you. Please move return (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN) || runstate_check(RUN_STATE_GUEST_PANICKED)); to a separate function (runstate_needs_reset for example), so that you can reuse it in the two or three places that need it. See it now. Thanks! -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 2/8] start vm after resetting it
On Mon, Mar 04, 2013 at 10:32:17AM +0100, Paolo Bonzini wrote: > Il 28/02/2013 13:13, Hu Tao ha scritto: > > From: Wen Congyang > > > > The guest should run after resetting it, but it does not run if its > > old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. > > > > We don't set runstate to RUN_STATE_PAUSED when resetting the guest, > > so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or > > RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). > > This is also debatable. In particular, restarting an INTERNAL_ERROR > guest makes it harder to inspect the state at the time of the failure. > > INTERNAL_ERROR should never happen, let's separate this patch too. Sure. > > Paolo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 2/8] start vm after resetting it
On Thu, Feb 28, 2013 at 02:23:42PM +0100, Jan Kiszka wrote: > On 2013-02-28 13:13, Hu Tao wrote: > > From: Wen Congyang > > > > The guest should run after resetting it, but it does not run if its > > old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. > > > > We don't set runstate to RUN_STATE_PAUSED when resetting the guest, > > so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or > > RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). > > I just wonder what will happen if I interrupted the guest via gdb and > then issue "monitor system_reset", also via gdb - common pattern if you > set a breakpoint on some BUG() or fault handler and then want to restart > the guest. Will the guest continue then while gdb thinks it is still > stopped? Likely, we do not differentiate between gdb-initiated stops and > the rest. Could you clarify? Guest won't continue unless issue gdb "continue". Anyway, I'll seperate this patch, as Paolo requested. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 5/8] add a new qevent: QEVENT_GUEST_PANICKED
On Fri, Mar 01, 2013 at 09:31:47AM -0700, Eric Blake wrote: > On 02/28/2013 05:13 AM, Hu Tao wrote: > > This event will be emited when the guest is panicked. > > > > Signed-off-by: Wen Congyang > > --- > > include/monitor/monitor.h | 1 + > > monitor.c | 1 + > > 2 files changed, 2 insertions(+) > > Missing documentation in QMP/qmp-events.txt Thanks, will add it. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
On Mon, Mar 04, 2013 at 10:40:15AM +0100, Paolo Bonzini wrote: > Il 28/02/2013 13:13, Hu Tao ha scritto: > > The guest will be in this state when it is panicked. > > > > Signed-off-by: Wen Congyang > > Signed-off-by: Hu Tao > > --- > > migration.c | 1 + > > qapi-schema.json | 6 +- > > qmp.c| 3 ++- > > vl.c | 11 ++- > > 4 files changed, 18 insertions(+), 3 deletions(-) > > > > diff --git a/migration.c b/migration.c > > index c29830e..fa17b82 100644 > > --- a/migration.c > > +++ b/migration.c > > @@ -698,6 +698,7 @@ static void *buffered_file_thread(void *opaque) > > int64_t start_time, end_time; > > > > DPRINTF("done iterating\n"); > > +save_run_state(); > > start_time = qemu_get_clock_ms(rt_clock); > > qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); > > if (old_vm_running) { > > diff --git a/qapi-schema.json b/qapi-schema.json > > index 28b070f..8f1d138 100644 > > --- a/qapi-schema.json > > +++ b/qapi-schema.json > > @@ -174,11 +174,15 @@ > > # @suspended: guest is suspended (ACPI S3) > > # > > # @watchdog: the watchdog action is configured to pause and has been > > triggered > > +# > > +# @guest-panicked: the panicked action is configured to pause and has been > > +# triggered. > > ## > > { 'enum': 'RunState', > >'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', > > 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', > > -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } > > +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', > > +'guest-panicked' ] } > > > > ## > > # @SnapshotInfo > > diff --git a/qmp.c b/qmp.c > > index 5f1bed1..f5027f6 100644 > > --- a/qmp.c > > +++ b/qmp.c > > @@ -150,7 +150,8 @@ void qmp_cont(Error **errp) > > Error *local_err = NULL; > > > > if (runstate_check(RUN_STATE_INTERNAL_ERROR) || > > - runstate_check(RUN_STATE_SHUTDOWN)) { > > +runstate_check(RUN_STATE_SHUTDOWN) || > > +runstate_check(RUN_STATE_GUEST_PANICKED)) { > > error_set(errp, QERR_RESET_REQUIRED); > > return; > > } else if (runstate_check(RUN_STATE_SUSPENDED)) { > > diff --git a/vl.c b/vl.c > > index 3d08e1a..51d4922 100644 > > --- a/vl.c > > +++ b/vl.c > > @@ -536,6 +536,7 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > > > { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, > > { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, > > +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, > > Is this a consequence of the first patch? Yes. > > > { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, > > { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, > > @@ -549,6 +550,7 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, > > { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, > > { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, > > +{ RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, > > Impossible. GUEST_PANICKED requires an instruction to be executed in > the guest, so it should first go to RUNNING. > > > { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, > > { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, > > @@ -559,6 +561,7 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > > > { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, > > { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, > > +{ RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, > > Is it also for the first patch? Yes. > > > { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, > > { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, > > @@ -569,6 +572,7 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, > > { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, > > { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, > > +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, > > This one is obviously ok. > > > { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, > > > > @@ -583,6 +587,10 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > { RUN_S
Re: [PATCH v13 1/8] save/load cpu runstate
On Mon, Mar 04, 2013 at 10:30:48AM +0100, Paolo Bonzini wrote: > Il 28/02/2013 13:13, Hu Tao ha scritto: > > This patch enables preservation of cpu runstate during save/load vm. > > So when a vm is restored from snapshot, the cpu runstate is restored, > > too. > > I don't think this feature is worth breaking backwards migration > compatibility. It is usually handled at a higher-level (management, > like libvirt). If guest panic happens during migration, runstate will still be running on destination host without this patch. But, it does be a problem to break backwards migration compatibility. > > Please make this a separate patch. Sure. > > Paolo > > > See following example: > > > > # save two vms: one is running, the other is paused > > (qemu) info status > > VM status: running > > (qemu) savevm running > > (qemu) stop > > (qemu) info status > > VM status: paused > > (qemu) savevm paused > > > > # restore the one running > > (qemu) info status > > VM status: paused > > (qemu) loadvm running > > (qemu) info status > > VM status: running > > > > # restore the one paused > > (qemu) loadvm paused > > (qemu) info status > > VM status: paused > > (qemu) cont > > (qemu)info status > > VM status: running > > > > Signed-off-by: Hu Tao > > --- > > include/sysemu/sysemu.h | 2 ++ > > migration.c | 6 +- > > monitor.c | 5 ++--- > > savevm.c| 1 + > > vl.c| 34 ++ > > 5 files changed, 40 insertions(+), 8 deletions(-) > > > > diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h > > index b19ec95..f121213 100644 > > --- a/include/sysemu/sysemu.h > > +++ b/include/sysemu/sysemu.h > > @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; > > int qemu_uuid_parse(const char *str, uint8_t *uuid); > > #define UUID_FMT > > "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" > > > > +void save_run_state(void); > > +void load_run_state(void); > > bool runstate_check(RunState state); > > void runstate_set(RunState new_state); > > int runstate_is_running(void); > > diff --git a/migration.c b/migration.c > > index 11725ae..c29830e 100644 > > --- a/migration.c > > +++ b/migration.c > > @@ -107,11 +107,7 @@ static void process_incoming_migration_co(void *opaque) > > /* Make sure all file formats flush their mutable metadata */ > > bdrv_invalidate_cache_all(); > > > > -if (autostart) { > > -vm_start(); > > -} else { > > -runstate_set(RUN_STATE_PAUSED); > > -} > > +load_run_state(); > > } > > > > void process_incoming_migration(QEMUFile *f) > > diff --git a/monitor.c b/monitor.c > > index 32a6e74..bf974b4 100644 > > --- a/monitor.c > > +++ b/monitor.c > > @@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp) > > > > static void do_loadvm(Monitor *mon, const QDict *qdict) > > { > > -int saved_vm_running = runstate_is_running(); > > const char *name = qdict_get_str(qdict, "name"); > > > > vm_stop(RUN_STATE_RESTORE_VM); > > > > -if (load_vmstate(name) == 0 && saved_vm_running) { > > -vm_start(); > > +if (load_vmstate(name) == 0) { > > +load_run_state(); > > } > > } > > > > diff --git a/savevm.c b/savevm.c > > index a8a53ef..aa631eb 100644 > > --- a/savevm.c > > +++ b/savevm.c > > @@ -2143,6 +2143,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) > > } > > > > saved_vm_running = runstate_is_running(); > > +save_run_state(); > > vm_stop(RUN_STATE_SAVE_VM); > > > > memset(sn, 0, sizeof(*sn)); > > diff --git a/vl.c b/vl.c > > index febd2ea..7991f2e 100644 > > --- a/vl.c > > +++ b/vl.c > > @@ -523,6 +523,7 @@ static int default_driver_check(QemuOpts *opts, void > > *opaque) > > /* QEMU state */ > > > > static RunState current_run_state = RUN_STATE_PRELAUNCH; > > +static RunState saved_run_state = RUN_STATE_RUNNING; > > > > typedef struct { > > RunState from; > > @@ -546,6 +547,7 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, > > > > { RUN_STATE_POSTMIG
Re: [PATCH v13 1/8] save/load cpu runstate
On Mon, Mar 04, 2013 at 10:30:48AM +0100, Paolo Bonzini wrote: Il 28/02/2013 13:13, Hu Tao ha scritto: This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too. I don't think this feature is worth breaking backwards migration compatibility. It is usually handled at a higher-level (management, like libvirt). If guest panic happens during migration, runstate will still be running on destination host without this patch. But, it does be a problem to break backwards migration compatibility. Please make this a separate patch. Sure. Paolo See following example: # save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused # restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running # restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- include/sysemu/sysemu.h | 2 ++ migration.c | 6 +- monitor.c | 5 ++--- savevm.c| 1 + vl.c| 34 ++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index b19ec95..f121213 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT %02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx +void save_run_state(void); +void load_run_state(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/migration.c b/migration.c index 11725ae..c29830e 100644 --- a/migration.c +++ b/migration.c @@ -107,11 +107,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); -if (autostart) { -vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); -} +load_run_state(); } void process_incoming_migration(QEMUFile *f) diff --git a/monitor.c b/monitor.c index 32a6e74..bf974b4 100644 --- a/monitor.c +++ b/monitor.c @@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp) static void do_loadvm(Monitor *mon, const QDict *qdict) { -int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, name); vm_stop(RUN_STATE_RESTORE_VM); -if (load_vmstate(name) == 0 saved_vm_running) { -vm_start(); +if (load_vmstate(name) == 0) { +load_run_state(); } } diff --git a/savevm.c b/savevm.c index a8a53ef..aa631eb 100644 --- a/savevm.c +++ b/savevm.c @@ -2143,6 +2143,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); +save_run_state(); vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/vl.c b/vl.c index febd2ea..7991f2e 100644 --- a/vl.c +++ b/vl.c @@ -523,6 +523,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque) /* QEMU state */ static RunState current_run_state = RUN_STATE_PRELAUNCH; +static RunState saved_run_state = RUN_STATE_RUNNING; typedef struct { RunState from; @@ -546,6 +547,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, @@ -556,6 +558,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -585,11 +588,39 @@ static const RunStateTransition runstate_transitions_def[] = { static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +void save_run_state(void) +{ +saved_run_state = current_run_state; +} + +void load_run_state(void) +{ +if (saved_run_state == RUN_STATE_RUNNING) { +vm_start(); +} else if (!runstate_check(saved_run_state)) { +runstate_set
Re: [PATCH v13 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
On Mon, Mar 04, 2013 at 10:40:15AM +0100, Paolo Bonzini wrote: Il 28/02/2013 13:13, Hu Tao ha scritto: The guest will be in this state when it is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- migration.c | 1 + qapi-schema.json | 6 +- qmp.c| 3 ++- vl.c | 11 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/migration.c b/migration.c index c29830e..fa17b82 100644 --- a/migration.c +++ b/migration.c @@ -698,6 +698,7 @@ static void *buffered_file_thread(void *opaque) int64_t start_time, end_time; DPRINTF(done iterating\n); +save_run_state(); start_time = qemu_get_clock_ms(rt_clock); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); if (old_vm_running) { diff --git a/qapi-schema.json b/qapi-schema.json index 28b070f..8f1d138 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -174,11 +174,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @SnapshotInfo diff --git a/qmp.c b/qmp.c index 5f1bed1..f5027f6 100644 --- a/qmp.c +++ b/qmp.c @@ -150,7 +150,8 @@ void qmp_cont(Error **errp) Error *local_err = NULL; if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index 3d08e1a..51d4922 100644 --- a/vl.c +++ b/vl.c @@ -536,6 +536,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, Is this a consequence of the first patch? Yes. { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, @@ -549,6 +550,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, Impossible. GUEST_PANICKED requires an instruction to be executed in the guest, so it should first go to RUNNING. { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, @@ -559,6 +561,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, Is it also for the first patch? Yes. { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -569,6 +572,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, This one is obviously ok. { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -583,6 +587,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, Like SHUTDOWN, it should go first to PAUSED and then to RUNNING. A GUEST_PANICKED - RUNNING transition is not possible. You're seeing it because you lack the addition of GUEST_PANICKED here: if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { runstate_set(RUN_STATE_PAUSED); } I think you should first move the INTERNAL_ERROR || SHUTDOWN checks to a separate function, so that you can then add GUEST_PANICKED. Will if (runstate_check
Re: [PATCH v13 5/8] add a new qevent: QEVENT_GUEST_PANICKED
On Fri, Mar 01, 2013 at 09:31:47AM -0700, Eric Blake wrote: On 02/28/2013 05:13 AM, Hu Tao wrote: This event will be emited when the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- include/monitor/monitor.h | 1 + monitor.c | 1 + 2 files changed, 2 insertions(+) Missing documentation in QMP/qmp-events.txt Thanks, will add it. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 2/8] start vm after resetting it
On Thu, Feb 28, 2013 at 02:23:42PM +0100, Jan Kiszka wrote: On 2013-02-28 13:13, Hu Tao wrote: From: Wen Congyang we...@cn.fujitsu.com The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). I just wonder what will happen if I interrupted the guest via gdb and then issue monitor system_reset, also via gdb - common pattern if you set a breakpoint on some BUG() or fault handler and then want to restart the guest. Will the guest continue then while gdb thinks it is still stopped? Likely, we do not differentiate between gdb-initiated stops and the rest. Could you clarify? Guest won't continue unless issue gdb continue. Anyway, I'll seperate this patch, as Paolo requested. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 2/8] start vm after resetting it
On Mon, Mar 04, 2013 at 10:32:17AM +0100, Paolo Bonzini wrote: Il 28/02/2013 13:13, Hu Tao ha scritto: From: Wen Congyang we...@cn.fujitsu.com The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). This is also debatable. In particular, restarting an INTERNAL_ERROR guest makes it harder to inspect the state at the time of the failure. INTERNAL_ERROR should never happen, let's separate this patch too. Sure. Paolo -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v13 1/8] save/load cpu runstate
On Thu, Feb 28, 2013 at 02:12:37PM -0700, Eric Blake wrote: > On 02/28/2013 05:13 AM, Hu Tao wrote: > > This patch enables preservation of cpu runstate during save/load vm. > > So when a vm is restored from snapshot, the cpu runstate is restored, > > too. > > What happens if a management app wants to override the runstate when > restoring the domain? I can think of several useful scenarios: > > 1. management app pauses the guest, then saves domain state and other > things (management state, or disk clones), then resumes the guest. > Later, the management wants to revert to the saved state, but have the > guest running right away. I guess here, knowing that the guest was > saved in a paused state doesn't hurt, since the management app can > resume it right away. > > 2. management app saves domain state of a live guest, then copies that > state elsewhere. In its new location, the management app wants to > investigate the state for forensic analysis - so even though the guest > remembers that it was running, management wants to start it paused. > Here, it is important that there must not be a window of time where the > guest can run, otherwise, the results are not reproducible. -S takes precedence in the case. But for in-migration, runstate is loaded from src. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13] kvm: notify host when the guest is panicked
We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- arch/x86/include/asm/kvm_para.h | 26 + arch/x86/include/uapi/asm/kvm_para.h | 2 ++ arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/kvm.c| 44 arch/x86/kernel/kvm_panic.c | 32 ++ kernel/panic.c | 4 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 arch/x86/kernel/kvm_panic.c diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 695399f..deae820 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -133,4 +133,30 @@ static inline void kvm_disable_steal_time(void) } #endif +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 + +static inline unsigned int kvm_arch_pv_features(void) +{ + return inl(KVM_PV_EVENT_PORT); +} + +static inline unsigned int kvm_arch_pv_has_feature(unsigned int feature) +{ + if (kvm_arch_pv_features() & (1UL << feature)) + return 1; + return 0; +} + +static inline void kvm_arch_pv_send_event(unsigned int event) +{ + outl(event, KVM_PV_EVENT_PORT); +} + +bool kvm_arch_pv_event_enabled(void); +int kvm_arch_pv_event_init(void); + #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 06fdbd9..c15ef33 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) + #endif /* _UAPI_ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 7bd3bd3..f0629b2 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -80,7 +80,7 @@ obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o obj-$(CONFIG_DEBUG_NX_TEST)+= test_nx.o obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o -obj-$(CONFIG_KVM_GUEST)+= kvm.o kvmclock.o +obj-$(CONFIG_KVM_GUEST)+= kvm.o kvmclock.o kvm_panic.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index b686a90..727ef91 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -73,6 +73,20 @@ static int parse_no_kvmclock_vsyscall(char *arg) early_param("no-kvmclock-vsyscall", parse_no_kvmclock_vsyscall); +static int pv_event = 1; +static int parse_no_pv_event(char *arg) +{ + pv_event = 0; + return 0; +} + +bool kvm_arch_pv_event_enabled(void) +{ + return !!pv_event; +} + +early_param("no-pv-event", parse_no_pv_event); + static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64); static int has_steal_clock = 0; @@ -386,6 +400,17 @@ static struct notifier_block kvm_pv_reboot_nb = { .notifier_call = kvm_pv_reboot_notify, }; +static int +kvm_pv_panic_notify(struct notifier_block *nb, unsigned long code, void *unused) +{ + kvm_arch_pv_send_event(KVM_PV_EVENT_PANICKED); + return NOTIFY_DONE; +} + +static struct notifier_block kvm_pv_panic_nb = { + .notifier_call = kvm_pv_panic_notify, +}; + static u64 kvm_steal_clock(int cpu) { u64 steal; @@ -463,6 +488,23 @@ static void __init kvm_apf_trap_init(void) set_intr_gate(14, _page_fault); } +static void __init kvm_pv_panicked_event_init(void) +{ + if (kvm_arch_pv_has_feature(KVM_PV_FEATURE_PANICKED)) + atomic_notifier_chain_register(_notifier_list, + _pv_panic_nb); +} + +static void enable_pv_event(void) +{ + if (pv_event) { + if (kvm_arch_pv_event_init()) + return; + + kvm_pv_panicked_event_init(); + } +} + void __init kvm_guest_init(void) { int i; @@ -494,6 +536,8 @@ void __init kvm_guest_init(void) #else
[PATCH v13 6/8] introduce a new qom device to deal with panicked event
If the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target. Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 198 +++ hw/pc_piix.c | 5 ++ include/sysemu/kvm.h | 2 + kvm-stub.c | 4 ++ 5 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 hw/kvm/pv_event.c diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs index f620d7f..cf93199 100644 --- a/hw/kvm/Makefile.objs +++ b/hw/kvm/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o pv_event.o diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c new file mode 100644 index 000..5e68190 --- /dev/null +++ b/hw/kvm/pv_event.c @@ -0,0 +1,198 @@ +/* + * QEMU KVM support, paravirtual event device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +#define PV_EVENT_DRIVER "kvm_pv_event" +#define PV_IOPORT(obj) OBJECT_CHECK(PVIOPortState, (obj), PV_EVENT_DRIVER) + +struct PVEventAction { +char *panicked_action; +int panicked_action_value; +}; + +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \ +DEFINE_PROP_STRING("panicked_action", _state, _conf.panicked_action) + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf("{ 'action': %s }", action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(uint32_t panicked_action) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event("report"); +break; + +case PANICKED_PAUSE: +panicked_mon_event("pause"); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event("poweroff"); +qemu_system_shutdown_request(); +break; + +case PANICKED_RESET: +panicked_mon_event("reset"); +qemu_system_reset_request(); +break; +} +} + +static uint64_t supported_event(void) +{ +return 1 << KVM_PV_FEATURE_PANICKED; +} + +static void handle_event(int event, struct PVEventAction *conf) +{ +if (event == KVM_PV_EVENT_PANICKED) { +panicked_perform_action(conf->panicked_action_value); +} +} + +static int pv_event_init(struct PVEventAction *conf) +{ +if (!conf->panicked_action) { +conf->panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf->panicked_action, "none") == 0) { +conf->panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf->panicked_action, "pause") == 0) { +conf->panicked_action_value = PANICKED_PAUSE; +} else if (strcasecmp(conf->panicked_action, "poweroff") == 0) { +conf->panicked_action_value = PANICKED_POWEROFF; +} else if (strcasecmp(conf->panicked_action, "reset") == 0) { +conf->panicked_action_value = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} + +#if defined(KVM_PV_EVENT_PORT) + +#include "hw/isa.h" + +typedef struct { +ISADevice dev; +struct PVEventAction conf; +MemoryRegion ioport; +} PVIOPortState; + +static uint64_t pv_io_read(void *opaque, hwaddr addr, unsigned size) +{ +return supported_event(); +} + +static void pv_io_write(void *opaque, hwaddr addr, uint64_
[PATCH v13 8/8] pv event: add document to describe the usage
Signed-off-by: Hu Tao --- docs/pv-event.txt | 17 + 1 file changed, 17 insertions(+) create mode 100644 docs/pv-event.txt diff --git a/docs/pv-event.txt b/docs/pv-event.txt new file mode 100644 index 000..ac9e7fa --- /dev/null +++ b/docs/pv-event.txt @@ -0,0 +1,17 @@ +KVM PV EVENT + + +kvm pv event allows guest OS to notify host OS of some events, for +example, guest panic. Currently, there is one event supported, that +is, guest panic. More events can be added later. + +By default, kvm pv event is disabled. In order to enable it, you have +to specify enable_pv_event=on for -machine command line option, along +with -global kvm_pv_event.panicked_action to specify the action taken +when panic event has occurred. Aviable panic actions are: "none", +"pause", "poweroff" and "reset". Following is example: + + qemu-system-x86_64 -enable-kvm -machine pc-0.12,enable_pv_event=on \ +-global kvm_pv_event.panicked_action=pause + +kvm pv event needs kvm support. -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
The guest will be in this state when it is panicked. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- migration.c | 1 + qapi-schema.json | 6 +- qmp.c| 3 ++- vl.c | 11 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/migration.c b/migration.c index c29830e..fa17b82 100644 --- a/migration.c +++ b/migration.c @@ -698,6 +698,7 @@ static void *buffered_file_thread(void *opaque) int64_t start_time, end_time; DPRINTF("done iterating\n"); +save_run_state(); start_time = qemu_get_clock_ms(rt_clock); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); if (old_vm_running) { diff --git a/qapi-schema.json b/qapi-schema.json index 28b070f..8f1d138 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -174,11 +174,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @SnapshotInfo diff --git a/qmp.c b/qmp.c index 5f1bed1..f5027f6 100644 --- a/qmp.c +++ b/qmp.c @@ -150,7 +150,8 @@ void qmp_cont(Error **errp) Error *local_err = NULL; if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index 3d08e1a..51d4922 100644 --- a/vl.c +++ b/vl.c @@ -536,6 +536,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, @@ -549,6 +550,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, @@ -559,6 +561,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -569,6 +572,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -583,6 +587,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, }; @@ -2001,7 +2009,8 @@ static bool main_loop_should_exit(void) qemu_system_reset(VMRESET_REPORT); resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || -runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { bdrv_iterate(iostatus_bdrv_it, NULL); vm_start(); } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 2/8] start vm after resetting it
From: Wen Congyang The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). Signed-off-by: Wen Congyang --- include/block/block.h | 2 ++ qmp.c | 2 +- vl.c | 7 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 0f750d7..8effc1e 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -376,6 +376,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + #ifdef CONFIG_LINUX_AIO int raw_get_aio_fd(BlockDriverState *bs); #else diff --git a/qmp.c b/qmp.c index 55b056b..5f1bed1 100644 --- a/qmp.c +++ b/qmp.c @@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index 7991f2e..3d08e1a 100644 --- a/vl.c +++ b/vl.c @@ -537,7 +537,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, @@ -572,7 +572,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, @@ -2002,7 +2002,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_wakeup_requested()) { -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 3/8] update kernel headers
update kernel headers to add pv event macros. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ 2 files changed, 7 insertions(+) diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index a1c3d72..e9b082d 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -96,5 +96,6 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT(0x505UL) #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index 7bdcf93..6c42923 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED1 + /* * hypercalls use architecture specific */ -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 1/8] save/load cpu runstate
This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too. See following example: # save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused # restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running # restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running Signed-off-by: Hu Tao --- include/sysemu/sysemu.h | 2 ++ migration.c | 6 +- monitor.c | 5 ++--- savevm.c| 1 + vl.c| 34 ++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index b19ec95..f121213 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +void save_run_state(void); +void load_run_state(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/migration.c b/migration.c index 11725ae..c29830e 100644 --- a/migration.c +++ b/migration.c @@ -107,11 +107,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); -if (autostart) { -vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); -} +load_run_state(); } void process_incoming_migration(QEMUFile *f) diff --git a/monitor.c b/monitor.c index 32a6e74..bf974b4 100644 --- a/monitor.c +++ b/monitor.c @@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp) static void do_loadvm(Monitor *mon, const QDict *qdict) { -int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, "name"); vm_stop(RUN_STATE_RESTORE_VM); -if (load_vmstate(name) == 0 && saved_vm_running) { -vm_start(); +if (load_vmstate(name) == 0) { +load_run_state(); } } diff --git a/savevm.c b/savevm.c index a8a53ef..aa631eb 100644 --- a/savevm.c +++ b/savevm.c @@ -2143,6 +2143,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); +save_run_state(); vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/vl.c b/vl.c index febd2ea..7991f2e 100644 --- a/vl.c +++ b/vl.c @@ -523,6 +523,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque) /* QEMU state */ static RunState current_run_state = RUN_STATE_PRELAUNCH; +static RunState saved_run_state = RUN_STATE_RUNNING; typedef struct { RunState from; @@ -546,6 +547,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, @@ -556,6 +558,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -585,11 +588,39 @@ static const RunStateTransition runstate_transitions_def[] = { static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +void save_run_state(void) +{ +saved_run_state = current_run_state; +} + +void load_run_state(void) +{ +if (saved_run_state == RUN_STATE_RUNNING) { +vm_start(); +} else if (!runstate_check(saved_run_state)) { +runstate_set(saved_run_state); +} else { +; /* leave unchanged */ +} +} + bool runstate_check(RunState state) { return current_run_state == state; } +static void runstate_save(QEMUFile *f, void *opaque) +{ +qemu_put_byte(f, saved_run_state); +} + +static int runstate_load(QEMUFile *f, void *opaque, int version_id) +{ +saved_run_state = qemu_get_byte(f); + +return 0; +} + static void runstate_init(void) { const RunStateTransition *p; @@ -599,6 +630,9 @@ static void runstate_init(void) for (p = _transitions_def[0]; p->from != RUN_STATE_MAX; p++) { runstate_valid_transitions[p->from][p->to] = true; } + +register_savevm(NULL, "runstate", 0, 1, +runstate_save, runstate_load, NULL); }
[PATCH v13 5/8] add a new qevent: QEVENT_GUEST_PANICKED
This event will be emited when the guest is panicked. Signed-off-by: Wen Congyang --- include/monitor/monitor.h | 1 + monitor.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 87fb49c..4006905 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -45,6 +45,7 @@ typedef enum MonitorEvent { QEVENT_WAKEUP, QEVENT_BALLOON_CHANGE, QEVENT_SPICE_MIGRATE_COMPLETED, +QEVENT_GUEST_PANICKED, /* Add to 'monitor_event_names' array in monitor.c when * defining new events here */ diff --git a/monitor.c b/monitor.c index bf974b4..d65218d 100644 --- a/monitor.c +++ b/monitor.c @@ -463,6 +463,7 @@ static const char *monitor_event_names[] = { [QEVENT_WAKEUP] = "WAKEUP", [QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE", [QEVENT_SPICE_MIGRATE_COMPLETED] = "SPICE_MIGRATE_COMPLETED", +[QEVENT_GUEST_PANICKED] = "GUEST_PANICKED", }; QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 7/8] allower the user to disable pv event support
Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- hw/pc_piix.c| 9 - qemu-options.hx | 3 ++- vl.c| 4 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 24a9bf3..82a421a 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -44,6 +44,7 @@ #include "exec/memory.h" #include "exec/address-spaces.h" #include "cpu.h" +#include "qemu/config-file.h" #ifdef CONFIG_XEN # include #endif @@ -86,6 +87,8 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; +QemuOptsList *list = qemu_find_opts("machine"); +bool enable_pv_event = false; pc_cpus_init(cpu_model); pc_acpi_init("acpi-dsdt.aml"); @@ -218,7 +221,11 @@ static void pc_init1(MemoryRegion *system_memory, pc_pci_device_init(pci_bus); } -if (kvm_enabled()) { +if (list && !QTAILQ_EMPTY(>head)) { +enable_pv_event = qemu_opt_get_bool(QTAILQ_FIRST(>head), +"enable_pv_event", false); +} +if (kvm_enabled() && enable_pv_event) { kvm_pv_event_init(isa_bus); } } diff --git a/qemu-options.hx b/qemu-options.hx index 797d992..1ad4041 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -35,7 +35,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ "kernel_irqchip=on|off controls accelerated irqchip support\n" "kvm_shadow_mem=size of KVM shadow MMU\n" "dump-guest-core=on|off include guest memory in a core dump (default=on)\n" -"mem-merge=on|off controls memory merge support (default: on)\n", +"mem-merge=on|off controls memory merge support (default: on)\n" +"enable_pv_event=on|off controls pv event support (default: off)\n", QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] diff --git a/vl.c b/vl.c index 51d4922..5b3a279 100644 --- a/vl.c +++ b/vl.c @@ -427,6 +427,10 @@ static QemuOptsList qemu_machine_opts = { .name = "usb", .type = QEMU_OPT_BOOL, .help = "Set on/off to enable/disable usb", +}, { +.name = "enable_pv_event", +.type = QEMU_OPT_BOOL, +.help = "handle pv event" }, { /* End of list */ } }, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 0/8] pv event interface between host and guest
This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. Also, the cpu runstate is preserved during save/load vm and migration. Thus, if vm is panicked during migration, we can still know it by quring the status of vm in destination host when migration completes. v12: http://lists.nongnu.org/archive/html/qemu-devel/2013-01/msg04120.html changes from v12: - no DO_UPCASE - the interface is only for x86 now - request 4 bytes io range(hw/kvm_pv_event.c) - rebase to the latest tree Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 198 +++ hw/pc_piix.c | 12 +++ include/block/block.h| 2 + include/monitor/monitor.h| 1 + include/sysemu/kvm.h | 2 + include/sysemu/sysemu.h | 2 + kvm-stub.c | 4 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- qapi-schema.json | 6 +- qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + vl.c | 56 ++- 18 files changed, 314 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
On Thu, Feb 07, 2013 at 11:39:47PM -0200, Marcelo Tosatti wrote: > Hi, > > On Wed, Jan 23, 2013 at 03:19:21PM +0800, Hu Tao wrote: > > We can know the guest is panicked when the guest runs on xen. > > But we do not have such feature on kvm. > > > > Another purpose of this feature is: management app(for example: > > libvirt) can do auto dump when the guest is panicked. If management > > app does not do auto dump, the guest's user can do dump by hand if > > he sees the guest is panicked. > > > > We have three solutions to implement this feature: > > 1. use vmcall > > 2. use I/O port > > 3. use virtio-serial. > > > > We have decided to avoid touching hypervisor. The reason why I choose > > choose the I/O port is: > > 1. it is easier to implememt > > 2. it does not depend any virtual device > > 3. it can work when starting the kernel > > > > Signed-off-by: Wen Congyang > > Signed-off-by: Hu Tao > > --- > > arch/ia64/kvm/irq.h | 19 + > > arch/powerpc/include/asm/kvm_para.h | 18 > > arch/s390/include/asm/kvm_para.h | 19 + > > arch/x86/include/asm/kvm_para.h | 20 ++ > > arch/x86/include/uapi/asm/kvm_para.h | 2 ++ > > arch/x86/kernel/kvm.c| 53 > > > > include/linux/kvm_para.h | 18 > > include/uapi/linux/kvm_para.h| 6 > > kernel/panic.c | 4 +++ > > 9 files changed, 159 insertions(+) > > > > diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h > > index c0785a7..b3870f8 100644 > > --- a/arch/ia64/kvm/irq.h > > +++ b/arch/ia64/kvm/irq.h > > @@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm) > > return 1; > > } > > > > +static inline int kvm_arch_pv_event_init(void) > > +{ > > + return 0; > > +} > > + > > +static inline unsigned int kvm_arch_pv_features(void) > > +{ > > + return 0; > > +} > > + > > +static inline void kvm_arch_pv_eject_event(unsigned int event) > > +{ > > +} > > + > > +static inline bool kvm_arch_pv_event_enabled(void) > > +{ > > + return false; > > +} > > + > > The interface is x86 only, no need to touch other architectures. OK. > > > #endif > > diff --git a/arch/powerpc/include/asm/kvm_para.h > > b/arch/powerpc/include/asm/kvm_para.h > > index 2b11965..17dd013 100644 > > --- a/arch/powerpc/include/asm/kvm_para.h > > +++ b/arch/powerpc/include/asm/kvm_para.h > > @@ -144,4 +144,22 @@ static inline bool > > kvm_check_and_clear_guest_paused(void) > > return false; > > } > > > > +static inline int kvm_arch_pv_event_init(void) > > +{ > > + return 0; > > +} > > + > > +static inline unsigned int kvm_arch_pv_features(void) > > +{ > > + return 0; > > +} > > + > > +static inline void kvm_arch_pv_eject_event(unsigned int event) > > +{ > > +} > > + > > +static inline bool kvm_arch_pv_event_enabled(void) > > +{ > > + return false; > > +} > > #endif /* __POWERPC_KVM_PARA_H__ */ > > diff --git a/arch/s390/include/asm/kvm_para.h > > b/arch/s390/include/asm/kvm_para.h > > index e0f8423..81d87ec 100644 > > --- a/arch/s390/include/asm/kvm_para.h > > +++ b/arch/s390/include/asm/kvm_para.h > > @@ -154,4 +154,23 @@ static inline bool > > kvm_check_and_clear_guest_paused(void) > > return false; > > } > > > > +static inline int kvm_arch_pv_event_init(void) > > +{ > > + return 0; > > +} > > + > > +static inline unsigned int kvm_arch_pv_features(void) > > +{ > > + return 0; > > +} > > + > > +static inline void kvm_arch_pv_eject_event(unsigned int event) > > +{ > > +} > > + > > +static inline bool kvm_arch_pv_event_enabled(void) > > +{ > > + return false; > > +} > > + > > #endif /* __S390_KVM_PARA_H */ > > --- a/arch/x86/include/asm/kvm_para.h > > +++ b/arch/x86/include/asm/kvm_para.h > > @@ -133,4 +133,24 @@ static inline void kvm_disable_steal_time(void) > > } > > #endif > > > > +static inline int kvm_arch_pv_event_init(void) > > +{ > > + if (!request_region(KVM_PV_EVENT_PORT, 4, "KVM_PV_EVENT")) > > + return -1; > > + > > + return 0; > > +} > > This should be in a driver in arch/x86/kernel/kvm-panic.
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
On Thu, Feb 07, 2013 at 11:39:47PM -0200, Marcelo Tosatti wrote: Hi, On Wed, Jan 23, 2013 at 03:19:21PM +0800, Hu Tao wrote: We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- arch/ia64/kvm/irq.h | 19 + arch/powerpc/include/asm/kvm_para.h | 18 arch/s390/include/asm/kvm_para.h | 19 + arch/x86/include/asm/kvm_para.h | 20 ++ arch/x86/include/uapi/asm/kvm_para.h | 2 ++ arch/x86/kernel/kvm.c| 53 include/linux/kvm_para.h | 18 include/uapi/linux/kvm_para.h| 6 kernel/panic.c | 4 +++ 9 files changed, 159 insertions(+) diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h index c0785a7..b3870f8 100644 --- a/arch/ia64/kvm/irq.h +++ b/arch/ia64/kvm/irq.h @@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm) return 1; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + The interface is x86 only, no need to touch other architectures. OK. #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index 2b11965..17dd013 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -144,4 +144,22 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index e0f8423..81d87ec 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,4 +154,23 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif /* __S390_KVM_PARA_H */ --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -133,4 +133,24 @@ static inline void kvm_disable_steal_time(void) } #endif +static inline int kvm_arch_pv_event_init(void) +{ + if (!request_region(KVM_PV_EVENT_PORT, 4, KVM_PV_EVENT)) + return -1; + + return 0; +} This should be in a driver in arch/x86/kernel/kvm-panic.c, or so. + +static inline unsigned int kvm_arch_pv_features(void) +{ + return inl(KVM_PV_EVENT_PORT); +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ + outl(event, KVM_PV_EVENT_PORT); +} + +bool kvm_arch_pv_event_enabled(void); + #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 06fdbd9..c15ef33 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) + No need for the ioport to be hard coded. What are the options to communicate an address to the guest? An MSR, via ACPI? I'm not quite understanding here. By 'address', you mean an ioport? how to communicate an address? (I have little knowledge about ACPI) #endif /* _UAPI_ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/kernel/kvm.c b/arch/x86
[PATCH v13 0/8] pv event interface between host and guest
This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. Also, the cpu runstate is preserved during save/load vm and migration. Thus, if vm is panicked during migration, we can still know it by quring the status of vm in destination host when migration completes. v12: http://lists.nongnu.org/archive/html/qemu-devel/2013-01/msg04120.html changes from v12: - no DO_UPCASE - the interface is only for x86 now - request 4 bytes io range(hw/kvm_pv_event.c) - rebase to the latest tree Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 198 +++ hw/pc_piix.c | 12 +++ include/block/block.h| 2 + include/monitor/monitor.h| 1 + include/sysemu/kvm.h | 2 + include/sysemu/sysemu.h | 2 + kvm-stub.c | 4 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- qapi-schema.json | 6 +- qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + vl.c | 56 ++- 18 files changed, 314 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 7/8] allower the user to disable pv event support
Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- hw/pc_piix.c| 9 - qemu-options.hx | 3 ++- vl.c| 4 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 24a9bf3..82a421a 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -44,6 +44,7 @@ #include exec/memory.h #include exec/address-spaces.h #include cpu.h +#include qemu/config-file.h #ifdef CONFIG_XEN # include xen/hvm/hvm_info_table.h #endif @@ -86,6 +87,8 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; +QemuOptsList *list = qemu_find_opts(machine); +bool enable_pv_event = false; pc_cpus_init(cpu_model); pc_acpi_init(acpi-dsdt.aml); @@ -218,7 +221,11 @@ static void pc_init1(MemoryRegion *system_memory, pc_pci_device_init(pci_bus); } -if (kvm_enabled()) { +if (list !QTAILQ_EMPTY(list-head)) { +enable_pv_event = qemu_opt_get_bool(QTAILQ_FIRST(list-head), +enable_pv_event, false); +} +if (kvm_enabled() enable_pv_event) { kvm_pv_event_init(isa_bus); } } diff --git a/qemu-options.hx b/qemu-options.hx index 797d992..1ad4041 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -35,7 +35,8 @@ DEF(machine, HAS_ARG, QEMU_OPTION_machine, \ kernel_irqchip=on|off controls accelerated irqchip support\n kvm_shadow_mem=size of KVM shadow MMU\n dump-guest-core=on|off include guest memory in a core dump (default=on)\n -mem-merge=on|off controls memory merge support (default: on)\n, +mem-merge=on|off controls memory merge support (default: on)\n +enable_pv_event=on|off controls pv event support (default: off)\n, QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] diff --git a/vl.c b/vl.c index 51d4922..5b3a279 100644 --- a/vl.c +++ b/vl.c @@ -427,6 +427,10 @@ static QemuOptsList qemu_machine_opts = { .name = usb, .type = QEMU_OPT_BOOL, .help = Set on/off to enable/disable usb, +}, { +.name = enable_pv_event, +.type = QEMU_OPT_BOOL, +.help = handle pv event }, { /* End of list */ } }, -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 5/8] add a new qevent: QEVENT_GUEST_PANICKED
This event will be emited when the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- include/monitor/monitor.h | 1 + monitor.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 87fb49c..4006905 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -45,6 +45,7 @@ typedef enum MonitorEvent { QEVENT_WAKEUP, QEVENT_BALLOON_CHANGE, QEVENT_SPICE_MIGRATE_COMPLETED, +QEVENT_GUEST_PANICKED, /* Add to 'monitor_event_names' array in monitor.c when * defining new events here */ diff --git a/monitor.c b/monitor.c index bf974b4..d65218d 100644 --- a/monitor.c +++ b/monitor.c @@ -463,6 +463,7 @@ static const char *monitor_event_names[] = { [QEVENT_WAKEUP] = WAKEUP, [QEVENT_BALLOON_CHANGE] = BALLOON_CHANGE, [QEVENT_SPICE_MIGRATE_COMPLETED] = SPICE_MIGRATE_COMPLETED, +[QEVENT_GUEST_PANICKED] = GUEST_PANICKED, }; QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 1/8] save/load cpu runstate
This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too. See following example: # save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused # restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running # restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- include/sysemu/sysemu.h | 2 ++ migration.c | 6 +- monitor.c | 5 ++--- savevm.c| 1 + vl.c| 34 ++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index b19ec95..f121213 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT %02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx +void save_run_state(void); +void load_run_state(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/migration.c b/migration.c index 11725ae..c29830e 100644 --- a/migration.c +++ b/migration.c @@ -107,11 +107,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); -if (autostart) { -vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); -} +load_run_state(); } void process_incoming_migration(QEMUFile *f) diff --git a/monitor.c b/monitor.c index 32a6e74..bf974b4 100644 --- a/monitor.c +++ b/monitor.c @@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp) static void do_loadvm(Monitor *mon, const QDict *qdict) { -int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, name); vm_stop(RUN_STATE_RESTORE_VM); -if (load_vmstate(name) == 0 saved_vm_running) { -vm_start(); +if (load_vmstate(name) == 0) { +load_run_state(); } } diff --git a/savevm.c b/savevm.c index a8a53ef..aa631eb 100644 --- a/savevm.c +++ b/savevm.c @@ -2143,6 +2143,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); +save_run_state(); vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/vl.c b/vl.c index febd2ea..7991f2e 100644 --- a/vl.c +++ b/vl.c @@ -523,6 +523,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque) /* QEMU state */ static RunState current_run_state = RUN_STATE_PRELAUNCH; +static RunState saved_run_state = RUN_STATE_RUNNING; typedef struct { RunState from; @@ -546,6 +547,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, @@ -556,6 +558,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -585,11 +588,39 @@ static const RunStateTransition runstate_transitions_def[] = { static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +void save_run_state(void) +{ +saved_run_state = current_run_state; +} + +void load_run_state(void) +{ +if (saved_run_state == RUN_STATE_RUNNING) { +vm_start(); +} else if (!runstate_check(saved_run_state)) { +runstate_set(saved_run_state); +} else { +; /* leave unchanged */ +} +} + bool runstate_check(RunState state) { return current_run_state == state; } +static void runstate_save(QEMUFile *f, void *opaque) +{ +qemu_put_byte(f, saved_run_state); +} + +static int runstate_load(QEMUFile *f, void *opaque, int version_id) +{ +saved_run_state = qemu_get_byte(f); + +return 0; +} + static void runstate_init(void) { const RunStateTransition *p; @@ -599,6 +630,9 @@ static void runstate_init(void) for (p = runstate_transitions_def[0]; p-from != RUN_STATE_MAX; p++) { runstate_valid_transitions[p-from][p-to] = true; } + +register_savevm(NULL, runstate, 0, 1, +runstate_save, runstate_load, NULL); } /* This function will abort
[PATCH v13 3/8] update kernel headers
update kernel headers to add pv event macros. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ 2 files changed, 7 insertions(+) diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index a1c3d72..e9b082d 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -96,5 +96,6 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT(0x505UL) #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index 7bdcf93..6c42923 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED1 + /* * hypercalls use architecture specific */ -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 2/8] start vm after resetting it
From: Wen Congyang we...@cn.fujitsu.com The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- include/block/block.h | 2 ++ qmp.c | 2 +- vl.c | 7 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 0f750d7..8effc1e 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -376,6 +376,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + #ifdef CONFIG_LINUX_AIO int raw_get_aio_fd(BlockDriverState *bs); #else diff --git a/qmp.c b/qmp.c index 55b056b..5f1bed1 100644 --- a/qmp.c +++ b/qmp.c @@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index 7991f2e..3d08e1a 100644 --- a/vl.c +++ b/vl.c @@ -537,7 +537,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, @@ -572,7 +572,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, @@ -2002,7 +2002,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_wakeup_requested()) { -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
The guest will be in this state when it is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- migration.c | 1 + qapi-schema.json | 6 +- qmp.c| 3 ++- vl.c | 11 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/migration.c b/migration.c index c29830e..fa17b82 100644 --- a/migration.c +++ b/migration.c @@ -698,6 +698,7 @@ static void *buffered_file_thread(void *opaque) int64_t start_time, end_time; DPRINTF(done iterating\n); +save_run_state(); start_time = qemu_get_clock_ms(rt_clock); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); if (old_vm_running) { diff --git a/qapi-schema.json b/qapi-schema.json index 28b070f..8f1d138 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -174,11 +174,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @SnapshotInfo diff --git a/qmp.c b/qmp.c index 5f1bed1..f5027f6 100644 --- a/qmp.c +++ b/qmp.c @@ -150,7 +150,8 @@ void qmp_cont(Error **errp) Error *local_err = NULL; if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index 3d08e1a..51d4922 100644 --- a/vl.c +++ b/vl.c @@ -536,6 +536,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, @@ -549,6 +550,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, @@ -559,6 +561,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -569,6 +572,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -583,6 +587,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, }; @@ -2001,7 +2009,8 @@ static bool main_loop_should_exit(void) qemu_system_reset(VMRESET_REPORT); resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || -runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { bdrv_iterate(iostatus_bdrv_it, NULL); vm_start(); } -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 8/8] pv event: add document to describe the usage
Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- docs/pv-event.txt | 17 + 1 file changed, 17 insertions(+) create mode 100644 docs/pv-event.txt diff --git a/docs/pv-event.txt b/docs/pv-event.txt new file mode 100644 index 000..ac9e7fa --- /dev/null +++ b/docs/pv-event.txt @@ -0,0 +1,17 @@ +KVM PV EVENT + + +kvm pv event allows guest OS to notify host OS of some events, for +example, guest panic. Currently, there is one event supported, that +is, guest panic. More events can be added later. + +By default, kvm pv event is disabled. In order to enable it, you have +to specify enable_pv_event=on for -machine command line option, along +with -global kvm_pv_event.panicked_action to specify the action taken +when panic event has occurred. Aviable panic actions are: none, +pause, poweroff and reset. Following is example: + + qemu-system-x86_64 -enable-kvm -machine pc-0.12,enable_pv_event=on \ +-global kvm_pv_event.panicked_action=pause other options + +kvm pv event needs kvm support. -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v13 6/8] introduce a new qom device to deal with panicked event
If the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target. Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 198 +++ hw/pc_piix.c | 5 ++ include/sysemu/kvm.h | 2 + kvm-stub.c | 4 ++ 5 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 hw/kvm/pv_event.c diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs index f620d7f..cf93199 100644 --- a/hw/kvm/Makefile.objs +++ b/hw/kvm/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o pv_event.o diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c new file mode 100644 index 000..5e68190 --- /dev/null +++ b/hw/kvm/pv_event.c @@ -0,0 +1,198 @@ +/* + * QEMU KVM support, paravirtual event device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang we...@cn.fujitsu.com + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include linux/kvm_para.h +#include asm/kvm_para.h +#include qapi/qmp/qobject.h +#include qapi/qmp/qjson.h +#include monitor/monitor.h +#include sysemu/sysemu.h +#include sysemu/kvm.h + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +#define PV_EVENT_DRIVER kvm_pv_event +#define PV_IOPORT(obj) OBJECT_CHECK(PVIOPortState, (obj), PV_EVENT_DRIVER) + +struct PVEventAction { +char *panicked_action; +int panicked_action_value; +}; + +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \ +DEFINE_PROP_STRING(panicked_action, _state, _conf.panicked_action) + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf({ 'action': %s }, action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(uint32_t panicked_action) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event(report); +break; + +case PANICKED_PAUSE: +panicked_mon_event(pause); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event(poweroff); +qemu_system_shutdown_request(); +break; + +case PANICKED_RESET: +panicked_mon_event(reset); +qemu_system_reset_request(); +break; +} +} + +static uint64_t supported_event(void) +{ +return 1 KVM_PV_FEATURE_PANICKED; +} + +static void handle_event(int event, struct PVEventAction *conf) +{ +if (event == KVM_PV_EVENT_PANICKED) { +panicked_perform_action(conf-panicked_action_value); +} +} + +static int pv_event_init(struct PVEventAction *conf) +{ +if (!conf-panicked_action) { +conf-panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf-panicked_action, none) == 0) { +conf-panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf-panicked_action, pause) == 0) { +conf-panicked_action_value = PANICKED_PAUSE; +} else if (strcasecmp(conf-panicked_action, poweroff) == 0) { +conf-panicked_action_value = PANICKED_POWEROFF; +} else if (strcasecmp(conf-panicked_action, reset) == 0) { +conf-panicked_action_value = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} + +#if defined(KVM_PV_EVENT_PORT) + +#include hw/isa.h + +typedef struct { +ISADevice dev; +struct PVEventAction conf; +MemoryRegion ioport; +} PVIOPortState; + +static uint64_t pv_io_read(void *opaque, hwaddr addr, unsigned size) +{ +return supported_event(); +} + +static void pv_io_write(void *opaque, hwaddr addr, uint64_t val
[PATCH v13] kvm: notify host when the guest is panicked
We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- arch/x86/include/asm/kvm_para.h | 26 + arch/x86/include/uapi/asm/kvm_para.h | 2 ++ arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/kvm.c| 44 arch/x86/kernel/kvm_panic.c | 32 ++ kernel/panic.c | 4 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 arch/x86/kernel/kvm_panic.c diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 695399f..deae820 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -133,4 +133,30 @@ static inline void kvm_disable_steal_time(void) } #endif +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 + +static inline unsigned int kvm_arch_pv_features(void) +{ + return inl(KVM_PV_EVENT_PORT); +} + +static inline unsigned int kvm_arch_pv_has_feature(unsigned int feature) +{ + if (kvm_arch_pv_features() (1UL feature)) + return 1; + return 0; +} + +static inline void kvm_arch_pv_send_event(unsigned int event) +{ + outl(event, KVM_PV_EVENT_PORT); +} + +bool kvm_arch_pv_event_enabled(void); +int kvm_arch_pv_event_init(void); + #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 06fdbd9..c15ef33 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) + #endif /* _UAPI_ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 7bd3bd3..f0629b2 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -80,7 +80,7 @@ obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o obj-$(CONFIG_DEBUG_NX_TEST)+= test_nx.o obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o -obj-$(CONFIG_KVM_GUEST)+= kvm.o kvmclock.o +obj-$(CONFIG_KVM_GUEST)+= kvm.o kvmclock.o kvm_panic.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index b686a90..727ef91 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -73,6 +73,20 @@ static int parse_no_kvmclock_vsyscall(char *arg) early_param(no-kvmclock-vsyscall, parse_no_kvmclock_vsyscall); +static int pv_event = 1; +static int parse_no_pv_event(char *arg) +{ + pv_event = 0; + return 0; +} + +bool kvm_arch_pv_event_enabled(void) +{ + return !!pv_event; +} + +early_param(no-pv-event, parse_no_pv_event); + static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64); static int has_steal_clock = 0; @@ -386,6 +400,17 @@ static struct notifier_block kvm_pv_reboot_nb = { .notifier_call = kvm_pv_reboot_notify, }; +static int +kvm_pv_panic_notify(struct notifier_block *nb, unsigned long code, void *unused) +{ + kvm_arch_pv_send_event(KVM_PV_EVENT_PANICKED); + return NOTIFY_DONE; +} + +static struct notifier_block kvm_pv_panic_nb = { + .notifier_call = kvm_pv_panic_notify, +}; + static u64 kvm_steal_clock(int cpu) { u64 steal; @@ -463,6 +488,23 @@ static void __init kvm_apf_trap_init(void) set_intr_gate(14, async_page_fault); } +static void __init kvm_pv_panicked_event_init(void) +{ + if (kvm_arch_pv_has_feature(KVM_PV_FEATURE_PANICKED)) + atomic_notifier_chain_register(panic_notifier_list, + kvm_pv_panic_nb); +} + +static void enable_pv_event(void) +{ + if (pv_event) { + if (kvm_arch_pv_event_init()) + return; + + kvm_pv_panicked_event_init(); + } +} + void __init kvm_guest_init(void) { int i; @@ -494,6 +536,8 @@ void __init kvm_guest_init(void) #else
Re: [PATCH v13 1/8] save/load cpu runstate
On Thu, Feb 28, 2013 at 02:12:37PM -0700, Eric Blake wrote: On 02/28/2013 05:13 AM, Hu Tao wrote: This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too. What happens if a management app wants to override the runstate when restoring the domain? I can think of several useful scenarios: 1. management app pauses the guest, then saves domain state and other things (management state, or disk clones), then resumes the guest. Later, the management wants to revert to the saved state, but have the guest running right away. I guess here, knowing that the guest was saved in a paused state doesn't hurt, since the management app can resume it right away. 2. management app saves domain state of a live guest, then copies that state elsewhere. In its new location, the management app wants to investigate the state for forensic analysis - so even though the guest remembers that it was running, management wants to start it paused. Here, it is important that there must not be a window of time where the guest can run, otherwise, the results are not reproducible. -S takes precedence in the case. But for in-migration, runstate is loaded from src. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v12 rebased 2/8] start vm after resetting it
On Thu, Feb 07, 2013 at 11:50:28PM -0200, Marcelo Tosatti wrote: > On Wed, Jan 23, 2013 at 03:19:23PM +0800, Hu Tao wrote: > > From: Wen Congyang > > > > The guest should run after resetting it, but it does not run if its > > old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. > > > > We don't set runstate to RUN_STATE_PAUSED when resetting the guest, > > so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or > > RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). > > It appears the last hunk will automatically reset state from > RUN_STATE_INTERNAL_ERROR to RUN_STATE_RUNNING ? Yes. > > I suppose the transition table allows, from RUN_STATE_INTERNAL_ERROR: > > system_reset > cont > > To resume the machine? True. I think the purpose of this patch is to always reset and _run_ the guest by `system_reset', avoiding an additional `cont' following `system_reset'. > > > > > Signed-off-by: Wen Congyang > > --- > > include/block/block.h | 2 ++ > > qmp.c | 2 +- > > vl.c | 7 --- > > 3 files changed, 7 insertions(+), 4 deletions(-) > > > > diff --git a/include/block/block.h b/include/block/block.h > > index ffd1936..5e82ccb 100644 > > --- a/include/block/block.h > > +++ b/include/block/block.h > > @@ -366,6 +366,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); > > void bdrv_set_in_use(BlockDriverState *bs, int in_use); > > int bdrv_in_use(BlockDriverState *bs); > > > > +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); > > + > > #ifdef CONFIG_LINUX_AIO > > int raw_get_aio_fd(BlockDriverState *bs); > > #else > > diff --git a/qmp.c b/qmp.c > > index 55b056b..5f1bed1 100644 > > --- a/qmp.c > > +++ b/qmp.c > > @@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) > > }; > > #endif > > > > -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) > > +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) > > { > > bdrv_iostatus_reset(bs); > > } > > diff --git a/vl.c b/vl.c > > index b0bcf1e..1d2edaa 100644 > > --- a/vl.c > > +++ b/vl.c > > @@ -534,7 +534,7 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, > > { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, > > > > -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, > > +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, > > { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, > > > > { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, > > @@ -569,7 +569,7 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > > > { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, > > > > -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, > > +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, > > { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, > > > > { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, > > @@ -1951,7 +1951,8 @@ static bool main_loop_should_exit(void) > > resume_all_vcpus(); > > if (runstate_check(RUN_STATE_INTERNAL_ERROR) || > > runstate_check(RUN_STATE_SHUTDOWN)) { > > -runstate_set(RUN_STATE_PAUSED); > > +bdrv_iterate(iostatus_bdrv_it, NULL); > > +vm_start(); > > } > > } > > if (qemu_wakeup_requested()) { > > -- > > 1.8.0.1.240.ge8a1f5a > > > > -- > > To unsubscribe from this list: send the line "unsubscribe kvm" in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Regards, Hu Tao -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v12 rebased 2/8] start vm after resetting it
On Thu, Feb 07, 2013 at 11:50:28PM -0200, Marcelo Tosatti wrote: On Wed, Jan 23, 2013 at 03:19:23PM +0800, Hu Tao wrote: From: Wen Congyang we...@cn.fujitsu.com The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). It appears the last hunk will automatically reset state from RUN_STATE_INTERNAL_ERROR to RUN_STATE_RUNNING ? Yes. I suppose the transition table allows, from RUN_STATE_INTERNAL_ERROR: monitor system_reset monitor cont To resume the machine? True. I think the purpose of this patch is to always reset and _run_ the guest by `system_reset', avoiding an additional `cont' following `system_reset'. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- include/block/block.h | 2 ++ qmp.c | 2 +- vl.c | 7 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index ffd1936..5e82ccb 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -366,6 +366,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + #ifdef CONFIG_LINUX_AIO int raw_get_aio_fd(BlockDriverState *bs); #else diff --git a/qmp.c b/qmp.c index 55b056b..5f1bed1 100644 --- a/qmp.c +++ b/qmp.c @@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index b0bcf1e..1d2edaa 100644 --- a/vl.c +++ b/vl.c @@ -534,7 +534,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, @@ -569,7 +569,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, @@ -1951,7 +1951,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_wakeup_requested()) { -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- Regards, Hu Tao -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v12 rebased 1/8] preserve cpu runstate
On Thu, Feb 07, 2013 at 11:45:34PM -0200, Marcelo Tosatti wrote: > On Wed, Jan 23, 2013 at 03:19:22PM +0800, Hu Tao wrote: > > This patch enables preservation of cpu runstate during save/load vm. > > So when a vm is restored from snapshot, the cpu runstate is restored, > > too. > > > > See following example: > > > > # save two vms: one is running, the other is paused > > (qemu) info status > > VM status: running > > (qemu) savevm running > > (qemu) stop > > (qemu) info status > > VM status: paused > > (qemu) savevm paused > > > > # restore the one running > > (qemu) info status > > VM status: paused > > (qemu) loadvm running > > (qemu) info status > > VM status: running > > > > # restore the one paused > > (qemu) loadvm paused > > (qemu) info status > > VM status: paused > > (qemu) cont > > (qemu)info status > > VM status: running > > > > > > Signed-off-by: Hu Tao > > Lack of pause state on guest images is annoying. > > Fail to see why the panic feature depends on preservation of cpu > runstate. To preserve the panic state if guest panic happens in the midway of migration. > > > include/sysemu/sysemu.h | 2 ++ > > migration.c | 6 +- > > monitor.c | 5 ++--- > > savevm.c| 1 + > > vl.c| 34 ++ > > 5 files changed, 40 insertions(+), 8 deletions(-) > > > > diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h > > index 337ce7d..7a69fde 100644 > > --- a/include/sysemu/sysemu.h > > +++ b/include/sysemu/sysemu.h > > @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; > > int qemu_uuid_parse(const char *str, uint8_t *uuid); > > #define UUID_FMT > > "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" > > > > +void save_run_state(void); > > +void load_run_state(void); > > bool runstate_check(RunState state); > > void runstate_set(RunState new_state); > > int runstate_is_running(void); > > diff --git a/migration.c b/migration.c > > index 77c1971..f96cfd6 100644 > > --- a/migration.c > > +++ b/migration.c > > @@ -108,11 +108,7 @@ static void process_incoming_migration_co(void *opaque) > > /* Make sure all file formats flush their mutable metadata */ > > bdrv_invalidate_cache_all(); > > > > -if (autostart) { > > -vm_start(); > > -} else { > > -runstate_set(RUN_STATE_PAUSED); > > -} > > +load_run_state(); > > } > > > > static void enter_migration_coroutine(void *opaque) > > diff --git a/monitor.c b/monitor.c > > index 20bd19b..9381ed0 100644 > > --- a/monitor.c > > +++ b/monitor.c > > @@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp) > > > > static void do_loadvm(Monitor *mon, const QDict *qdict) > > { > > -int saved_vm_running = runstate_is_running(); > > const char *name = qdict_get_str(qdict, "name"); > > > > vm_stop(RUN_STATE_RESTORE_VM); > > > > -if (load_vmstate(name) == 0 && saved_vm_running) { > > -vm_start(); > > +if (load_vmstate(name) == 0) { > > +load_run_state(); > > } > > } > > > > diff --git a/savevm.c b/savevm.c > > index 304d1ef..10f1d56 100644 > > --- a/savevm.c > > +++ b/savevm.c > > @@ -2112,6 +2112,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) > > } > > > > saved_vm_running = runstate_is_running(); > > +save_run_state(); > > vm_stop(RUN_STATE_SAVE_VM); > > > > memset(sn, 0, sizeof(*sn)); > > diff --git a/vl.c b/vl.c > > index 4ee1302..b0bcf1e 100644 > > --- a/vl.c > > +++ b/vl.c > > @@ -520,6 +520,7 @@ static int default_driver_check(QemuOpts *opts, void > > *opaque) > > /* QEMU state */ > > > > static RunState current_run_state = RUN_STATE_PRELAUNCH; > > +static RunState saved_run_state = RUN_STATE_PRELAUNCH; > > > > typedef struct { > > RunState from; > > @@ -543,6 +544,7 @@ static const RunStateTransition > > runstate_transitions_def[] = { > > { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, > > > > { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, > > +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, > > { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, &g
Re: [PATCH v12 rebased 1/8] preserve cpu runstate
On Thu, Feb 07, 2013 at 11:45:34PM -0200, Marcelo Tosatti wrote: On Wed, Jan 23, 2013 at 03:19:22PM +0800, Hu Tao wrote: This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too. See following example: # save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused # restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running # restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running Signed-off-by: Hu Tao hu...@cn.fujitsu.com Lack of pause state on guest images is annoying. Fail to see why the panic feature depends on preservation of cpu runstate. To preserve the panic state if guest panic happens in the midway of migration. include/sysemu/sysemu.h | 2 ++ migration.c | 6 +- monitor.c | 5 ++--- savevm.c| 1 + vl.c| 34 ++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 337ce7d..7a69fde 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT %02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx +void save_run_state(void); +void load_run_state(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/migration.c b/migration.c index 77c1971..f96cfd6 100644 --- a/migration.c +++ b/migration.c @@ -108,11 +108,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); -if (autostart) { -vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); -} +load_run_state(); } static void enter_migration_coroutine(void *opaque) diff --git a/monitor.c b/monitor.c index 20bd19b..9381ed0 100644 --- a/monitor.c +++ b/monitor.c @@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp) static void do_loadvm(Monitor *mon, const QDict *qdict) { -int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, name); vm_stop(RUN_STATE_RESTORE_VM); -if (load_vmstate(name) == 0 saved_vm_running) { -vm_start(); +if (load_vmstate(name) == 0) { +load_run_state(); } } diff --git a/savevm.c b/savevm.c index 304d1ef..10f1d56 100644 --- a/savevm.c +++ b/savevm.c @@ -2112,6 +2112,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); +save_run_state(); vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/vl.c b/vl.c index 4ee1302..b0bcf1e 100644 --- a/vl.c +++ b/vl.c @@ -520,6 +520,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque) /* QEMU state */ static RunState current_run_state = RUN_STATE_PRELAUNCH; +static RunState saved_run_state = RUN_STATE_PRELAUNCH; typedef struct { RunState from; @@ -543,6 +544,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, @@ -553,6 +555,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -582,11 +585,39 @@ static const RunStateTransition runstate_transitions_def[] = { static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +void save_run_state(void) +{ +saved_run_state = current_run_state; +} + +void load_run_state(void) +{ +if (saved_run_state == RUN_STATE_RUNNING) { +vm_start(); +} else if (!runstate_check(saved_run_state)) { +runstate_set(saved_run_state); +} else { +; /* leave unchanged */ +} +} + bool runstate_check(RunState state) { return current_run_state
[PATCH v12 rebased 3/8] update kernel headers
update kernel headers to add pv event macros. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ 2 files changed, 7 insertions(+) diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index a1c3d72..781959a 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -96,5 +96,6 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index 7bdcf93..f6be0bb 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 + /* * hypercalls use architecture specific */ -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased] kvm: notify host when the guest is panicked
We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- arch/ia64/kvm/irq.h | 19 + arch/powerpc/include/asm/kvm_para.h | 18 arch/s390/include/asm/kvm_para.h | 19 + arch/x86/include/asm/kvm_para.h | 20 ++ arch/x86/include/uapi/asm/kvm_para.h | 2 ++ arch/x86/kernel/kvm.c| 53 include/linux/kvm_para.h | 18 include/uapi/linux/kvm_para.h| 6 kernel/panic.c | 4 +++ 9 files changed, 159 insertions(+) diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h index c0785a7..b3870f8 100644 --- a/arch/ia64/kvm/irq.h +++ b/arch/ia64/kvm/irq.h @@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm) return 1; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index 2b11965..17dd013 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -144,4 +144,22 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index e0f8423..81d87ec 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,4 +154,23 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif /* __S390_KVM_PARA_H */ diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 5ed1f161..c3f2ca8 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -133,4 +133,24 @@ static inline void kvm_disable_steal_time(void) } #endif +static inline int kvm_arch_pv_event_init(void) +{ + if (!request_region(KVM_PV_EVENT_PORT, 4, "KVM_PV_EVENT")) + return -1; + + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return inl(KVM_PV_EVENT_PORT); +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ + outl(event, KVM_PV_EVENT_PORT); +} + +bool kvm_arch_pv_event_enabled(void); + #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 06fdbd9..c15ef33 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) + #endif /* _UAPI_ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 9c2bd8b..0aa7b3e 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -73,6 +73,20 @@ static int parse_no_kvmclock_vsyscall(char *arg) early_param("no-kvmclock-vsyscall", parse_no_kvmclock_vsyscall); +static int pv_event = 1; +static int parse_no_pv_event(char *arg) +{ + pv_event = 0; + return 0; +} + +bool kvm_arch_pv_event_enabled(void) +{ + return !!pv_event; +} + +early_param("no-pv-event", parse_no_pv_event); + static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64); static int has_steal_clock = 0; @@ -385,6 +399,17 @@ static struct n
[PATCH v12 rebased 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
The guest will be in this state when it is panicked. If guest is panicked during live migration, the runstate RUN_STATE_GUEST_PANICKED will be transferred to dest machine. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- migration.c | 1 + qapi-schema.json | 6 +- qmp.c| 3 ++- vl.c | 11 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/migration.c b/migration.c index f96cfd6..2b51913 100644 --- a/migration.c +++ b/migration.c @@ -705,6 +705,7 @@ static void *buffered_file_thread(void *opaque) int64_t start_time, end_time; DPRINTF("done iterating\n"); +save_run_state(); start_time = qemu_get_clock_ms(rt_clock); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); if (old_vm_running) { diff --git a/qapi-schema.json b/qapi-schema.json index 6d7252b..b49094b 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -174,11 +174,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @SnapshotInfo diff --git a/qmp.c b/qmp.c index 5f1bed1..f5027f6 100644 --- a/qmp.c +++ b/qmp.c @@ -150,7 +150,8 @@ void qmp_cont(Error **errp) Error *local_err = NULL; if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index 1d2edaa..5aae03f 100644 --- a/vl.c +++ b/vl.c @@ -533,6 +533,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, @@ -546,6 +547,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, @@ -556,6 +558,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -566,6 +569,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -580,6 +584,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, }; @@ -1950,7 +1958,8 @@ static bool main_loop_should_exit(void) qemu_system_reset(VMRESET_REPORT); resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || -runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { bdrv_iterate(iostatus_bdrv_it, NULL); vm_start(); } -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 7/8] allower the user to disable pv event support
Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- hw/pc_piix.c| 9 - qemu-options.hx | 3 ++- vl.c| 4 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index fed6ccf..507c98b 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -44,6 +44,7 @@ #include "exec/memory.h" #include "exec/address-spaces.h" #include "cpu.h" +#include "qemu/config-file.h" #ifdef CONFIG_XEN # include #endif @@ -86,6 +87,8 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; +QemuOptsList *list = qemu_find_opts("machine"); +bool enable_pv_event = false; pc_cpus_init(cpu_model); pc_acpi_init("acpi-dsdt.aml"); @@ -218,7 +221,11 @@ static void pc_init1(MemoryRegion *system_memory, pc_pci_device_init(pci_bus); } -if (kvm_enabled()) { +if (list && !QTAILQ_EMPTY(>head)) { +enable_pv_event = qemu_opt_get_bool(QTAILQ_FIRST(>head), +"enable_pv_event", false); +} +if (kvm_enabled() && enable_pv_event) { kvm_pv_event_init(isa_bus); } } diff --git a/qemu-options.hx b/qemu-options.hx index 4e2b499..7522f4a 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -35,7 +35,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ "kernel_irqchip=on|off controls accelerated irqchip support\n" "kvm_shadow_mem=size of KVM shadow MMU\n" "dump-guest-core=on|off include guest memory in a core dump (default=on)\n" -"mem-merge=on|off controls memory merge support (default: on)\n", +"mem-merge=on|off controls memory merge support (default: on)\n" +"enable_pv_event=on|off controls pv event support (default: off)\n", QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] diff --git a/vl.c b/vl.c index 5aae03f..aa15b23 100644 --- a/vl.c +++ b/vl.c @@ -424,6 +424,10 @@ static QemuOptsList qemu_machine_opts = { .name = "usb", .type = QEMU_OPT_BOOL, .help = "Set on/off to enable/disable usb", +}, { +.name = "enable_pv_event", +.type = QEMU_OPT_BOOL, +.help = "handle pv event" }, { /* End of list */ } }, -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 5/8] add a new qevent: QEVENT_GUEST_PANICKED
This event will be emited when the guest is panicked. Signed-off-by: Wen Congyang --- include/monitor/monitor.h | 1 + monitor.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 87fb49c..4006905 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -45,6 +45,7 @@ typedef enum MonitorEvent { QEVENT_WAKEUP, QEVENT_BALLOON_CHANGE, QEVENT_SPICE_MIGRATE_COMPLETED, +QEVENT_GUEST_PANICKED, /* Add to 'monitor_event_names' array in monitor.c when * defining new events here */ diff --git a/monitor.c b/monitor.c index 9381ed0..61beeb4 100644 --- a/monitor.c +++ b/monitor.c @@ -463,6 +463,7 @@ static const char *monitor_event_names[] = { [QEVENT_WAKEUP] = "WAKEUP", [QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE", [QEVENT_SPICE_MIGRATE_COMPLETED] = "SPICE_MIGRATE_COMPLETED", +[QEVENT_GUEST_PANICKED] = "GUEST_PANICKED", }; QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 0/8] pv event to notify host when the guest is panicked
This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. Also, the cpu runstate is preserved during save/load vm and migration. Thus, if vm is panicked during migration, we can still know it by quring the status of vm in destination host. This version is a rebase and no code change. v12: http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg01459.html v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 12 +++ include/block/block.h| 2 + include/monitor/monitor.h| 1 + include/sysemu/kvm.h | 2 + include/sysemu/sysemu.h | 2 + kvm-stub.c | 4 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- qapi-schema.json | 6 +- qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + vl.c | 56 ++- 18 files changed, 313 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 6/8] introduce a new qom device to deal with panicked event
If the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target. Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 5 ++ include/sysemu/kvm.h | 2 + kvm-stub.c | 4 ++ 5 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 hw/kvm/pv_event.c diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs index f620d7f..cf93199 100644 --- a/hw/kvm/Makefile.objs +++ b/hw/kvm/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o pv_event.o diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c new file mode 100644 index 000..f32f82e --- /dev/null +++ b/hw/kvm/pv_event.c @@ -0,0 +1,197 @@ +/* + * QEMU KVM support, paravirtual event device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +#define PV_EVENT_DRIVER "kvm_pv_event" + +struct PVEventAction { +char *panicked_action; +int panicked_action_value; +}; + +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \ +DEFINE_PROP_STRING("panicked_action", _state, _conf.panicked_action) + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf("{ 'action': %s }", action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(uint32_t panicked_action) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event("report"); +break; + +case PANICKED_PAUSE: +panicked_mon_event("pause"); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event("poweroff"); +qemu_system_shutdown_request(); +break; + +case PANICKED_RESET: +panicked_mon_event("reset"); +qemu_system_reset_request(); +break; +} +} + +static uint64_t supported_event(void) +{ +return 1 << KVM_PV_FEATURE_PANICKED; +} + +static void handle_event(int event, struct PVEventAction *conf) +{ +if (event == KVM_PV_EVENT_PANICKED) { +panicked_perform_action(conf->panicked_action_value); +} +} + +static int pv_event_init(struct PVEventAction *conf) +{ +if (!conf->panicked_action) { +conf->panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf->panicked_action, "none") == 0) { +conf->panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf->panicked_action, "pause") == 0) { +conf->panicked_action_value = PANICKED_PAUSE; +} else if (strcasecmp(conf->panicked_action, "poweroff") == 0) { +conf->panicked_action_value = PANICKED_POWEROFF; +} else if (strcasecmp(conf->panicked_action, "reset") == 0) { +conf->panicked_action_value = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} + +#if defined(KVM_PV_EVENT_PORT) + +#include "hw/isa.h" + +typedef struct { +ISADevice dev; +struct PVEventAction conf; +MemoryRegion ioport; +} PVIOPortState; + +static uint64_t pv_io_read(void *opaque, hwaddr addr, unsigned size) +{ +return supported_event(); +} + +static void pv_io_write(void *opaque, hwaddr addr, uint64_t val, +unsigned size) +{ +PVIOPortStat
[PATCH v12 rebased 8/8] pv event: add document to describe the usage
Signed-off-by: Hu Tao --- docs/pv-event.txt | 17 + 1 file changed, 17 insertions(+) create mode 100644 docs/pv-event.txt diff --git a/docs/pv-event.txt b/docs/pv-event.txt new file mode 100644 index 000..ac9e7fa --- /dev/null +++ b/docs/pv-event.txt @@ -0,0 +1,17 @@ +KVM PV EVENT + + +kvm pv event allows guest OS to notify host OS of some events, for +example, guest panic. Currently, there is one event supported, that +is, guest panic. More events can be added later. + +By default, kvm pv event is disabled. In order to enable it, you have +to specify enable_pv_event=on for -machine command line option, along +with -global kvm_pv_event.panicked_action to specify the action taken +when panic event has occurred. Aviable panic actions are: "none", +"pause", "poweroff" and "reset". Following is example: + + qemu-system-x86_64 -enable-kvm -machine pc-0.12,enable_pv_event=on \ +-global kvm_pv_event.panicked_action=pause + +kvm pv event needs kvm support. -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 2/8] start vm after resetting it
From: Wen Congyang The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). Signed-off-by: Wen Congyang --- include/block/block.h | 2 ++ qmp.c | 2 +- vl.c | 7 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index ffd1936..5e82ccb 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -366,6 +366,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + #ifdef CONFIG_LINUX_AIO int raw_get_aio_fd(BlockDriverState *bs); #else diff --git a/qmp.c b/qmp.c index 55b056b..5f1bed1 100644 --- a/qmp.c +++ b/qmp.c @@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index b0bcf1e..1d2edaa 100644 --- a/vl.c +++ b/vl.c @@ -534,7 +534,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, @@ -569,7 +569,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, @@ -1951,7 +1951,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_wakeup_requested()) { -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 1/8] preserve cpu runstate
This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too. See following example: # save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused # restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running # restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running Signed-off-by: Hu Tao --- include/sysemu/sysemu.h | 2 ++ migration.c | 6 +- monitor.c | 5 ++--- savevm.c| 1 + vl.c| 34 ++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 337ce7d..7a69fde 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +void save_run_state(void); +void load_run_state(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/migration.c b/migration.c index 77c1971..f96cfd6 100644 --- a/migration.c +++ b/migration.c @@ -108,11 +108,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); -if (autostart) { -vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); -} +load_run_state(); } static void enter_migration_coroutine(void *opaque) diff --git a/monitor.c b/monitor.c index 20bd19b..9381ed0 100644 --- a/monitor.c +++ b/monitor.c @@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp) static void do_loadvm(Monitor *mon, const QDict *qdict) { -int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, "name"); vm_stop(RUN_STATE_RESTORE_VM); -if (load_vmstate(name) == 0 && saved_vm_running) { -vm_start(); +if (load_vmstate(name) == 0) { +load_run_state(); } } diff --git a/savevm.c b/savevm.c index 304d1ef..10f1d56 100644 --- a/savevm.c +++ b/savevm.c @@ -2112,6 +2112,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); +save_run_state(); vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/vl.c b/vl.c index 4ee1302..b0bcf1e 100644 --- a/vl.c +++ b/vl.c @@ -520,6 +520,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque) /* QEMU state */ static RunState current_run_state = RUN_STATE_PRELAUNCH; +static RunState saved_run_state = RUN_STATE_PRELAUNCH; typedef struct { RunState from; @@ -543,6 +544,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, @@ -553,6 +555,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -582,11 +585,39 @@ static const RunStateTransition runstate_transitions_def[] = { static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +void save_run_state(void) +{ +saved_run_state = current_run_state; +} + +void load_run_state(void) +{ +if (saved_run_state == RUN_STATE_RUNNING) { +vm_start(); +} else if (!runstate_check(saved_run_state)) { +runstate_set(saved_run_state); +} else { +; /* leave unchanged */ +} +} + bool runstate_check(RunState state) { return current_run_state == state; } +static void runstate_save(QEMUFile *f, void *opaque) +{ +qemu_put_byte(f, saved_run_state); +} + +static int runstate_load(QEMUFile *f, void *opaque, int version_id) +{ +saved_run_state = qemu_get_byte(f); + +return 0; +} + static void runstate_init(void) { const RunStateTransition *p; @@ -596,6 +627,9 @@ static void runstate_init(void) for (p = _transitions_def[0]; p->from != RUN_STATE_MAX; p++) { runstate_valid_transitions[p->from][p->to] = true; } + +register_savevm(NULL, "runstate", 0, 1, +runstate_save, runstate_load, NULL);
[PATCH v12 rebased 1/8] preserve cpu runstate
This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too. See following example: # save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused # restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running # restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- include/sysemu/sysemu.h | 2 ++ migration.c | 6 +- monitor.c | 5 ++--- savevm.c| 1 + vl.c| 34 ++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 337ce7d..7a69fde 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT %02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx +void save_run_state(void); +void load_run_state(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/migration.c b/migration.c index 77c1971..f96cfd6 100644 --- a/migration.c +++ b/migration.c @@ -108,11 +108,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); -if (autostart) { -vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); -} +load_run_state(); } static void enter_migration_coroutine(void *opaque) diff --git a/monitor.c b/monitor.c index 20bd19b..9381ed0 100644 --- a/monitor.c +++ b/monitor.c @@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp) static void do_loadvm(Monitor *mon, const QDict *qdict) { -int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, name); vm_stop(RUN_STATE_RESTORE_VM); -if (load_vmstate(name) == 0 saved_vm_running) { -vm_start(); +if (load_vmstate(name) == 0) { +load_run_state(); } } diff --git a/savevm.c b/savevm.c index 304d1ef..10f1d56 100644 --- a/savevm.c +++ b/savevm.c @@ -2112,6 +2112,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); +save_run_state(); vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/vl.c b/vl.c index 4ee1302..b0bcf1e 100644 --- a/vl.c +++ b/vl.c @@ -520,6 +520,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque) /* QEMU state */ static RunState current_run_state = RUN_STATE_PRELAUNCH; +static RunState saved_run_state = RUN_STATE_PRELAUNCH; typedef struct { RunState from; @@ -543,6 +544,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, @@ -553,6 +555,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -582,11 +585,39 @@ static const RunStateTransition runstate_transitions_def[] = { static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +void save_run_state(void) +{ +saved_run_state = current_run_state; +} + +void load_run_state(void) +{ +if (saved_run_state == RUN_STATE_RUNNING) { +vm_start(); +} else if (!runstate_check(saved_run_state)) { +runstate_set(saved_run_state); +} else { +; /* leave unchanged */ +} +} + bool runstate_check(RunState state) { return current_run_state == state; } +static void runstate_save(QEMUFile *f, void *opaque) +{ +qemu_put_byte(f, saved_run_state); +} + +static int runstate_load(QEMUFile *f, void *opaque, int version_id) +{ +saved_run_state = qemu_get_byte(f); + +return 0; +} + static void runstate_init(void) { const RunStateTransition *p; @@ -596,6 +627,9 @@ static void runstate_init(void) for (p = runstate_transitions_def[0]; p-from != RUN_STATE_MAX; p++) { runstate_valid_transitions[p-from][p-to] = true; } + +register_savevm(NULL, runstate, 0, 1, +runstate_save, runstate_load, NULL); } /* This function
[PATCH v12 rebased 2/8] start vm after resetting it
From: Wen Congyang we...@cn.fujitsu.com The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- include/block/block.h | 2 ++ qmp.c | 2 +- vl.c | 7 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index ffd1936..5e82ccb 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -366,6 +366,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + #ifdef CONFIG_LINUX_AIO int raw_get_aio_fd(BlockDriverState *bs); #else diff --git a/qmp.c b/qmp.c index 55b056b..5f1bed1 100644 --- a/qmp.c +++ b/qmp.c @@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index b0bcf1e..1d2edaa 100644 --- a/vl.c +++ b/vl.c @@ -534,7 +534,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, @@ -569,7 +569,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, @@ -1951,7 +1951,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_wakeup_requested()) { -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 6/8] introduce a new qom device to deal with panicked event
If the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target. Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 5 ++ include/sysemu/kvm.h | 2 + kvm-stub.c | 4 ++ 5 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 hw/kvm/pv_event.c diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs index f620d7f..cf93199 100644 --- a/hw/kvm/Makefile.objs +++ b/hw/kvm/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o pv_event.o diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c new file mode 100644 index 000..f32f82e --- /dev/null +++ b/hw/kvm/pv_event.c @@ -0,0 +1,197 @@ +/* + * QEMU KVM support, paravirtual event device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang we...@cn.fujitsu.com + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include linux/kvm_para.h +#include asm/kvm_para.h +#include qapi/qmp/qobject.h +#include qapi/qmp/qjson.h +#include monitor/monitor.h +#include sysemu/sysemu.h +#include sysemu/kvm.h + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +#define PV_EVENT_DRIVER kvm_pv_event + +struct PVEventAction { +char *panicked_action; +int panicked_action_value; +}; + +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \ +DEFINE_PROP_STRING(panicked_action, _state, _conf.panicked_action) + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf({ 'action': %s }, action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(uint32_t panicked_action) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event(report); +break; + +case PANICKED_PAUSE: +panicked_mon_event(pause); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event(poweroff); +qemu_system_shutdown_request(); +break; + +case PANICKED_RESET: +panicked_mon_event(reset); +qemu_system_reset_request(); +break; +} +} + +static uint64_t supported_event(void) +{ +return 1 KVM_PV_FEATURE_PANICKED; +} + +static void handle_event(int event, struct PVEventAction *conf) +{ +if (event == KVM_PV_EVENT_PANICKED) { +panicked_perform_action(conf-panicked_action_value); +} +} + +static int pv_event_init(struct PVEventAction *conf) +{ +if (!conf-panicked_action) { +conf-panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf-panicked_action, none) == 0) { +conf-panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf-panicked_action, pause) == 0) { +conf-panicked_action_value = PANICKED_PAUSE; +} else if (strcasecmp(conf-panicked_action, poweroff) == 0) { +conf-panicked_action_value = PANICKED_POWEROFF; +} else if (strcasecmp(conf-panicked_action, reset) == 0) { +conf-panicked_action_value = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} + +#if defined(KVM_PV_EVENT_PORT) + +#include hw/isa.h + +typedef struct { +ISADevice dev; +struct PVEventAction conf; +MemoryRegion ioport; +} PVIOPortState; + +static uint64_t pv_io_read(void *opaque, hwaddr addr, unsigned size) +{ +return supported_event(); +} + +static void pv_io_write(void *opaque, hwaddr addr, uint64_t val, +unsigned size) +{ +PVIOPortState *s = opaque; + +handle_event(val, s-conf
[PATCH v12 rebased 8/8] pv event: add document to describe the usage
Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- docs/pv-event.txt | 17 + 1 file changed, 17 insertions(+) create mode 100644 docs/pv-event.txt diff --git a/docs/pv-event.txt b/docs/pv-event.txt new file mode 100644 index 000..ac9e7fa --- /dev/null +++ b/docs/pv-event.txt @@ -0,0 +1,17 @@ +KVM PV EVENT + + +kvm pv event allows guest OS to notify host OS of some events, for +example, guest panic. Currently, there is one event supported, that +is, guest panic. More events can be added later. + +By default, kvm pv event is disabled. In order to enable it, you have +to specify enable_pv_event=on for -machine command line option, along +with -global kvm_pv_event.panicked_action to specify the action taken +when panic event has occurred. Aviable panic actions are: none, +pause, poweroff and reset. Following is example: + + qemu-system-x86_64 -enable-kvm -machine pc-0.12,enable_pv_event=on \ +-global kvm_pv_event.panicked_action=pause other options + +kvm pv event needs kvm support. -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 0/8] pv event to notify host when the guest is panicked
This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. Also, the cpu runstate is preserved during save/load vm and migration. Thus, if vm is panicked during migration, we can still know it by quring the status of vm in destination host. This version is a rebase and no code change. v12: http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg01459.html v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 12 +++ include/block/block.h| 2 + include/monitor/monitor.h| 1 + include/sysemu/kvm.h | 2 + include/sysemu/sysemu.h | 2 + kvm-stub.c | 4 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- qapi-schema.json | 6 +- qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + vl.c | 56 ++- 18 files changed, 313 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 7/8] allower the user to disable pv event support
Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- hw/pc_piix.c| 9 - qemu-options.hx | 3 ++- vl.c| 4 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index fed6ccf..507c98b 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -44,6 +44,7 @@ #include exec/memory.h #include exec/address-spaces.h #include cpu.h +#include qemu/config-file.h #ifdef CONFIG_XEN # include xen/hvm/hvm_info_table.h #endif @@ -86,6 +87,8 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; +QemuOptsList *list = qemu_find_opts(machine); +bool enable_pv_event = false; pc_cpus_init(cpu_model); pc_acpi_init(acpi-dsdt.aml); @@ -218,7 +221,11 @@ static void pc_init1(MemoryRegion *system_memory, pc_pci_device_init(pci_bus); } -if (kvm_enabled()) { +if (list !QTAILQ_EMPTY(list-head)) { +enable_pv_event = qemu_opt_get_bool(QTAILQ_FIRST(list-head), +enable_pv_event, false); +} +if (kvm_enabled() enable_pv_event) { kvm_pv_event_init(isa_bus); } } diff --git a/qemu-options.hx b/qemu-options.hx index 4e2b499..7522f4a 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -35,7 +35,8 @@ DEF(machine, HAS_ARG, QEMU_OPTION_machine, \ kernel_irqchip=on|off controls accelerated irqchip support\n kvm_shadow_mem=size of KVM shadow MMU\n dump-guest-core=on|off include guest memory in a core dump (default=on)\n -mem-merge=on|off controls memory merge support (default: on)\n, +mem-merge=on|off controls memory merge support (default: on)\n +enable_pv_event=on|off controls pv event support (default: off)\n, QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] diff --git a/vl.c b/vl.c index 5aae03f..aa15b23 100644 --- a/vl.c +++ b/vl.c @@ -424,6 +424,10 @@ static QemuOptsList qemu_machine_opts = { .name = usb, .type = QEMU_OPT_BOOL, .help = Set on/off to enable/disable usb, +}, { +.name = enable_pv_event, +.type = QEMU_OPT_BOOL, +.help = handle pv event }, { /* End of list */ } }, -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 5/8] add a new qevent: QEVENT_GUEST_PANICKED
This event will be emited when the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- include/monitor/monitor.h | 1 + monitor.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 87fb49c..4006905 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -45,6 +45,7 @@ typedef enum MonitorEvent { QEVENT_WAKEUP, QEVENT_BALLOON_CHANGE, QEVENT_SPICE_MIGRATE_COMPLETED, +QEVENT_GUEST_PANICKED, /* Add to 'monitor_event_names' array in monitor.c when * defining new events here */ diff --git a/monitor.c b/monitor.c index 9381ed0..61beeb4 100644 --- a/monitor.c +++ b/monitor.c @@ -463,6 +463,7 @@ static const char *monitor_event_names[] = { [QEVENT_WAKEUP] = WAKEUP, [QEVENT_BALLOON_CHANGE] = BALLOON_CHANGE, [QEVENT_SPICE_MIGRATE_COMPLETED] = SPICE_MIGRATE_COMPLETED, +[QEVENT_GUEST_PANICKED] = GUEST_PANICKED, }; QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
The guest will be in this state when it is panicked. If guest is panicked during live migration, the runstate RUN_STATE_GUEST_PANICKED will be transferred to dest machine. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- migration.c | 1 + qapi-schema.json | 6 +- qmp.c| 3 ++- vl.c | 11 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/migration.c b/migration.c index f96cfd6..2b51913 100644 --- a/migration.c +++ b/migration.c @@ -705,6 +705,7 @@ static void *buffered_file_thread(void *opaque) int64_t start_time, end_time; DPRINTF(done iterating\n); +save_run_state(); start_time = qemu_get_clock_ms(rt_clock); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); if (old_vm_running) { diff --git a/qapi-schema.json b/qapi-schema.json index 6d7252b..b49094b 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -174,11 +174,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @SnapshotInfo diff --git a/qmp.c b/qmp.c index 5f1bed1..f5027f6 100644 --- a/qmp.c +++ b/qmp.c @@ -150,7 +150,8 @@ void qmp_cont(Error **errp) Error *local_err = NULL; if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index 1d2edaa..5aae03f 100644 --- a/vl.c +++ b/vl.c @@ -533,6 +533,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, @@ -546,6 +547,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, @@ -556,6 +558,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -566,6 +569,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -580,6 +584,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, }; @@ -1950,7 +1958,8 @@ static bool main_loop_should_exit(void) qemu_system_reset(VMRESET_REPORT); resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || -runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { bdrv_iterate(iostatus_bdrv_it, NULL); vm_start(); } -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 rebased] kvm: notify host when the guest is panicked
We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- arch/ia64/kvm/irq.h | 19 + arch/powerpc/include/asm/kvm_para.h | 18 arch/s390/include/asm/kvm_para.h | 19 + arch/x86/include/asm/kvm_para.h | 20 ++ arch/x86/include/uapi/asm/kvm_para.h | 2 ++ arch/x86/kernel/kvm.c| 53 include/linux/kvm_para.h | 18 include/uapi/linux/kvm_para.h| 6 kernel/panic.c | 4 +++ 9 files changed, 159 insertions(+) diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h index c0785a7..b3870f8 100644 --- a/arch/ia64/kvm/irq.h +++ b/arch/ia64/kvm/irq.h @@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm) return 1; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index 2b11965..17dd013 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -144,4 +144,22 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index e0f8423..81d87ec 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,4 +154,23 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif /* __S390_KVM_PARA_H */ diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 5ed1f161..c3f2ca8 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -133,4 +133,24 @@ static inline void kvm_disable_steal_time(void) } #endif +static inline int kvm_arch_pv_event_init(void) +{ + if (!request_region(KVM_PV_EVENT_PORT, 4, KVM_PV_EVENT)) + return -1; + + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return inl(KVM_PV_EVENT_PORT); +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ + outl(event, KVM_PV_EVENT_PORT); +} + +bool kvm_arch_pv_event_enabled(void); + #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 06fdbd9..c15ef33 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) + #endif /* _UAPI_ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 9c2bd8b..0aa7b3e 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -73,6 +73,20 @@ static int parse_no_kvmclock_vsyscall(char *arg) early_param(no-kvmclock-vsyscall, parse_no_kvmclock_vsyscall); +static int pv_event = 1; +static int parse_no_pv_event(char *arg) +{ + pv_event = 0; + return 0; +} + +bool kvm_arch_pv_event_enabled(void) +{ + return !!pv_event; +} + +early_param(no-pv-event, parse_no_pv_event); + static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64); static int has_steal_clock = 0; @@ -385,6 +399,17 @@ static struct
[PATCH v12 rebased 3/8] update kernel headers
update kernel headers to add pv event macros. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ 2 files changed, 7 insertions(+) diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index a1c3d72..781959a 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -96,5 +96,6 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index 7bdcf93..f6be0bb 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 + /* * hypercalls use architecture specific */ -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Qemu-devel] [PATCH v12 0/8] pv event to notify host when the guest is panicked
On Tue, Dec 25, 2012 at 07:54:20PM -0200, Marcelo Tosatti wrote: > On Thu, Dec 20, 2012 at 03:53:59PM +0800, Hu Tao wrote: > > Hi, > > > > Any comments? > > Did you verify possibilities listed at > https://lkml.org/lkml/2012/11/20/653 ? Except the EIO one you mentioned. I don't know how to reproduce it. > > If so, a summary in the patchset would be helpful. Thanks for reminding, I'll add it in the next version. Basically, the run state is saved and loaded again so we can know the state when restoring a vm. This is done by patch #1, and is independent of guest panic. Can you have a review of patch #1 before next version? > > > On Wed, Dec 12, 2012 at 02:13:43PM +0800, Hu Tao wrote: > > > This series implements a new interface, kvm pv event, to notify host when > > > some events happen in guest. Right now there is one supported event: guest > > > panic. > > > > > > changes from v11: > > > > > > - add a new patch 'save/load cpu runstate' > > > - fix a bug of null-dereference when no -machine option is supplied > > > - reserve RUN_STATE_GUEST_PANICKED during migration > > > - add doc of enable_pv_event option > > > - disable reboot-on-panic if pv_event is on > > > > > > v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html > > > > > > Hu Tao (7): > > > save/load cpu runstate > > > update kernel headers > > > add a new runstate: RUN_STATE_GUEST_PANICKED > > > add a new qevent: QEVENT_GUEST_PANICKED > > > introduce a new qom device to deal with panicked event > > > allower the user to disable pv event support > > > pv event: add document to describe the usage > > > > > > Wen Congyang (1): > > > start vm after resetting it > > > > > > block.h | 2 + > > > docs/pv-event.txt| 17 > > > hw/kvm/Makefile.objs | 2 +- > > > hw/kvm/pv_event.c| 197 > > > +++ > > > hw/pc_piix.c | 11 +++ > > > kvm-stub.c | 4 + > > > kvm.h| 2 + > > > linux-headers/asm-x86/kvm_para.h | 1 + > > > linux-headers/linux/kvm_para.h | 6 ++ > > > migration.c | 7 +- > > > monitor.c| 6 +- > > > monitor.h| 1 + > > > qapi-schema.json | 6 +- > > > qemu-config.c| 4 + > > > qemu-options.hx | 3 +- > > > qmp.c| 5 +- > > > savevm.c | 1 + > > > sysemu.h | 2 + > > > vl.c | 52 ++- > > > 19 files changed, 312 insertions(+), 17 deletions(-) > > > create mode 100644 docs/pv-event.txt > > > create mode 100644 hw/kvm/pv_event.c > > > > > > -- > > > 1.8.0.1.240.ge8a1f5a > > -- > > To unsubscribe from this list: send the line "unsubscribe kvm" in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Qemu-devel] [PATCH v12 0/8] pv event to notify host when the guest is panicked
Hi Marcelo, Sorry for the late reply. On Tue, Dec 25, 2012 at 07:52:05PM -0200, Marcelo Tosatti wrote: > On Thu, Dec 20, 2012 at 03:53:59PM +0800, Hu Tao wrote: > > Hi, > > > > Any comments? > > As far as i can see, items 2 and 3 of > > https://lkml.org/lkml/2012/11/12/588 > > Have not been addressed. > > https://lkml.org/lkml/2012/11/20/653 contains discussions on those > items. > > 2) Format of the interface for other architectures (you can choose > a different KVM supported architecture and write an example). It was > your choice to choose an I/O port, which is x86 specific. Unfortunately I don't have hardware other than x86 in hand to test it. > > 3) Clear/documented management interface for the feature. Patch #8 adds a document to describe the usage of pv event. But as you are asking again, I must be misunderstanding the meaning of management interface. Can you clarify it? > > Note 3 is for management, not the guest<->host interface. > > > On Wed, Dec 12, 2012 at 02:13:43PM +0800, Hu Tao wrote: > > > This series implements a new interface, kvm pv event, to notify host when > > > some events happen in guest. Right now there is one supported event: guest > > > panic. > > > > > > changes from v11: > > > > > > - add a new patch 'save/load cpu runstate' > > > - fix a bug of null-dereference when no -machine option is supplied > > > - reserve RUN_STATE_GUEST_PANICKED during migration > > > - add doc of enable_pv_event option > > > - disable reboot-on-panic if pv_event is on > > > > > > v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html > > > > > > Hu Tao (7): > > > save/load cpu runstate > > > update kernel headers > > > add a new runstate: RUN_STATE_GUEST_PANICKED > > > add a new qevent: QEVENT_GUEST_PANICKED > > > introduce a new qom device to deal with panicked event > > > allower the user to disable pv event support > > > pv event: add document to describe the usage > > > > > > Wen Congyang (1): > > > start vm after resetting it > > > > > > block.h | 2 + > > > docs/pv-event.txt| 17 > > > hw/kvm/Makefile.objs | 2 +- > > > hw/kvm/pv_event.c| 197 > > > +++ > > > hw/pc_piix.c | 11 +++ > > > kvm-stub.c | 4 + > > > kvm.h| 2 + > > > linux-headers/asm-x86/kvm_para.h | 1 + > > > linux-headers/linux/kvm_para.h | 6 ++ > > > migration.c | 7 +- > > > monitor.c| 6 +- > > > monitor.h| 1 + > > > qapi-schema.json | 6 +- > > > qemu-config.c| 4 + > > > qemu-options.hx | 3 +- > > > qmp.c| 5 +- > > > savevm.c | 1 + > > > sysemu.h | 2 + > > > vl.c | 52 ++- > > > 19 files changed, 312 insertions(+), 17 deletions(-) > > > create mode 100644 docs/pv-event.txt > > > create mode 100644 hw/kvm/pv_event.c > > > > > > -- > > > 1.8.0.1.240.ge8a1f5a > > -- > > To unsubscribe from this list: send the line "unsubscribe kvm" in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Qemu-devel] [PATCH v12 0/8] pv event to notify host when the guest is panicked
Hi Marcelo, Sorry for the late reply. On Tue, Dec 25, 2012 at 07:52:05PM -0200, Marcelo Tosatti wrote: On Thu, Dec 20, 2012 at 03:53:59PM +0800, Hu Tao wrote: Hi, Any comments? As far as i can see, items 2 and 3 of https://lkml.org/lkml/2012/11/12/588 Have not been addressed. https://lkml.org/lkml/2012/11/20/653 contains discussions on those items. 2) Format of the interface for other architectures (you can choose a different KVM supported architecture and write an example). It was your choice to choose an I/O port, which is x86 specific. Unfortunately I don't have hardware other than x86 in hand to test it. 3) Clear/documented management interface for the feature. Patch #8 adds a document to describe the usage of pv event. But as you are asking again, I must be misunderstanding the meaning of management interface. Can you clarify it? Note 3 is for management, not the guest-host interface. On Wed, Dec 12, 2012 at 02:13:43PM +0800, Hu Tao wrote: This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. changes from v11: - add a new patch 'save/load cpu runstate' - fix a bug of null-dereference when no -machine option is supplied - reserve RUN_STATE_GUEST_PANICKED during migration - add doc of enable_pv_event option - disable reboot-on-panic if pv_event is on v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it block.h | 2 + docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 11 +++ kvm-stub.c | 4 + kvm.h| 2 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- monitor.h| 1 + qapi-schema.json | 6 +- qemu-config.c| 4 + qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + sysemu.h | 2 + vl.c | 52 ++- 19 files changed, 312 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Qemu-devel] [PATCH v12 0/8] pv event to notify host when the guest is panicked
On Tue, Dec 25, 2012 at 07:54:20PM -0200, Marcelo Tosatti wrote: On Thu, Dec 20, 2012 at 03:53:59PM +0800, Hu Tao wrote: Hi, Any comments? Did you verify possibilities listed at https://lkml.org/lkml/2012/11/20/653 ? Except the EIO one you mentioned. I don't know how to reproduce it. If so, a summary in the patchset would be helpful. Thanks for reminding, I'll add it in the next version. Basically, the run state is saved and loaded again so we can know the state when restoring a vm. This is done by patch #1, and is independent of guest panic. Can you have a review of patch #1 before next version? On Wed, Dec 12, 2012 at 02:13:43PM +0800, Hu Tao wrote: This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. changes from v11: - add a new patch 'save/load cpu runstate' - fix a bug of null-dereference when no -machine option is supplied - reserve RUN_STATE_GUEST_PANICKED during migration - add doc of enable_pv_event option - disable reboot-on-panic if pv_event is on v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it block.h | 2 + docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 11 +++ kvm-stub.c | 4 + kvm.h| 2 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- monitor.h| 1 + qapi-schema.json | 6 +- qemu-config.c| 4 + qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + sysemu.h | 2 + vl.c | 52 ++- 19 files changed, 312 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Qemu-devel] [PATCH v12 0/8] pv event to notify host when the guest is panicked
Hi, Any comments? On Wed, Dec 12, 2012 at 02:13:43PM +0800, Hu Tao wrote: > This series implements a new interface, kvm pv event, to notify host when > some events happen in guest. Right now there is one supported event: guest > panic. > > changes from v11: > > - add a new patch 'save/load cpu runstate' > - fix a bug of null-dereference when no -machine option is supplied > - reserve RUN_STATE_GUEST_PANICKED during migration > - add doc of enable_pv_event option > - disable reboot-on-panic if pv_event is on > > v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html > > Hu Tao (7): > save/load cpu runstate > update kernel headers > add a new runstate: RUN_STATE_GUEST_PANICKED > add a new qevent: QEVENT_GUEST_PANICKED > introduce a new qom device to deal with panicked event > allower the user to disable pv event support > pv event: add document to describe the usage > > Wen Congyang (1): > start vm after resetting it > > block.h | 2 + > docs/pv-event.txt| 17 > hw/kvm/Makefile.objs | 2 +- > hw/kvm/pv_event.c| 197 > +++ > hw/pc_piix.c | 11 +++ > kvm-stub.c | 4 + > kvm.h| 2 + > linux-headers/asm-x86/kvm_para.h | 1 + > linux-headers/linux/kvm_para.h | 6 ++ > migration.c | 7 +- > monitor.c| 6 +- > monitor.h| 1 + > qapi-schema.json | 6 +- > qemu-config.c| 4 + > qemu-options.hx | 3 +- > qmp.c| 5 +- > savevm.c | 1 + > sysemu.h | 2 + > vl.c | 52 ++- > 19 files changed, 312 insertions(+), 17 deletions(-) > create mode 100644 docs/pv-event.txt > create mode 100644 hw/kvm/pv_event.c > > -- > 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Qemu-devel] [PATCH v12 0/8] pv event to notify host when the guest is panicked
Hi, Any comments? On Wed, Dec 12, 2012 at 02:13:43PM +0800, Hu Tao wrote: This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. changes from v11: - add a new patch 'save/load cpu runstate' - fix a bug of null-dereference when no -machine option is supplied - reserve RUN_STATE_GUEST_PANICKED during migration - add doc of enable_pv_event option - disable reboot-on-panic if pv_event is on v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it block.h | 2 + docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 11 +++ kvm-stub.c | 4 + kvm.h| 2 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- monitor.h| 1 + qapi-schema.json | 6 +- qemu-config.c| 4 + qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + sysemu.h | 2 + vl.c | 52 ++- 19 files changed, 312 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 3/8] update kernel headers
update kernel headers to add pv event macros. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ 2 files changed, 7 insertions(+) diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index a1c3d72..781959a 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -96,5 +96,6 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index cea2c5c..c41ddce 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 + /* * hypercalls use architecture specific */ -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 1/8] save/load cpu runstate
Signed-off-by: Hu Tao --- migration.c | 6 +- monitor.c | 5 ++--- savevm.c| 1 + sysemu.h| 2 ++ vl.c| 34 ++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/migration.c b/migration.c index 73ce170..31fa300 100644 --- a/migration.c +++ b/migration.c @@ -102,11 +102,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); -if (autostart) { -vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); -} +load_run_state(); } static void enter_migration_coroutine(void *opaque) diff --git a/monitor.c b/monitor.c index c0e32d6..1226501 100644 --- a/monitor.c +++ b/monitor.c @@ -2067,13 +2067,12 @@ void qmp_closefd(const char *fdname, Error **errp) static void do_loadvm(Monitor *mon, const QDict *qdict) { -int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, "name"); vm_stop(RUN_STATE_RESTORE_VM); -if (load_vmstate(name) == 0 && saved_vm_running) { -vm_start(); +if (load_vmstate(name) == 0) { +load_run_state(); } } diff --git a/savevm.c b/savevm.c index 5d04d59..98963a4 100644 --- a/savevm.c +++ b/savevm.c @@ -2149,6 +2149,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); +save_run_state(); vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/sysemu.h b/sysemu.h index f5ac664..618f55e 100644 --- a/sysemu.h +++ b/sysemu.h @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +void save_run_state(void); +void load_run_state(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/vl.c b/vl.c index c8e9c78..6f274cc 100644 --- a/vl.c +++ b/vl.c @@ -331,6 +331,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque) /* QEMU state */ static RunState current_run_state = RUN_STATE_PRELAUNCH; +static RunState saved_run_state = RUN_STATE_PRELAUNCH; typedef struct { RunState from; @@ -354,6 +355,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, @@ -364,6 +366,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -393,11 +396,39 @@ static const RunStateTransition runstate_transitions_def[] = { static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +void save_run_state(void) +{ +saved_run_state = current_run_state; +} + +void load_run_state(void) +{ +if (saved_run_state == RUN_STATE_RUNNING) { +vm_start(); +} else if (!runstate_check(saved_run_state)) { +runstate_set(saved_run_state); +} else { +; /* leave unchanged */ +} +} + bool runstate_check(RunState state) { return current_run_state == state; } +static void runstate_save(QEMUFile *f, void *opaque) +{ +qemu_put_byte(f, saved_run_state); +} + +static int runstate_load(QEMUFile *f, void *opaque, int version_id) +{ +saved_run_state = qemu_get_byte(f); + +return 0; +} + static void runstate_init(void) { const RunStateTransition *p; @@ -407,6 +438,9 @@ static void runstate_init(void) for (p = _transitions_def[0]; p->from != RUN_STATE_MAX; p++) { runstate_valid_transitions[p->from][p->to] = true; } + +register_savevm(NULL, "runstate", 0, 1, +runstate_save, runstate_load, NULL); } /* This function will abort() on invalid state transitions */ -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] kvm: notify host when the guest is panicked
We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- arch/ia64/kvm/irq.h | 19 + arch/powerpc/include/asm/kvm_para.h | 18 + arch/s390/include/asm/kvm_para.h| 19 + arch/x86/include/asm/kvm_para.h | 23 arch/x86/kernel/kvm.c | 53 + include/linux/kvm_para.h| 18 + include/uapi/linux/kvm_para.h | 6 + kernel/panic.c | 4 +++ 8 files changed, 160 insertions(+) diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h index c0785a7..b3870f8 100644 --- a/arch/ia64/kvm/irq.h +++ b/arch/ia64/kvm/irq.h @@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm) return 1; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index 9365860..4b0e8dd 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -145,4 +145,22 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index e0f8423..81d87ec 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,4 +154,23 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif /* __S390_KVM_PARA_H */ diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index eb3e9d8..5c38429 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -96,8 +96,11 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) + #ifdef __KERNEL__ #include +#include extern void kvmclock_init(void); extern int kvm_register_clock(char *txt); @@ -228,6 +231,26 @@ static inline void kvm_disable_steal_time(void) } #endif +static inline int kvm_arch_pv_event_init(void) +{ + if (!request_region(KVM_PV_EVENT_PORT, 4, "KVM_PV_EVENT")) + return -1; + + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return inl(KVM_PV_EVENT_PORT); +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ + outl(event, KVM_PV_EVENT_PORT); +} + +bool kvm_arch_pv_event_enabled(void); + #endif /* __KERNEL__ */ #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 4180a87..c92b962 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -62,6 +62,20 @@ static int parse_no_stealacc(char *arg) early_param("no-steal-acc", parse_no_stealacc); +static int pv_event = 1; +static int parse_no_pv_event(char *arg) +{ + pv_event = 0; + return 0; +} + +bool kvm_arch_pv_event_enabled(void) +{ + return !!pv_event; +} + +early_param("no-pv-event", parse_no_pv_event); + static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64); static int has_steal_clock = 0; @@ -372,6 +386,17 @@ static struct notifier_block kvm_pv_reboot_nb = { .notifier_call = kvm_pv_reboot_notify, }; +static int +kvm_pv_panic_notify(struct notifier_block *nb, uns
[PATCH v12 5/8] add a new qevent: QEVENT_GUEST_PANICKED
This event will be emited when the guest is panicked. Signed-off-by: Wen Congyang --- monitor.c | 1 + monitor.h | 1 + 2 files changed, 2 insertions(+) diff --git a/monitor.c b/monitor.c index 1226501..231785b 100644 --- a/monitor.c +++ b/monitor.c @@ -458,6 +458,7 @@ static const char *monitor_event_names[] = { [QEVENT_WAKEUP] = "WAKEUP", [QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE", [QEVENT_SPICE_MIGRATE_COMPLETED] = "SPICE_MIGRATE_COMPLETED", +[QEVENT_GUEST_PANICKED] = "GUEST_PANICKED", }; QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) diff --git a/monitor.h b/monitor.h index b4ef955..16c1c83 100644 --- a/monitor.h +++ b/monitor.h @@ -46,6 +46,7 @@ typedef enum MonitorEvent { QEVENT_WAKEUP, QEVENT_BALLOON_CHANGE, QEVENT_SPICE_MIGRATE_COMPLETED, +QEVENT_GUEST_PANICKED, /* Add to 'monitor_event_names' array in monitor.c when * defining new events here */ -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
The guest will be in this state when it is panicked. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- migration.c | 1 + qapi-schema.json | 6 +- qmp.c| 3 ++- vl.c | 11 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/migration.c b/migration.c index 31fa300..9122dca 100644 --- a/migration.c +++ b/migration.c @@ -345,6 +345,7 @@ void migrate_fd_put_ready(MigrationState *s) int64_t start_time, end_time; DPRINTF("done iterating\n"); +save_run_state(); start_time = qemu_get_clock_ms(rt_clock); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); diff --git a/qapi-schema.json b/qapi-schema.json index 542e3ac..5fd4ae8 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -174,11 +174,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @SnapshotInfo diff --git a/qmp.c b/qmp.c index bcd7229..2c590e4 100644 --- a/qmp.c +++ b/qmp.c @@ -149,7 +149,8 @@ void qmp_cont(Error **errp) Error *local_err = NULL; if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index 69fca16..30d6e58 100644 --- a/vl.c +++ b/vl.c @@ -344,6 +344,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, @@ -357,6 +358,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, @@ -367,6 +369,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -377,6 +380,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -391,6 +395,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, }; @@ -1769,7 +1777,8 @@ static bool main_loop_should_exit(void) qemu_system_reset(VMRESET_REPORT); resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || -runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { bdrv_iterate(iostatus_bdrv_it, NULL); vm_start(); } -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 0/8] pv event to notify host when the guest is panicked
This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. changes from v11: - add a new patch 'save/load cpu runstate' - fix a bug of null-dereference when no -machine option is supplied - reserve RUN_STATE_GUEST_PANICKED during migration - add doc of enable_pv_event option - disable reboot-on-panic if pv_event is on v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it block.h | 2 + docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 11 +++ kvm-stub.c | 4 + kvm.h| 2 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- monitor.h| 1 + qapi-schema.json | 6 +- qemu-config.c| 4 + qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + sysemu.h | 2 + vl.c | 52 ++- 19 files changed, 312 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 7/8] allower the user to disable pv event support
Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- hw/pc_piix.c| 8 +++- qemu-config.c | 4 qemu-options.hx | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 8380702..bf31b96 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -150,6 +150,8 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; +QemuOptsList *list = qemu_find_opts("machine"); +bool enable_pv_event = false; pc_cpus_init(cpu_model); @@ -288,7 +290,11 @@ static void pc_init1(MemoryRegion *system_memory, pc_pci_device_init(pci_bus); } -if (kvm_enabled()) { +if (list && !QTAILQ_EMPTY(>head)) { +enable_pv_event = qemu_opt_get_bool(QTAILQ_FIRST(>head), +"enable_pv_event", false); +} +if (kvm_enabled() && enable_pv_event) { kvm_pv_event_init(isa_bus); } } diff --git a/qemu-config.c b/qemu-config.c index 10d1ba4..6682276 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -627,6 +627,10 @@ static QemuOptsList qemu_machine_opts = { .name = "usb", .type = QEMU_OPT_BOOL, .help = "Set on/off to enable/disable usb", +}, { +.name = "enable_pv_event", +.type = QEMU_OPT_BOOL, +.help = "handle pv event" }, { /* End of list */ } }, diff --git a/qemu-options.hx b/qemu-options.hx index dd86bfe..44c7760 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -35,7 +35,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ "kernel_irqchip=on|off controls accelerated irqchip support\n" "kvm_shadow_mem=size of KVM shadow MMU\n" "dump-guest-core=on|off include guest memory in a core dump (default=on)\n" -"mem-merge=on|off controls memory merge support (default: on)\n", +"mem-merge=on|off controls memory merge support (default: on)\n" +"enable_pv_event=on|off controls pv event support (default: off)\n", QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 6/8] introduce a new qom device to deal with panicked event
If the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target. Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang Signed-off-by: Hu Tao --- hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 5 ++ kvm-stub.c | 4 ++ kvm.h| 2 + 5 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 hw/kvm/pv_event.c diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs index f620d7f..cf93199 100644 --- a/hw/kvm/Makefile.objs +++ b/hw/kvm/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o pv_event.o diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c new file mode 100644 index 000..112491e --- /dev/null +++ b/hw/kvm/pv_event.c @@ -0,0 +1,197 @@ +/* + * QEMU KVM support, paravirtual event device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +#define PV_EVENT_DRIVER "kvm_pv_event" + +struct PVEventAction { +char *panicked_action; +int panicked_action_value; +}; + +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \ +DEFINE_PROP_STRING("panicked_action", _state, _conf.panicked_action) + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf("{ 'action': %s }", action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(uint32_t panicked_action) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event("report"); +break; + +case PANICKED_PAUSE: +panicked_mon_event("pause"); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event("poweroff"); +qemu_system_shutdown_request(); +break; + +case PANICKED_RESET: +panicked_mon_event("reset"); +qemu_system_reset_request(); +break; +} +} + +static uint64_t supported_event(void) +{ +return 1 << KVM_PV_FEATURE_PANICKED; +} + +static void handle_event(int event, struct PVEventAction *conf) +{ +if (event == KVM_PV_EVENT_PANICKED) { +panicked_perform_action(conf->panicked_action_value); +} +} + +static int pv_event_init(struct PVEventAction *conf) +{ +if (!conf->panicked_action) { +conf->panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf->panicked_action, "none") == 0) { +conf->panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf->panicked_action, "pause") == 0) { +conf->panicked_action_value = PANICKED_PAUSE; +} else if (strcasecmp(conf->panicked_action, "poweroff") == 0) { +conf->panicked_action_value = PANICKED_POWEROFF; +} else if (strcasecmp(conf->panicked_action, "reset") == 0) { +conf->panicked_action_value = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} + +#if defined(KVM_PV_EVENT_PORT) + +#include "hw/isa.h" + +typedef struct { +ISADevice dev; +struct PVEventAction conf; +MemoryRegion ioport; +} PVIOPortState; + +static uint64_t pv_io_read(void *opaque, hwaddr addr, unsigned size) +{ +return supported_event(); +} + +static void pv_io_write(void *opaque, hwaddr addr, uint64_t val, +unsigned size) +{ +PVIOPortStat
[PATCH v12 8/8] pv event: add document to describe the usage
Signed-off-by: Hu Tao --- docs/pv-event.txt | 17 + 1 file changed, 17 insertions(+) create mode 100644 docs/pv-event.txt diff --git a/docs/pv-event.txt b/docs/pv-event.txt new file mode 100644 index 000..ac9e7fa --- /dev/null +++ b/docs/pv-event.txt @@ -0,0 +1,17 @@ +KVM PV EVENT + + +kvm pv event allows guest OS to notify host OS of some events, for +example, guest panic. Currently, there is one event supported, that +is, guest panic. More events can be added later. + +By default, kvm pv event is disabled. In order to enable it, you have +to specify enable_pv_event=on for -machine command line option, along +with -global kvm_pv_event.panicked_action to specify the action taken +when panic event has occurred. Aviable panic actions are: "none", +"pause", "poweroff" and "reset". Following is example: + + qemu-system-x86_64 -enable-kvm -machine pc-0.12,enable_pv_event=on \ +-global kvm_pv_event.panicked_action=pause + +kvm pv event needs kvm support. -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 2/8] start vm after resetting it
From: Wen Congyang The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). Signed-off-by: Wen Congyang --- block.h | 2 ++ qmp.c | 2 +- vl.c| 7 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/block.h b/block.h index 722c620..2eea979 100644 --- a/block.h +++ b/block.h @@ -365,6 +365,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + enum BlockAcctType { BDRV_ACCT_READ, BDRV_ACCT_WRITE, diff --git a/qmp.c b/qmp.c index 13e83a5..bcd7229 100644 --- a/qmp.c +++ b/qmp.c @@ -129,7 +129,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index 6f274cc..69fca16 100644 --- a/vl.c +++ b/vl.c @@ -345,7 +345,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, @@ -380,7 +380,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, @@ -1770,7 +1770,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_wakeup_requested()) { -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 2/8] start vm after resetting it
From: Wen Congyang we...@cn.fujitsu.com The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- block.h | 2 ++ qmp.c | 2 +- vl.c| 7 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/block.h b/block.h index 722c620..2eea979 100644 --- a/block.h +++ b/block.h @@ -365,6 +365,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + enum BlockAcctType { BDRV_ACCT_READ, BDRV_ACCT_WRITE, diff --git a/qmp.c b/qmp.c index 13e83a5..bcd7229 100644 --- a/qmp.c +++ b/qmp.c @@ -129,7 +129,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index 6f274cc..69fca16 100644 --- a/vl.c +++ b/vl.c @@ -345,7 +345,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, @@ -380,7 +380,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, @@ -1770,7 +1770,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_wakeup_requested()) { -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 8/8] pv event: add document to describe the usage
Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- docs/pv-event.txt | 17 + 1 file changed, 17 insertions(+) create mode 100644 docs/pv-event.txt diff --git a/docs/pv-event.txt b/docs/pv-event.txt new file mode 100644 index 000..ac9e7fa --- /dev/null +++ b/docs/pv-event.txt @@ -0,0 +1,17 @@ +KVM PV EVENT + + +kvm pv event allows guest OS to notify host OS of some events, for +example, guest panic. Currently, there is one event supported, that +is, guest panic. More events can be added later. + +By default, kvm pv event is disabled. In order to enable it, you have +to specify enable_pv_event=on for -machine command line option, along +with -global kvm_pv_event.panicked_action to specify the action taken +when panic event has occurred. Aviable panic actions are: none, +pause, poweroff and reset. Following is example: + + qemu-system-x86_64 -enable-kvm -machine pc-0.12,enable_pv_event=on \ +-global kvm_pv_event.panicked_action=pause other options + +kvm pv event needs kvm support. -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 7/8] allower the user to disable pv event support
Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- hw/pc_piix.c| 8 +++- qemu-config.c | 4 qemu-options.hx | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 8380702..bf31b96 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -150,6 +150,8 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; +QemuOptsList *list = qemu_find_opts(machine); +bool enable_pv_event = false; pc_cpus_init(cpu_model); @@ -288,7 +290,11 @@ static void pc_init1(MemoryRegion *system_memory, pc_pci_device_init(pci_bus); } -if (kvm_enabled()) { +if (list !QTAILQ_EMPTY(list-head)) { +enable_pv_event = qemu_opt_get_bool(QTAILQ_FIRST(list-head), +enable_pv_event, false); +} +if (kvm_enabled() enable_pv_event) { kvm_pv_event_init(isa_bus); } } diff --git a/qemu-config.c b/qemu-config.c index 10d1ba4..6682276 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -627,6 +627,10 @@ static QemuOptsList qemu_machine_opts = { .name = usb, .type = QEMU_OPT_BOOL, .help = Set on/off to enable/disable usb, +}, { +.name = enable_pv_event, +.type = QEMU_OPT_BOOL, +.help = handle pv event }, { /* End of list */ } }, diff --git a/qemu-options.hx b/qemu-options.hx index dd86bfe..44c7760 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -35,7 +35,8 @@ DEF(machine, HAS_ARG, QEMU_OPTION_machine, \ kernel_irqchip=on|off controls accelerated irqchip support\n kvm_shadow_mem=size of KVM shadow MMU\n dump-guest-core=on|off include guest memory in a core dump (default=on)\n -mem-merge=on|off controls memory merge support (default: on)\n, +mem-merge=on|off controls memory merge support (default: on)\n +enable_pv_event=on|off controls pv event support (default: off)\n, QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 6/8] introduce a new qom device to deal with panicked event
If the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target. Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 5 ++ kvm-stub.c | 4 ++ kvm.h| 2 + 5 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 hw/kvm/pv_event.c diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs index f620d7f..cf93199 100644 --- a/hw/kvm/Makefile.objs +++ b/hw/kvm/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o pv_event.o diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c new file mode 100644 index 000..112491e --- /dev/null +++ b/hw/kvm/pv_event.c @@ -0,0 +1,197 @@ +/* + * QEMU KVM support, paravirtual event device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang we...@cn.fujitsu.com + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include linux/kvm_para.h +#include asm/kvm_para.h +#include qobject.h +#include qjson.h +#include monitor.h +#include sysemu.h +#include kvm.h + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +#define PV_EVENT_DRIVER kvm_pv_event + +struct PVEventAction { +char *panicked_action; +int panicked_action_value; +}; + +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \ +DEFINE_PROP_STRING(panicked_action, _state, _conf.panicked_action) + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf({ 'action': %s }, action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(uint32_t panicked_action) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event(report); +break; + +case PANICKED_PAUSE: +panicked_mon_event(pause); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event(poweroff); +qemu_system_shutdown_request(); +break; + +case PANICKED_RESET: +panicked_mon_event(reset); +qemu_system_reset_request(); +break; +} +} + +static uint64_t supported_event(void) +{ +return 1 KVM_PV_FEATURE_PANICKED; +} + +static void handle_event(int event, struct PVEventAction *conf) +{ +if (event == KVM_PV_EVENT_PANICKED) { +panicked_perform_action(conf-panicked_action_value); +} +} + +static int pv_event_init(struct PVEventAction *conf) +{ +if (!conf-panicked_action) { +conf-panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf-panicked_action, none) == 0) { +conf-panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf-panicked_action, pause) == 0) { +conf-panicked_action_value = PANICKED_PAUSE; +} else if (strcasecmp(conf-panicked_action, poweroff) == 0) { +conf-panicked_action_value = PANICKED_POWEROFF; +} else if (strcasecmp(conf-panicked_action, reset) == 0) { +conf-panicked_action_value = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} + +#if defined(KVM_PV_EVENT_PORT) + +#include hw/isa.h + +typedef struct { +ISADevice dev; +struct PVEventAction conf; +MemoryRegion ioport; +} PVIOPortState; + +static uint64_t pv_io_read(void *opaque, hwaddr addr, unsigned size) +{ +return supported_event(); +} + +static void pv_io_write(void *opaque, hwaddr addr, uint64_t val, +unsigned size) +{ +PVIOPortState *s = opaque; + +handle_event(val, s-conf); +} + +static const MemoryRegionOps pv_io_ops
[PATCH v12 0/8] pv event to notify host when the guest is panicked
This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic. changes from v11: - add a new patch 'save/load cpu runstate' - fix a bug of null-dereference when no -machine option is supplied - reserve RUN_STATE_GUEST_PANICKED during migration - add doc of enable_pv_event option - disable reboot-on-panic if pv_event is on v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html Hu Tao (7): save/load cpu runstate update kernel headers add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage Wen Congyang (1): start vm after resetting it block.h | 2 + docs/pv-event.txt| 17 hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c| 197 +++ hw/pc_piix.c | 11 +++ kvm-stub.c | 4 + kvm.h| 2 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c| 6 +- monitor.h| 1 + qapi-schema.json | 6 +- qemu-config.c| 4 + qemu-options.hx | 3 +- qmp.c| 5 +- savevm.c | 1 + sysemu.h | 2 + vl.c | 52 ++- 19 files changed, 312 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 5/8] add a new qevent: QEVENT_GUEST_PANICKED
This event will be emited when the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- monitor.c | 1 + monitor.h | 1 + 2 files changed, 2 insertions(+) diff --git a/monitor.c b/monitor.c index 1226501..231785b 100644 --- a/monitor.c +++ b/monitor.c @@ -458,6 +458,7 @@ static const char *monitor_event_names[] = { [QEVENT_WAKEUP] = WAKEUP, [QEVENT_BALLOON_CHANGE] = BALLOON_CHANGE, [QEVENT_SPICE_MIGRATE_COMPLETED] = SPICE_MIGRATE_COMPLETED, +[QEVENT_GUEST_PANICKED] = GUEST_PANICKED, }; QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) diff --git a/monitor.h b/monitor.h index b4ef955..16c1c83 100644 --- a/monitor.h +++ b/monitor.h @@ -46,6 +46,7 @@ typedef enum MonitorEvent { QEVENT_WAKEUP, QEVENT_BALLOON_CHANGE, QEVENT_SPICE_MIGRATE_COMPLETED, +QEVENT_GUEST_PANICKED, /* Add to 'monitor_event_names' array in monitor.c when * defining new events here */ -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 4/8] add a new runstate: RUN_STATE_GUEST_PANICKED
The guest will be in this state when it is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- migration.c | 1 + qapi-schema.json | 6 +- qmp.c| 3 ++- vl.c | 11 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/migration.c b/migration.c index 31fa300..9122dca 100644 --- a/migration.c +++ b/migration.c @@ -345,6 +345,7 @@ void migrate_fd_put_ready(MigrationState *s) int64_t start_time, end_time; DPRINTF(done iterating\n); +save_run_state(); start_time = qemu_get_clock_ms(rt_clock); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); diff --git a/qapi-schema.json b/qapi-schema.json index 542e3ac..5fd4ae8 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -174,11 +174,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @SnapshotInfo diff --git a/qmp.c b/qmp.c index bcd7229..2c590e4 100644 --- a/qmp.c +++ b/qmp.c @@ -149,7 +149,8 @@ void qmp_cont(Error **errp) Error *local_err = NULL; if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index 69fca16..30d6e58 100644 --- a/vl.c +++ b/vl.c @@ -344,6 +344,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, +{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, @@ -357,6 +358,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, @@ -367,6 +369,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -377,6 +380,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -391,6 +395,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, }; @@ -1769,7 +1777,8 @@ static bool main_loop_should_exit(void) qemu_system_reset(VMRESET_REPORT); resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || -runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { bdrv_iterate(iostatus_bdrv_it, NULL); vm_start(); } -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] kvm: notify host when the guest is panicked
We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- arch/ia64/kvm/irq.h | 19 + arch/powerpc/include/asm/kvm_para.h | 18 + arch/s390/include/asm/kvm_para.h| 19 + arch/x86/include/asm/kvm_para.h | 23 arch/x86/kernel/kvm.c | 53 + include/linux/kvm_para.h| 18 + include/uapi/linux/kvm_para.h | 6 + kernel/panic.c | 4 +++ 8 files changed, 160 insertions(+) diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h index c0785a7..b3870f8 100644 --- a/arch/ia64/kvm/irq.h +++ b/arch/ia64/kvm/irq.h @@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm) return 1; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index 9365860..4b0e8dd 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -145,4 +145,22 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index e0f8423..81d87ec 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,4 +154,23 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled(void) +{ + return false; +} + #endif /* __S390_KVM_PARA_H */ diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index eb3e9d8..5c38429 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -96,8 +96,11 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) + #ifdef __KERNEL__ #include asm/processor.h +#include linux/ioport.h extern void kvmclock_init(void); extern int kvm_register_clock(char *txt); @@ -228,6 +231,26 @@ static inline void kvm_disable_steal_time(void) } #endif +static inline int kvm_arch_pv_event_init(void) +{ + if (!request_region(KVM_PV_EVENT_PORT, 4, KVM_PV_EVENT)) + return -1; + + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return inl(KVM_PV_EVENT_PORT); +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ + outl(event, KVM_PV_EVENT_PORT); +} + +bool kvm_arch_pv_event_enabled(void); + #endif /* __KERNEL__ */ #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 4180a87..c92b962 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -62,6 +62,20 @@ static int parse_no_stealacc(char *arg) early_param(no-steal-acc, parse_no_stealacc); +static int pv_event = 1; +static int parse_no_pv_event(char *arg) +{ + pv_event = 0; + return 0; +} + +bool kvm_arch_pv_event_enabled(void) +{ + return !!pv_event; +} + +early_param(no-pv-event, parse_no_pv_event); + static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64); static int has_steal_clock = 0; @@ -372,6 +386,17 @@ static struct notifier_block kvm_pv_reboot_nb = { .notifier_call = kvm_pv_reboot_notify, }; +static int +kvm_pv_panic_notify(struct notifier_block
[PATCH v12 1/8] save/load cpu runstate
Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- migration.c | 6 +- monitor.c | 5 ++--- savevm.c| 1 + sysemu.h| 2 ++ vl.c| 34 ++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/migration.c b/migration.c index 73ce170..31fa300 100644 --- a/migration.c +++ b/migration.c @@ -102,11 +102,7 @@ static void process_incoming_migration_co(void *opaque) /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); -if (autostart) { -vm_start(); -} else { -runstate_set(RUN_STATE_PAUSED); -} +load_run_state(); } static void enter_migration_coroutine(void *opaque) diff --git a/monitor.c b/monitor.c index c0e32d6..1226501 100644 --- a/monitor.c +++ b/monitor.c @@ -2067,13 +2067,12 @@ void qmp_closefd(const char *fdname, Error **errp) static void do_loadvm(Monitor *mon, const QDict *qdict) { -int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, name); vm_stop(RUN_STATE_RESTORE_VM); -if (load_vmstate(name) == 0 saved_vm_running) { -vm_start(); +if (load_vmstate(name) == 0) { +load_run_state(); } } diff --git a/savevm.c b/savevm.c index 5d04d59..98963a4 100644 --- a/savevm.c +++ b/savevm.c @@ -2149,6 +2149,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); +save_run_state(); vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/sysemu.h b/sysemu.h index f5ac664..618f55e 100644 --- a/sysemu.h +++ b/sysemu.h @@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT %02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx +void save_run_state(void); +void load_run_state(void); bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/vl.c b/vl.c index c8e9c78..6f274cc 100644 --- a/vl.c +++ b/vl.c @@ -331,6 +331,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque) /* QEMU state */ static RunState current_run_state = RUN_STATE_PRELAUNCH; +static RunState saved_run_state = RUN_STATE_PRELAUNCH; typedef struct { RunState from; @@ -354,6 +355,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, +{ RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, @@ -364,6 +366,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, +{ RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR }, @@ -393,11 +396,39 @@ static const RunStateTransition runstate_transitions_def[] = { static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +void save_run_state(void) +{ +saved_run_state = current_run_state; +} + +void load_run_state(void) +{ +if (saved_run_state == RUN_STATE_RUNNING) { +vm_start(); +} else if (!runstate_check(saved_run_state)) { +runstate_set(saved_run_state); +} else { +; /* leave unchanged */ +} +} + bool runstate_check(RunState state) { return current_run_state == state; } +static void runstate_save(QEMUFile *f, void *opaque) +{ +qemu_put_byte(f, saved_run_state); +} + +static int runstate_load(QEMUFile *f, void *opaque, int version_id) +{ +saved_run_state = qemu_get_byte(f); + +return 0; +} + static void runstate_init(void) { const RunStateTransition *p; @@ -407,6 +438,9 @@ static void runstate_init(void) for (p = runstate_transitions_def[0]; p-from != RUN_STATE_MAX; p++) { runstate_valid_transitions[p-from][p-to] = true; } + +register_savevm(NULL, runstate, 0, 1, +runstate_save, runstate_load, NULL); } /* This function will abort() on invalid state transitions */ -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v12 3/8] update kernel headers
update kernel headers to add pv event macros. Signed-off-by: Wen Congyang we...@cn.fujitsu.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ 2 files changed, 7 insertions(+) diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index a1c3d72..781959a 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -96,5 +96,6 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index cea2c5c..c41ddce 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 + /* * hypercalls use architecture specific */ -- 1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v11] kvm: notify host when the guest is panicked
Hi Marcelo, On Tue, Nov 13, 2012 at 12:19:08AM -0200, Marcelo Tosatti wrote: > On Fri, Nov 09, 2012 at 03:17:39PM -0500, Sasha Levin wrote: > > On Mon, Nov 5, 2012 at 8:58 PM, Hu Tao wrote: > > > But in the case of panic notification, more dependency means more > > > chances of failure of panic notification. Say, if we use a virtio device > > > to do panic notification, then we will fail if: virtio itself has > > > problems, virtio for some reason can't be deployed(neither built-in or > > > as a module), or guest doesn't support virtio, etc. > > > > Add polling to your virtio device. If it didn't notify of a panic but > > taking more than 20 sec to answer your poll request you can assume > > it's dead. > > > > Actually, just use virtio-serial and something in userspace on the guest. > > They want the guest to stop, so a memory dump can be taken by management > interface. > > Hu Tao, lets assume port I/O is the preferred method for communication. Okey. > Now, the following comments have still not been addressed: > > 1) Lifecycle of the stopped guest and interaction with other stopped > states in QEMU. Patch 3 already deals with run state transitions. But in case I'm missing something, could you be more specific? > > 2) Format of the interface for other architectures (you can choose > a different KVM supported architecture and write an example). > > 3) Clear/documented management interface for the feature. It is documented in patch 0: Documentation/virtual/kvm/pv_event.txt. Does it need to be improved? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v11] kvm: notify host when the guest is panicked
Hi Marcelo, On Tue, Nov 13, 2012 at 12:19:08AM -0200, Marcelo Tosatti wrote: On Fri, Nov 09, 2012 at 03:17:39PM -0500, Sasha Levin wrote: On Mon, Nov 5, 2012 at 8:58 PM, Hu Tao hu...@cn.fujitsu.com wrote: But in the case of panic notification, more dependency means more chances of failure of panic notification. Say, if we use a virtio device to do panic notification, then we will fail if: virtio itself has problems, virtio for some reason can't be deployed(neither built-in or as a module), or guest doesn't support virtio, etc. Add polling to your virtio device. If it didn't notify of a panic but taking more than 20 sec to answer your poll request you can assume it's dead. Actually, just use virtio-serial and something in userspace on the guest. They want the guest to stop, so a memory dump can be taken by management interface. Hu Tao, lets assume port I/O is the preferred method for communication. Okey. Now, the following comments have still not been addressed: 1) Lifecycle of the stopped guest and interaction with other stopped states in QEMU. Patch 3 already deals with run state transitions. But in case I'm missing something, could you be more specific? 2) Format of the interface for other architectures (you can choose a different KVM supported architecture and write an example). 3) Clear/documented management interface for the feature. It is documented in patch 0: Documentation/virtual/kvm/pv_event.txt. Does it need to be improved? -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v11] kvm: notify host when the guest is panicked
On Tue, Oct 30, 2012 at 10:30:02PM -0400, Sasha Levin wrote: > On Tue, Oct 30, 2012 at 9:48 PM, Wen Congyang wrote: > > At 10/31/2012 09:12 AM, Marcelo Tosatti Wrote: > >> It has been asked earlier why a simple virtio device is not usable > >> for this (with no response IIRC). > > > > 1. We can't use virtio device when the kernel is booting. > > So the issue here is the small window between the point the guest > becomes "self aware" and to the point virtio drivers are loaded, > right? > > I agree that if something happens during that interval, a > "virtio-notifier" driver won't catch that, but anything beyond that is > better done with a virtio driver, so how is the generic infrastructure > added in this patch useful to anything beyond detecting panics in that > initial interval? Another point is dependency. To make panic notification more reliable, we have to reduce its dependency on other parts of kernel as possible as we can. > > > 2. The virtio's driver can be built as a module, and if it is not loaded > >and the kernel is panicked, there is no way to notify the host. > > Even if the suggested virtio-notifier driver is built as a module, it > would get auto-loaded when the guest is booting, so I'm not sure about > this point? > > > 3. I/O port is more reliable than virtio device. > >If virtio's driver has some bug, and it cause kernel panicked, we can't > >use it. The I/O port is more reliable because it only depends on notifier > >chain(If we use virtio device, it also depends on notifier chain). > > This is like suggesting that we let KVM emulate virtio-blk on it's > own, parallel to the virtio implementation, so that even if there's a > problem with virtio-blk, KVM can emulate a virtio-blk on it's own. Not the same. On virtio-blk, if we can make use of virtio, why not? If there is a problem of virtio-blk but caused by virtio itself, just fix it in virtio. But in the case of panic notification, more dependency means more chances of failure of panic notification. Say, if we use a virtio device to do panic notification, then we will fail if: virtio itself has problems, virtio for some reason can't be deployed(neither built-in or as a module), or guest doesn't support virtio, etc. We choose IO because compared to virtio device, it is not that heavy and less problematic. > > Furthermore, why stop at virtio? What if the KVM code has a bug and it > doesn't pass IO properly? Or the x86 code? we still want panic > notifications if that happens... Better ideas are welcome. -- Thanks, Hu Tao -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v11] kvm: notify host when the guest is panicked
On Tue, Oct 30, 2012 at 10:30:02PM -0400, Sasha Levin wrote: On Tue, Oct 30, 2012 at 9:48 PM, Wen Congyang we...@cn.fujitsu.com wrote: At 10/31/2012 09:12 AM, Marcelo Tosatti Wrote: It has been asked earlier why a simple virtio device is not usable for this (with no response IIRC). 1. We can't use virtio device when the kernel is booting. So the issue here is the small window between the point the guest becomes self aware and to the point virtio drivers are loaded, right? I agree that if something happens during that interval, a virtio-notifier driver won't catch that, but anything beyond that is better done with a virtio driver, so how is the generic infrastructure added in this patch useful to anything beyond detecting panics in that initial interval? Another point is dependency. To make panic notification more reliable, we have to reduce its dependency on other parts of kernel as possible as we can. 2. The virtio's driver can be built as a module, and if it is not loaded and the kernel is panicked, there is no way to notify the host. Even if the suggested virtio-notifier driver is built as a module, it would get auto-loaded when the guest is booting, so I'm not sure about this point? 3. I/O port is more reliable than virtio device. If virtio's driver has some bug, and it cause kernel panicked, we can't use it. The I/O port is more reliable because it only depends on notifier chain(If we use virtio device, it also depends on notifier chain). This is like suggesting that we let KVM emulate virtio-blk on it's own, parallel to the virtio implementation, so that even if there's a problem with virtio-blk, KVM can emulate a virtio-blk on it's own. Not the same. On virtio-blk, if we can make use of virtio, why not? If there is a problem of virtio-blk but caused by virtio itself, just fix it in virtio. But in the case of panic notification, more dependency means more chances of failure of panic notification. Say, if we use a virtio device to do panic notification, then we will fail if: virtio itself has problems, virtio for some reason can't be deployed(neither built-in or as a module), or guest doesn't support virtio, etc. We choose IO because compared to virtio device, it is not that heavy and less problematic. Furthermore, why stop at virtio? What if the KVM code has a bug and it doesn't pass IO properly? Or the x86 code? we still want panic notifications if that happens... Better ideas are welcome. -- Thanks, Hu Tao -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/