kvm: notify host when the guest is panicked
PATCH v7 1/1 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 startint the kernel
--- arch/ia64/include/asm/kvm_para.h | 5 +++++ arch/powerpc/include/asm/kvm_para.h | 5 +++++ arch/s390/include/asm/kvm_para.h | 5 +++++ arch/x86/include/asm/kvm_para.h | 7 +++++++ arch/x86/kernel/kvm.c | 14 ++++++++++++++ include/linux/kvm_para.h | 13 +++++++++++++ 6 files changed, 49 insertions(+), 0 deletions(-)
arch/ia64/include/asm/kvm_para.h +5 -0
@@ -31,6 +31,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif #endif
arch/powerpc/include/asm/kvm_para.h +5 -0
@@ -211,6 +211,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */
arch/s390/include/asm/kvm_para.h +5 -0
@@ -154,6 +154,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif #endif /* __S390_KVM_PARA_H */
arch/x86/include/asm/kvm_para.h +7 -0
@@ -89,6 +89,8 @@ struct kvm_vcpu_pv_apf_data {__u32 enabled; }; +#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h>
@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +#endif /* __KERNEL__ */ #endif /* _ASM_X86_KVM_PARA_H */
arch/x86/kernel/kvm.c +14 -0
@@ -328,6 +328,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) +{ +outl (KVM_PV_PANICKED ,KVM_PV_PORT ); +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;
@@ -414,6 +425,9 @@ void __init kvm_guest_init(void)paravirt_ops_setup ();register_reboot_notifier (&kvm_pv_reboot_nb); +if (kvm_pv_has_feature (KVM_PV_FEATURE_PANICKED )) +atomic_notifier_chain_register (&panic_notifier_list, + &kvm_pv_panic_nb);for (i =0 ; i <KVM_TASK_SLEEP_HASHSIZE ; i++)spin_lock_init (&async_pf_sleepers[i].lock);if (kvm_para_has_feature (KVM_FEATURE_ASYNC_PF ))
include/linux/kvm_para.h +13 -0
@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of the value read from KVM_PV_PORT */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The value writen to KVM_PV_PORT */ +#define KVM_PV_PANICKED 1 +/* * hypercalls use architecture specific */
@@ -33,5 +39,12 @@ static inline int kvm_para_has_feature(unsigned int feature)return 1 ;return 0 ; } + +static inline int kvm_pv_has_feature (unsigned int feature) +{ +if (kvm_arch_pv_features () & (1UL << feature)) +return 1 ; +return 0 ; +}#endif /* __KERNEL__ */ #endif /* __LINUX_KVM_PARA_H */
Signature · 1 line
1.7.1
PATCH v7 1/6 start vm after reseting it
The guest should run after reseting 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 reseting 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).
--- block.h | 2 ++ qmp.c | 2 +- vl.c | 7 ++++--- 3 files changed, 7 insertions(+), 4 deletions(-)
block.h +2 -0
@@ -337,6 +337,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 ,
qmp.c +1 -1
@@ -125,7 +125,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); }
vl.c +4 -3
@@ -331,7 +331,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH }, - { 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 },
@@ -364,7 +364,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 },
@@ -1532,7 +1532,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_powerdown_requested ()) {
Signature · 1 line
1.7.1
PATCH v7 2/6 kvm: Update kernel headers
In reply to Wen CongyangCorresponding kvm.git hash: 37e41afa and apply my patch for kvm
--- linux-headers/asm-x86/kvm_para.h | 2 ++ linux-headers/linux/kvm_para.h | 6 ++++++ 2 files changed, 8 insertions(+), 0 deletions(-)
linux-headers/asm-x86/kvm_para.h +2 -0
@@ -89,5 +89,7 @@ struct kvm_vcpu_pv_apf_data { __u32 enabled; }; +#define KVM_PV_PORT (0x505UL) +#endif /* _ASM_X86_KVM_PARA_H */
linux-headers/linux/kvm_para.h +6 -0
@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of the value read from KVM_PV_PORT */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The value writen to KVM_PV_PORT */ +#define KVM_PV_PANICKED 1 +/* * hypercalls use architecture specific */
Signature · 1 line
1.7.1
PATCH v7 3/6 add a new runstate: RUN_STATE_GUEST_PANICKED
In reply to Wen CongyangThe guest will be in this state when it is panicked.
--- qapi-schema.json | 6 +++++- qmp.c | 3 ++- vl.c | 7 ++++++- 3 files changed, 13 insertions(+), 3 deletions(-)
qapi-schema.json +5 -1
@@ -119,11 +119,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' ] } ## # @StatusInfo:
qmp.c +2 -1
@@ -148,7 +148,8 @@ void qmp_cont(Error **errp)error_set (errp,QERR_MIGRATION_EXPECTED );return ; }else 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 )) {
vl.c +6 -1
@@ -361,6 +361,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 },
@@ -375,6 +376,9 @@ 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_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, };
@@ -1531,7 +1535,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 (); }
Signature · 1 line
1.7.1
PATCH v7 4/6 add a new qevent: QEVENT_GUEST_PANICKED
In reply to Wen CongyangThis event will be emited when the guest is panicked.
--- monitor.c | 1 + monitor.h | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
monitor.c +1 -0
@@ -458,6 +458,7 @@ static const char *monitor_event_names[] = { [QEVENT_SUSPEND] = "SUSPEND", [QEVENT_WAKEUP] = "WAKEUP", [QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE", + [QEVENT_GUEST_PANICKED ] ="GUEST_PANICKED" , };QEMU_BUILD_BUG_ON (ARRAY_SIZE (monitor_event_names) !=QEVENT_MAX )
monitor.h +1 -0
@@ -42,6 +42,7 @@ typedef enum MonitorEvent {QEVENT_SUSPEND ,QEVENT_WAKEUP ,QEVENT_BALLOON_CHANGE , + QEVENT_GUEST_PANICKED,/* Add to 'monitor_event_names' array in monitor.c when * defining new events here */
Signature · 1 line
1.7.1
PATCH v7 5/6 introduce a new qom device to deal with panicked event
In reply to Wen CongyangIf the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_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.
--- hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++ hw/kvm/pv_ioport.c | 93 ++++++++++++++++++++++++++++++++++++++++++ hw/pc_piix.c | 9 ++++ kvm.h | 2 + 5 files changed, 214 insertions(+), 1 deletions(-) create mode 100644 hw/kvm/pv_event.c create mode 100644 hw/kvm/pv_ioport.c
hw/kvm/Makefile.objs +1 -1
@@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pv_event.o
hw/kvm/pv_event.c new file +109 -0
109 lines not on this page · raw message
hw/kvm/pv_ioport.c new file +93 -0
93 lines not on this page · raw message
hw/pc_piix.c +9 -0
@@ -46,6 +46,9 @@#ifdef CONFIG_XEN # include <xen/hvm/hvm_info_table.h> #endif +#ifdef CONFIG_KVM +# include <asm/kvm_para.h> +#endif #define MAX_IDE_BUS 2
@@ -285,6 +288,12 @@ static void pc_init1(MemoryRegion *system_memory,if (pci_enabled) {pc_pci_device_init (pci_bus); } + +#ifdef KVM_PV_PORT +if (kvm_enabled ()) { +kvm_pv_event_init (isa_bus); + } +#endif } static void pc_init_pci(ram_addr_t ram_size,
kvm.h +2 -0
@@ -222,4 +222,6 @@ int kvm_irqchip_add_irqfd(KVMState *s, int fd, int virq);int kvm_irqchip_remove_irqfd (KVMState *s,int fd,int virq);int kvm_irqchip_add_irq_notifier (KVMState *s,EventNotifier *n,int virq);int kvm_irqchip_remove_irq_notifier (KVMState *s,EventNotifier *n,int virq); + +void kvm_pv_event_init (void *opaque);#endif
Signature · 1 line
1.7.1
PATCH v7 6/6 allow the user to disable pv event support
In reply to Wen CongyangThe qom device uses a fixed PIO port that might conflict with (non-Linux) guest expectations and/or future device models. So allow the user to disable it.
--- hw/pc_piix.c | 6 +++++- qemu-config.c | 4 ++++ qemu-options.hx | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-)
hw/pc_piix.c +5 -1
@@ -151,6 +151,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;pc_cpus_init (cpu_model);
@@ -289,8 +291,10 @@ static void pc_init1(MemoryRegion *system_memory,pc_pci_device_init (pci_bus); } + enable_pv_event =qemu_opt_get_bool (QTAILQ_FIRST (&list->head), +"enable_pv_event" , false);#ifdef KVM_PV_PORT -if (kvm_enabled ()) { +if (kvm_enabled () && enable_pv_event) {kvm_pv_event_init (isa_bus); }#endif
qemu-config.c +4 -0
@@ -595,6 +595,10 @@ static QemuOptsList qemu_machine_opts = { .name = "dt_compatible", .type = QEMU_OPT_STRING, .help = "Overrides the \"compatible\" property of the dt root node", + }, { + .name = "enable_pv_event", + .type = QEMU_OPT_BOOL, + .help = "handle pv event" }, {/* End of list */ } },
qemu-options.hx +2 -1
@@ -33,7 +33,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ " property accel=accel1[:accel2[:...]] selects accelerator\n" " supported accelerators are kvm, xen, tcg (default: tcg)\n" " kernel_irqchip=on|off controls accelerated irqchip support\n" - " kvm_shadow_mem=size of KVM shadow MMU\n", + " kvm_shadow_mem=size of KVM shadow MMU\n" + " enable_pv_event=on|off controls pv event support\n", QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]]
Signature · 1 line
1.7.1
Quoted 152 lines · Wen Congyang
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 startint the kernelSigned-off-by Wen Congyang <[email protected]>--- arch/ia64/include/asm/kvm_para.h | 5 +++++ arch/powerpc/include/asm/kvm_para.h | 5 +++++ arch/s390/include/asm/kvm_para.h | 5 +++++ arch/x86/include/asm/kvm_para.h | 7 +++++++ arch/x86/kernel/kvm.c | 14 ++++++++++++++ include/linux/kvm_para.h | 13 +++++++++++++ 6 files changed, 49 insertions(+), 0 deletions(-)arch/ia64/include/asm/kvm_para.h +5
-0@@ -31,6 +31,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif #endif arch/powerpc/include/asm/kvm_para.h +5
-0@@ -211,6 +211,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */ arch/s390/include/asm/kvm_para.h +5
-0@@ -154,6 +154,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif #endif /* __S390_KVM_PARA_H */ arch/x86/include/asm/kvm_para.h +7
-0@@ -89,6 +89,8 @@ struct kvm_vcpu_pv_apf_data {__u32 enabled; }; +#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> @@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +#endif /* __KERNEL__ */ #endif /* _ASM_X86_KVM_PARA_H */ arch/x86/kernel/kvm.c +14
-0@@ -328,6 +328,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) +{ +outl (KVM_PV_PANICKED ,KVM_PV_PORT ); +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;@@ -414,6 +425,9 @@ void __init kvm_guest_init(void)paravirt_ops_setup ();register_reboot_notifier (&kvm_pv_reboot_nb); +if (kvm_pv_has_feature (KVM_PV_FEATURE_PANICKED )) +atomic_notifier_chain_register (&panic_notifier_list, + &kvm_pv_panic_nb);for (i =0 ; i <KVM_TASK_SLEEP_HASHSIZE ; i++)spin_lock_init (&async_pf_sleepers[i].lock);if (kvm_para_has_feature (KVM_FEATURE_ASYNC_PF ))include/linux/kvm_para.h +6
-0@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of the value read from KVM_PV_PORT */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The value writen to KVM_PV_PORT */ +#define KVM_PV_PANICKED 1 +/* * hypercalls use architecture specific */
include/linux/kvm_para.h static inline int kvm_para_has_feature(unsigned int feature) · line 45
Quoted 7 lines
include/linux/kvm_para.h +4
-0@@ -33,5 +39,12 @@ static inline int kvm_para_has_feature(unsigned int feature)return 1 ;return 0 ; } + +static inline int kvm_pv_has_feature (unsigned int feature) +{ +if (kvm_arch_pv_features () & (1UL << feature))
Reading from an invalid I/O port will return -1. So your test will deliver a wrong result on a platform that doesn't support this PV channel.
Jan
Quoted 6 lines
include/linux/kvm_para.h +3
-0+return 1 ; +return 0 ; +}#endif /* __KERNEL__ */ #endif /* __LINUX_KVM_PARA_H */
At 07/21/2012 03:19 PM, Jan Kiszka Wrote:
Quoted 155 lines · Wen Congyang
Quoted 154 lines
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 startint the kernelSigned-off-by Wen Congyang <[email protected]>--- arch/ia64/include/asm/kvm_para.h | 5 +++++ arch/powerpc/include/asm/kvm_para.h | 5 +++++ arch/s390/include/asm/kvm_para.h | 5 +++++ arch/x86/include/asm/kvm_para.h | 7 +++++++ arch/x86/kernel/kvm.c | 14 ++++++++++++++ include/linux/kvm_para.h | 13 +++++++++++++ 6 files changed, 49 insertions(+), 0 deletions(-)arch/ia64/include/asm/kvm_para.h +5
-0@@ -31,6 +31,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif #endif arch/powerpc/include/asm/kvm_para.h +5
-0@@ -211,6 +211,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */ arch/s390/include/asm/kvm_para.h +5
-0@@ -154,6 +154,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif #endif /* __S390_KVM_PARA_H */ arch/x86/include/asm/kvm_para.h +7
-0@@ -89,6 +89,8 @@ struct kvm_vcpu_pv_apf_data {__u32 enabled; }; +#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> @@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +#endif /* __KERNEL__ */ #endif /* _ASM_X86_KVM_PARA_H */ arch/x86/kernel/kvm.c +14
-0@@ -328,6 +328,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) +{ +outl (KVM_PV_PANICKED ,KVM_PV_PORT ); +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;@@ -414,6 +425,9 @@ void __init kvm_guest_init(void)paravirt_ops_setup ();register_reboot_notifier (&kvm_pv_reboot_nb); +if (kvm_pv_has_feature (KVM_PV_FEATURE_PANICKED )) +atomic_notifier_chain_register (&panic_notifier_list, + &kvm_pv_panic_nb);for (i =0 ; i <KVM_TASK_SLEEP_HASHSIZE ; i++)spin_lock_init (&async_pf_sleepers[i].lock);if (kvm_para_has_feature (KVM_FEATURE_ASYNC_PF ))include/linux/kvm_para.h +6
-0@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of the value read from KVM_PV_PORT */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The value writen to KVM_PV_PORT */ +#define KVM_PV_PANICKED 1 +/* * hypercalls use architecture specific */ @@ -33,5 +39,12 @@ static inline int kvm_para_has_feature(unsigned int feature)return 1 ;return 0 ;
Quoted 8 lines
include/linux/kvm_para.h static inline int kvm_para_has_feature(unsigned int feature) · line 45
Quoted 5 lines
include/linux/kvm_para.h +4
-0} + +static inline int kvm_pv_has_feature (unsigned int feature) +{ +if (kvm_arch_pv_features () & (1UL << feature))Reading from an invalid I/O port will return -1. So your test will deliver a wrong result on a platform that doesn't support this PV channel.
Yes, you are right. I will update it.
Thanks
Wen Congyang
Quoted 13 lines
Jan
Quoted 6 lines
include/linux/kvm_para.h +3
-0+return 1 ; +return 0 ; +}#endif /* __KERNEL__ */ #endif /* __LINUX_KVM_PARA_H */
PATCH 1/1 kvm: notify host when the guest is panicked
In reply to Wen CongyangWe 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
--- arch/ia64/include/asm/kvm_para.h | 5 +++++ arch/powerpc/include/asm/kvm_para.h | 5 +++++ arch/s390/include/asm/kvm_para.h | 5 +++++ arch/x86/include/asm/kvm_para.h | 13 +++++++++++++ arch/x86/kernel/kvm.c | 14 ++++++++++++++ include/linux/kvm_para.h | 13 +++++++++++++ 6 files changed, 55 insertions(+), 0 deletions(-)
arch/ia64/include/asm/kvm_para.h +5 -0
@@ -31,6 +31,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif #endif
arch/powerpc/include/asm/kvm_para.h +5 -0
@@ -211,6 +211,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */
arch/s390/include/asm/kvm_para.h +5 -0
@@ -154,6 +154,11 @@ static inline bool kvm_check_and_clear_guest_paused(void)return false; } +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} +#endif #endif /* __S390_KVM_PARA_H */
arch/x86/include/asm/kvm_para.h +13 -0
@@ -89,6 +89,8 @@ struct kvm_vcpu_pv_apf_data {__u32 enabled; }; +#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h>
@@ -221,6 +223,17 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +unsigned int features =inl (KVM_PV_PORT ); + +/* Reading from an invalid I/O port will return -1 */ +if (features == ~0 ) + features =0 ; + +return features; +} +#endif /* __KERNEL__ */ #endif /* _ASM_X86_KVM_PARA_H */
arch/x86/kernel/kvm.c +14 -0
@@ -328,6 +328,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) +{ +outl (KVM_PV_PANICKED ,KVM_PV_PORT ); +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;
@@ -414,6 +425,9 @@ void __init kvm_guest_init(void)paravirt_ops_setup ();register_reboot_notifier (&kvm_pv_reboot_nb); +if (kvm_pv_has_feature (KVM_PV_FEATURE_PANICKED )) +atomic_notifier_chain_register (&panic_notifier_list, + &kvm_pv_panic_nb);for (i =0 ; i <KVM_TASK_SLEEP_HASHSIZE ; i++)spin_lock_init (&async_pf_sleepers[i].lock);if (kvm_para_has_feature (KVM_FEATURE_ASYNC_PF ))
include/linux/kvm_para.h +13 -0
@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of the value read from KVM_PV_PORT */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The value writen to KVM_PV_PORT */ +#define KVM_PV_PANICKED 1 +/* * hypercalls use architecture specific */
@@ -33,5 +39,12 @@ static inline int kvm_para_has_feature(unsigned int feature)return 1 ;return 0 ; } + +static inline int kvm_pv_has_feature (unsigned int feature) +{ +if (kvm_arch_pv_features () & (1UL << feature)) +return 1 ; +return 0 ; +}#endif /* __KERNEL__ */ #endif /* __LINUX_KVM_PARA_H */
Signature · 1 line
1.7.1
Quoted 13 lines · Wen Congyang
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.
Quoted 5 lines
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
Was the option of implementing a virtio-watchdog driver considered?
You're basically re-implementing a watchdog, a guest-host interface and a set of protocols for guest-host communications.
Why can't we re-use everything we have now, push a virtio watchdog driver into drivers/watchdog/, and gain a more complete solution to detecting hangs inside the guest.
Quoted 20 lines · Sasha Levin
Quoted 13 lines · Wen Congyang
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.Quoted 5 lines
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
Quoted 7 lines
Was the option of implementing a virtio-watchdog driver considered?
You're basically re-implementing a watchdog, a guest-host interface and a set of protocols for guest-host communications.
Why can't we re-use everything we have now, push a virtio watchdog driver into
drivers/watchdog/, and gain a more complete solution to detecting hangs inside the guest.
The purpose of virtio is not to reinvent every possible type of device. There are plenty of hardware watchdogs that are very suitable to be used for this purpose. QEMU implements quite a few already.
Watchdogs are not performance sensitive so there's no point in using virtio.
Regards,
Anthony Liguori
Quoted 30 lines · Anthony Liguori
Quoted 20 lines · Sasha Levin
Quoted 13 lines · Wen Congyang
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.Quoted 5 lines
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 kernelQuoted 7 lines
Was the option of implementing a virtio-watchdog driver considered?
You're basically re-implementing a watchdog, a guest-host interface and a set of protocols for guest-host communications.
Why can't we re-use everything we have now, push a virtio watchdog driver into
drivers/watchdog/, and gain a more complete solution to detecting hangs inside the guest.
Quoted 6 lines
The purpose of virtio is not to reinvent every possible type of device. There are plenty of hardware watchdogs that are very suitable to be used for this purpose. QEMU implements quite a few already.
Watchdogs are not performance sensitive so there's no point in using virtio.
The issue here is not performance, but the adding of a brand new guest-host interface.
virtio-rng isn't performance sensitive either, yet it was implemented using virtio so there wouldn't be yet another interface to communicate between guest and host.
This patch goes ahead to add a "arch pv features" interface using ioports, without any idea what it might be used for beyond this watchdog.
Quoted 35 lines · Sasha Levin
Quoted 34 lines · Anthony Liguori
Quoted 20 lines · Sasha Levin
Quoted 13 lines · Wen Congyang
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.Quoted 5 lines
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 kernelQuoted 7 lines
Was the option of implementing a virtio-watchdog driver considered?
You're basically re-implementing a watchdog, a guest-host interface and a set of protocols for guest-host communications.
Why can't we re-use everything we have now, push a virtio watchdog driver into
drivers/watchdog/, and gain a more complete solution to detecting hangs inside the guest.The purpose of virtio is not to reinvent every possible type of device. There are plenty of hardware watchdogs that are very suitable to be used for this purpose. QEMU implements quite a few already.
Quoted 5 lines
Quoted 2 lines
Watchdogs are not performance sensitive so there's no point in using virtio.
The issue here is not performance, but the adding of a brand new guest-host interface.
We have:
1) Virtio--this is our preferred PV interface. It needs PCI to be fully initialized and probably will live as a module.
2) Hypercalls--this a secondary PV interface but is available very early. It's terminated in kvm.ko which means it can only operate on things that are logically part of the CPU and/or APIC complex.
This patch introduces a third interface which is available early like hypercalls but not necessarily terminated in kvm.ko. That means it can have a broader scope in functionality than (2).
We could just as well use a hypercall and have multiple commands issued to that hypercall as a convention and add a new exit type to KVM that sent that specific hypercall to userspace for processing.
But a PIO operation already has this behavior and requires no changes to kvm.ko.
Quoted 3 lines
virtio-rng isn't performance sensitive either, yet it was implemented using virtio so there wouldn't be yet another interface to communicate between guest and host.
There isn't really an obvious discrete RNG that is widely supported.
Quoted 3 lines
This patch goes ahead to add a "arch pv features" interface using ioports, without any idea what it might be used for beyond this watchdog.
It's not a watchdog--it's the opposite of a watchdog.
You know such a thing already exists in the kernel, right? S390 has had a hypercall like this for years.
Regards,
Anthony Liguori
Quoted 56 lines · Anthony Liguori
Quoted 35 lines · Sasha Levin
Quoted 34 lines · Anthony Liguori
Quoted 20 lines · Sasha Levin
Quoted 13 lines · Wen Congyang
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.Quoted 5 lines
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 kernelQuoted 7 lines
Was the option of implementing a virtio-watchdog driver considered?
You're basically re-implementing a watchdog, a guest-host interface and a set of protocols for guest-host communications.
Why can't we re-use everything we have now, push a virtio watchdog driver into
drivers/watchdog/, and gain a more complete solution to detecting hangs inside the guest.The purpose of virtio is not to reinvent every possible type of device. There are plenty of hardware watchdogs that are very suitable to be used for this purpose. QEMU implements quite a few already.
Quoted 5 lines
Quoted 2 lines
Watchdogs are not performance sensitive so there's no point in using virtio.
The issue here is not performance, but the adding of a brand new guest-host interface.
We have:
1) Virtio--this is our preferred PV interface. It needs PCI to be fully initialized and probably will live as a module.
2) Hypercalls--this a secondary PV interface but is available very early. It's terminated in kvm.ko which means it can only operate on things that are logically part of the CPU and/or APIC complex.
This patch introduces a third interface which is available early like hypercalls but not necessarily terminated in kvm.ko. That means it can have a broader scope in functionality than (2).
Quoted 5 lines
We could just as well use a hypercall and have multiple commands issued to that hypercall as a convention and add a new exit type to KVM that sent that specific hypercall to userspace for processing.
But a PIO operation already has this behavior and requires no changes to kvm.ko.
I don't dispute that there may be a need for another guest-host interface, but this patch can basically be called "kvm: notify host when the guest is panicked, oh, btw, and add a brand new undocumented interface"
The new interface should at least come in it's own patch, with documentation.
At 07/23/2012 07:50 AM, Sasha Levin Wrote:
Quoted 57 lines · Anthony Liguori
Quoted 56 lines
Quoted 35 lines · Sasha Levin
Quoted 34 lines · Anthony Liguori
Quoted 20 lines · Sasha Levin
Quoted 13 lines · Wen Congyang
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.Quoted 5 lines
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 kernelQuoted 7 lines
Was the option of implementing a virtio-watchdog driver considered?
You're basically re-implementing a watchdog, a guest-host interface and a set of protocols for guest-host communications.
Why can't we re-use everything we have now, push a virtio watchdog driver into
drivers/watchdog/, and gain a more complete solution to detecting hangs inside the guest.The purpose of virtio is not to reinvent every possible type of device. There are plenty of hardware watchdogs that are very suitable to be used for this purpose. QEMU implements quite a few already.
Quoted 5 lines
Quoted 2 lines
Watchdogs are not performance sensitive so there's no point in using virtio.
The issue here is not performance, but the adding of a brand new guest-host interface.
We have:
1) Virtio--this is our preferred PV interface. It needs PCI to be fully initialized and probably will live as a module.
2) Hypercalls--this a secondary PV interface but is available very early. It's terminated in kvm.ko which means it can only operate on things that are logically part of the CPU and/or APIC complex.
This patch introduces a third interface which is available early like hypercalls but not necessarily terminated in kvm.ko. That means it can have a broader scope in functionality than (2).
Quoted 7 lines
Quoted 5 lines
We could just as well use a hypercall and have multiple commands issued to that hypercall as a convention and add a new exit type to KVM that sent that specific hypercall to userspace for processing.
But a PIO operation already has this behavior and requires no changes to kvm.ko.
I don't dispute that there may be a need for another guest-host interface, but this patch can basically be called "kvm: notify host when the guest is panicked, oh, btw, and add a brand new undocumented interface"
I forgot to document this interface. I will add it.
Thanks
Wen Congyang
Quoted 8 lines
The new interface should at least come in it's own patch, with documentation. --
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
At 07/22/2012 07:39 PM, Sasha Levin Wrote:
Quoted 14 lines · Wen Congyang
Quoted 13 lines
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.
Quoted 7 lines
Quoted 5 lines
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 kernelWas the option of implementing a virtio-watchdog driver considered?
virtio-watchdog? What is this? I don't find it in qemu. Do I miss something?
Another reason why we don't use this:
If the watchdog timeouts, we cannot say the kernel is panicked. For example, the kernel is hung, or the kernel is deadlock, or ... the watchdog daemon can not have chance to touch watchdog device.
Thanks
Wen Congyang
Quoted 10 lines
You're basically re-implementing a watchdog, a guest-host interface and a set of protocols for guest-host communications.
Why can't we re-use everything we have now, push a virtio watchdog driver into
drivers/watchdog/, and gain a more complete solution to detecting hangs inside the guest. --
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 6 lines · Wen Congyang
arch/x86/include/asm/kvm_para.h +2
-0+#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h>
arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 230
Quoted 8 lines
arch/x86/include/asm/kvm_para.h +5
-0@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +
Why is this safe?
I'm not sure you can just pick any ioport you'd like and use it.
Quoted 18 lines · Sasha Levin
Quoted 6 lines · Wen Congyang
arch/x86/include/asm/kvm_para.h +2
-0+#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 230
Quoted 8 lines
arch/x86/include/asm/kvm_para.h +5
-0@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +Why is this safe?
Quoted 1 line
I'm not sure you can just pick any ioport you'd like and use it.
There are three ways I/O ports get used on a PC:
1) Platform devices
- This is well defined since the vast majority of platform devices are implemented within a single chip. If you're emulating an i440fx chipset, the PIIX4 spec has an exhaustive list.
2) PCI devices
- Typically, PCI only allocates ports starting at 0x0d00 to avoid conflicts with ISA devices.
3) ISA devices
- ISA uses subtractive decoding so any ISA device can access. In theory, an ISA device could attempt to use port 0x0505 but it's unlikely. In a modern guest, there aren't really any ISA devices being added either.
So yes, picking port 0x0505 is safe for something like this (as long as you check to make sure that you really are under KVM).
Regards,
Anthony Liguori
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 33 lines · Anthony Liguori
Quoted 18 lines · Sasha Levin
Quoted 6 lines · Wen Congyang
arch/x86/include/asm/kvm_para.h +2
-0+#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 230
Quoted 8 lines
arch/x86/include/asm/kvm_para.h +5
-0@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +Why is this safe?
Quoted 1 line
I'm not sure you can just pick any ioport you'd like and use it.
There are three ways I/O ports get used on a PC:
1) Platform devices
- This is well defined since the vast majority of platform devices are implemented within a single chip. If you're emulating an i440fx chipset, the PIIX4 spec has an exhaustive list.2) PCI devices
- Typically, PCI only allocates ports starting at0x0d00to avoid conflicts with ISA devices.
Quoted 8 lines
3) ISA devices
- ISA uses subtractive decoding so any ISA device can access. In theory, an ISA device could attempt to use port0x0505but it's unlikely. In a modern guest, there aren't really any ISA devices being added either.So yes, picking port
0x0505is safe for something like this (as long as you check to make sure that you really are under KVM).
Is there anything that actually prevents me from using PCI ports lower than 0x0d00? As you said in (3), ISA isn't really used anymore (nor is implemented by lkvm for example), so placing PCI below 0x0d00 might even make sense in that case.
Furthermore, I can place one of these brand new virtio-mmio devices which got introduced recently wherever I want right now - Having a device that uses 0x505 would cause a pretty non-obvious failure mode.
Either way, If we are going to grab an ioport, then:
- It should be documented well somewhere in Documentation/virt/kvm
- It should go through request_region() to actually claim those ioports.
- It should fail gracefully if that port is taken for some reason, instead of not even checking it.
Quoted 45 lines · Sasha Levin
Quoted 33 lines · Anthony Liguori
Quoted 18 lines · Sasha Levin
Quoted 6 lines · Wen Congyang
arch/x86/include/asm/kvm_para.h +2
-0+#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 230
Quoted 8 lines
arch/x86/include/asm/kvm_para.h +5
-0@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +Why is this safe?
Quoted 1 line
I'm not sure you can just pick any ioport you'd like and use it.
There are three ways I/O ports get used on a PC:
1) Platform devices
- This is well defined since the vast majority of platform devices are implemented within a single chip. If you're emulating an i440fx chipset, the PIIX4 spec has an exhaustive list.2) PCI devices
- Typically, PCI only allocates ports starting at0x0d00to avoid conflicts with ISA devices.Quoted 8 lines
3) ISA devices
- ISA uses subtractive decoding so any ISA device can access. In theory, an ISA device could attempt to use port0x0505but it's unlikely. In a modern guest, there aren't really any ISA devices being added either.So yes, picking port
0x0505is safe for something like this (as long as you check to make sure that you really are under KVM).Is there anything that actually prevents me from using PCI ports lower than
0x0d00? As you said in (3), ISA isn't really used anymore (nor is implemented by lkvm for example), so placing PCI below0x0d00might even make sense in that case.
Quoted 8 lines
Furthermore, I can place one of these brand new virtio-mmio devices which got introduced recently wherever I want right now - Having a device that uses
0x505would cause a pretty non-obvious failure mode.Either way, If we are going to grab an ioport, then:
- It should be documented well somewhere in
Documentation/virt/kvm
- It should go throughrequest_region()to actually claim those ioports.
- It should fail gracefully if that port is taken for some reason, instead of not even checking it.
Out of curiosity I tested that, and apparently lkvm has no problem allocating virtio-pci devices in that range:
sh-4.2# pwd /sys/devices/pci0000:00/0000:00:01.0
sh-4.2# cat resource | head -n1 0x0000000000000500 0x00000000000005ff 0x0000000000040101
This was with the commit in question applied.
Quoted 55 lines · Sasha Levin
Quoted 45 lines · Sasha Levin
Quoted 33 lines · Anthony Liguori
Quoted 18 lines · Sasha Levin
Quoted 6 lines · Wen Congyang
arch/x86/include/asm/kvm_para.h +2
-0+#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 230
Quoted 8 lines
arch/x86/include/asm/kvm_para.h +5
-0@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +Why is this safe?
Quoted 1 line
I'm not sure you can just pick any ioport you'd like and use it.
There are three ways I/O ports get used on a PC:
1) Platform devices
- This is well defined since the vast majority of platform devices are implemented within a single chip. If you're emulating an i440fx chipset, the PIIX4 spec has an exhaustive list.2) PCI devices
- Typically, PCI only allocates ports starting at0x0d00to avoid conflicts with ISA devices.Quoted 8 lines
3) ISA devices
- ISA uses subtractive decoding so any ISA device can access. In theory, an ISA device could attempt to use port0x0505but it's unlikely. In a modern guest, there aren't really any ISA devices being added either.So yes, picking port
0x0505is safe for something like this (as long as you check to make sure that you really are under KVM).Is there anything that actually prevents me from using PCI ports lower than
0x0d00? As you said in (3), ISA isn't really used anymore (nor is implemented by lkvm for example), so placing PCI below0x0d00might even make sense in that case.Quoted 8 lines
Furthermore, I can place one of these brand new virtio-mmio devices which got introduced recently wherever I want right now - Having a device that uses
0x505would cause a pretty non-obvious failure mode.Either way, If we are going to grab an ioport, then:
- It should be documented well somewhere in
Documentation/virt/kvm
- It should go throughrequest_region()to actually claim those ioports.
- It should fail gracefully if that port is taken for some reason, instead of not even checking it.
Quoted 8 lines
Out of curiosity I tested that, and apparently lkvm has no problem allocating virtio-pci devices in that range:
sh-4.2# pwd /sys/devices/pci0000:00/0000:00:01.0
sh-4.2# cat resource | head -n10x00000000000005000x00000000000005ff0x0000000000040101This was with the commit in question applied.
With all due respect, lkvm has a half-baked implementation of PCI. This is why you have to pass kernel parameters to disable ACPI and disable PCI BIOS probing.
So yeah, you can do funky things in lkvm but that doesn't mean a system that emulated actual hardware would ever do that.
Regards,
Anthony Liguori
Quoted 64 lines · Anthony Liguori
Quoted 62 lines · Sasha Levin
Quoted 45 lines · Sasha Levin
Quoted 33 lines · Anthony Liguori
Quoted 18 lines · Sasha Levin
Quoted 6 lines · Wen Congyang
arch/x86/include/asm/kvm_para.h +2
-0+#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 230
Quoted 8 lines
arch/x86/include/asm/kvm_para.h +5
-0@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +Why is this safe?
Quoted 1 line
I'm not sure you can just pick any ioport you'd like and use it.
There are three ways I/O ports get used on a PC:
1) Platform devices
- This is well defined since the vast majority of platform devices are implemented within a single chip. If you're emulating an i440fx chipset, the PIIX4 spec has an exhaustive list.2) PCI devices
- Typically, PCI only allocates ports starting at0x0d00to avoid conflicts with ISA devices.Quoted 8 lines
3) ISA devices
- ISA uses subtractive decoding so any ISA device can access. In theory, an ISA device could attempt to use port0x0505but it's unlikely. In a modern guest, there aren't really any ISA devices being added either.So yes, picking port
0x0505is safe for something like this (as long as you check to make sure that you really are under KVM).Is there anything that actually prevents me from using PCI ports lower than
0x0d00? As you said in (3), ISA isn't really used anymore (nor is implemented by lkvm for example), so placing PCI below0x0d00might even make sense in that case.Quoted 8 lines
Furthermore, I can place one of these brand new virtio-mmio devices which got introduced recently wherever I want right now - Having a device that uses
0x505would cause a pretty non-obvious failure mode.Either way, If we are going to grab an ioport, then:
- It should be documented well somewhere in
Documentation/virt/kvm
- It should go throughrequest_region()to actually claim those ioports.
- It should fail gracefully if that port is taken for some reason, instead of not even checking it.Out of curiosity I tested that, and apparently lkvm has no problem allocating virtio-pci devices in that range:
sh-4.2# pwd /sys/devices/pci0000:00/0000:00:01.0
sh-4.2# cat resource | head -n10x00000000000005000x00000000000005ff0x0000000000040101
Quoted 8 lines
Quoted 1 line
This was with the commit in question applied.
With all due respect, lkvm has a half-baked implementation of PCI. This is why you have to pass kernel parameters to disable ACPI and disable PCI BIOS probing.
So yeah, you can do funky things in lkvm but that doesn't mean a system that emulated actual hardware would ever do that.
We disable ACPI simply because we don't support it. MPtable is a perfectly valid mechanism to do everything we need so far, so implementing ACPI didn't interest either of us too much. What's more - why implement a "complete design disaster in every way" ;)
Regarding PCI probing, while we do force the use of direct memory probing this is because we lack anything which reassembles a BIOS. Like the above, this wasn't too interesting in a virtualized environment, and the kernel is pretty happy running without it. PCI probing does happen in a standard way.
I think that the interesting part in that test was not that you could actually put a PCI device in the 0x500 range, but that nothing failed and no one yelled at me (with the panic commit applied).
I'm not worried about port 0x505 being taken, I'm worried that it'll silently break a (although not very common/reasonable/typical) perfectly valid use case.
Quoted 40 lines · Sasha Levin
Quoted 39 lines · Anthony Liguori
Quoted 18 lines · Sasha Levin
Quoted 6 lines · Wen Congyang
arch/x86/include/asm/kvm_para.h +2
-0+#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 230
Quoted 8 lines
arch/x86/include/asm/kvm_para.h +5
-0@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +Why is this safe?
Quoted 1 line
I'm not sure you can just pick any ioport you'd like and use it.
There are three ways I/O ports get used on a PC:
1) Platform devices
- This is well defined since the vast majority of platform devices are implemented within a single chip. If you're emulating an i440fx chipset, the PIIX4 spec has an exhaustive list.2) PCI devices
- Typically, PCI only allocates ports starting at0x0d00to avoid conflicts with ISA devices.3) ISA devices
- ISA uses subtractive decoding so any ISA device can access. In theory, an ISA device could attempt to use port0x0505but it's unlikely. In a modern guest, there aren't really any ISA devices being added either.
Quoted 7 lines
Quoted 2 lines
So yes, picking port
0x0505is safe for something like this (as long as you check to make sure that you really are under KVM).Is there anything that actually prevents me from using PCI ports lower than
0x0d00? As you said in (3), ISA isn't really used anymore (nor is implemented by lkvm for example), so placing PCI below0x0d00might even make sense in that case.
On modern systems, the OS goes by whatever is in the ACPI table describing the PCI bus. In QEMU, we have:
WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, // Address Space Granularity
0x0D00, // Address Range Minimum
0xFFFF, // Address Range Maximum
0x0000, // Address Translation Offset
0xF300, // Address Length
,, , TypeStatic)So Linux will always use 0x0D00 -> 0xFFFF for the valid range. Practically speaking, you can't use anything below 0x0D00 because the PCI bus configuration registers live at 0xCF8-0xCFF. If you tried to create the region starting at 0x0500 you'd have to limit it to 0xCF8 to avoid conflicting with the PCI host controller.
That's not a useful amount of space for I/O ports so that would be a pretty dumb thing to do.
Quoted 3 lines
Furthermore, I can place one of these brand new virtio-mmio devices which got introduced recently wherever I want right now - Having a device that uses
0x505would cause a pretty non-obvious failure mode.
I think you're confusing PIO with MMIO. They are separate address spaces.
You could certainly argue that relying on PIO is way too architecture specific since that's only available on x86. That's a good argument but the counter is that other architectures have their own interfaces for this sort of thing.
Quoted 6 lines
Either way, If we are going to grab an ioport, then:
- It should be documented well somewhere in
Documentation/virt/kvm
- It should go throughrequest_region()to actually claim those ioports.
- It should fail gracefully if that port is taken for some reason, instead of not even checking it.
I agree with the above.
Regards,
Anthony Liguori
At 07/23/2012 04:19 AM, Sasha Levin Wrote:
Quoted 43 lines · Anthony Liguori
Quoted 33 lines
Quoted 18 lines · Sasha Levin
Quoted 6 lines · Wen Congyang
arch/x86/include/asm/kvm_para.h +2
-0+#define KVM_PV_PORT (0x505UL) +#ifdef __KERNEL__#include <asm/processor.h> arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 230
Quoted 8 lines
arch/x86/include/asm/kvm_para.h +5
-0@@ -221,6 +223,11 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_PORT ); +} +Why is this safe?
Quoted 1 line
I'm not sure you can just pick any ioport you'd like and use it.
There are three ways I/O ports get used on a PC:
1) Platform devices
- This is well defined since the vast majority of platform devices are implemented within a single chip. If you're emulating an i440fx chipset, the PIIX4 spec has an exhaustive list.2) PCI devices
- Typically, PCI only allocates ports starting at0x0d00to avoid conflicts with ISA devices.Quoted 8 lines
3) ISA devices
- ISA uses subtractive decoding so any ISA device can access. In theory, an ISA device could attempt to use port0x0505but it's unlikely. In a modern guest, there aren't really any ISA devices being added either.So yes, picking port
0x0505is safe for something like this (as long as you check to make sure that you really are under KVM).
Quoted 8 lines
Is there anything that actually prevents me from using PCI ports lower than
0x0d00? As you said in (3), ISA isn't really used anymore (nor is implemented by lkvm for example), so placing PCI below0x0d00might even make sense in that case.Furthermore, I can place one of these brand new virtio-mmio devices which got introduced recently wherever I want right now - Having a device that uses
0x505would cause a pretty non-obvious failure mode.Either way, If we are going to grab an ioport, then:
- It should be documented well somewhere in
Documentation/virt/kvm
- It should go throughrequest_region()to actually claim those ioports.
Good idea.
Quoted 1 line
- It should fail gracefully if that port is taken for some reason, instead of not even checking it.
Yes, I agree it.
I will update it.
Thanks
Wen Congyang
Quoted 6 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/