qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3 v2] Enable and Handle in-kernel watchdog emulation
@ 2012-12-28  5:16 Bharat Bhushan
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 1/3 v2] Synchronized the linux headers Bharat Bhushan
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Bharat Bhushan @ 2012-12-28  5:16 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf; +Cc: Bharat Bhushan

The Patchset enables and handle the in-kernel watchdog emulation
if KVM supports.
The first Patch is synchronizes the Linux-headers as this is needed
for enabling the in-kernel watchdog emulation.
The Second Patch installs the timer reset handler and the Third patch
enables and handles the watchdog exit.

Bharat Bhushan (3):
  Synchronized the linux headers
  Reset qemu timers when guest reset
  Enable kvm emulated watchdog

 hw/ppc.h                                 |    1 +
 hw/ppc_booke.c                           |   48 ++++++++++++++-
 linux-headers/asm-generic/kvm_para.h     |    4 +
 linux-headers/asm-powerpc/epapr_hcalls.h |   98 ++++++++++++++++++++++++++++++
 linux-headers/asm-powerpc/kvm.h          |   86 ++++++++++++++++++++++++++
 linux-headers/asm-powerpc/kvm_para.h     |    7 +-
 linux-headers/linux/kvm.h                |   21 +++++--
 target-ppc/kvm.c                         |   56 +++++++++++++++++
 target-ppc/kvm_ppc.h                     |   11 +++
 9 files changed, 323 insertions(+), 9 deletions(-)
 create mode 100644 linux-headers/asm-generic/kvm_para.h
 create mode 100644 linux-headers/asm-powerpc/epapr_hcalls.h

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 1/3 v2] Synchronized the linux headers
  2012-12-28  5:16 [Qemu-devel] [PATCH 0/3 v2] Enable and Handle in-kernel watchdog emulation Bharat Bhushan
@ 2012-12-28  5:16 ` Bharat Bhushan
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 2/3 v2] Reset qemu timers when guest reset Bharat Bhushan
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 3/3 v2] Enable kvm emulated watchdog Bharat Bhushan
  2 siblings, 0 replies; 14+ messages in thread
From: Bharat Bhushan @ 2012-12-28  5:16 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf; +Cc: Bharat Bhushan

This is needed for the watchdog patches (follow up patches)

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 v2: same as v1

 linux-headers/asm-generic/kvm_para.h     |    4 +
 linux-headers/asm-powerpc/epapr_hcalls.h |   98 ++++++++++++++++++++++++++++++
 linux-headers/asm-powerpc/kvm.h          |   86 ++++++++++++++++++++++++++
 linux-headers/asm-powerpc/kvm_para.h     |    7 +-
 linux-headers/linux/kvm.h                |   21 +++++--
 5 files changed, 208 insertions(+), 8 deletions(-)
 create mode 100644 linux-headers/asm-generic/kvm_para.h
 create mode 100644 linux-headers/asm-powerpc/epapr_hcalls.h

diff --git a/linux-headers/asm-generic/kvm_para.h b/linux-headers/asm-generic/kvm_para.h
new file mode 100644
index 0000000..486f0af
--- /dev/null
+++ b/linux-headers/asm-generic/kvm_para.h
@@ -0,0 +1,4 @@
+/*
+ * There isn't anything here, but the file must not be empty or patch
+ * will delete it.
+ */
diff --git a/linux-headers/asm-powerpc/epapr_hcalls.h b/linux-headers/asm-powerpc/epapr_hcalls.h
new file mode 100644
index 0000000..7f9c74b
--- /dev/null
+++ b/linux-headers/asm-powerpc/epapr_hcalls.h
@@ -0,0 +1,98 @@
+/*
+ * ePAPR hcall interface
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ *
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * This file is provided under a dual BSD/GPL license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UAPI_ASM_POWERPC_EPAPR_HCALLS_H
+#define _UAPI_ASM_POWERPC_EPAPR_HCALLS_H
+
+#define EV_BYTE_CHANNEL_SEND		1
+#define EV_BYTE_CHANNEL_RECEIVE		2
+#define EV_BYTE_CHANNEL_POLL		3
+#define EV_INT_SET_CONFIG		4
+#define EV_INT_GET_CONFIG		5
+#define EV_INT_SET_MASK			6
+#define EV_INT_GET_MASK			7
+#define EV_INT_IACK			9
+#define EV_INT_EOI			10
+#define EV_INT_SEND_IPI			11
+#define EV_INT_SET_TASK_PRIORITY	12
+#define EV_INT_GET_TASK_PRIORITY	13
+#define EV_DOORBELL_SEND		14
+#define EV_MSGSND			15
+#define EV_IDLE				16
+
+/* vendor ID: epapr */
+#define EV_LOCAL_VENDOR_ID		0	/* for private use */
+#define EV_EPAPR_VENDOR_ID		1
+#define EV_FSL_VENDOR_ID		2	/* Freescale Semiconductor */
+#define EV_IBM_VENDOR_ID		3	/* IBM */
+#define EV_GHS_VENDOR_ID		4	/* Green Hills Software */
+#define EV_ENEA_VENDOR_ID		5	/* Enea */
+#define EV_WR_VENDOR_ID			6	/* Wind River Systems */
+#define EV_AMCC_VENDOR_ID		7	/* Applied Micro Circuits */
+#define EV_KVM_VENDOR_ID		42	/* KVM */
+
+/* The max number of bytes that a byte channel can send or receive per call */
+#define EV_BYTE_CHANNEL_MAX_BYTES	16
+
+
+#define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num))
+#define EV_HCALL_TOKEN(hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num)
+
+/* epapr return codes */
+#define EV_SUCCESS		0
+#define EV_EPERM		1	/* Operation not permitted */
+#define EV_ENOENT		2	/*  Entry Not Found */
+#define EV_EIO			3	/* I/O error occured */
+#define EV_EAGAIN		4	/* The operation had insufficient
+					 * resources to complete and should be
+					 * retried
+					 */
+#define EV_ENOMEM		5	/* There was insufficient memory to
+					 * complete the operation */
+#define EV_EFAULT		6	/* Bad guest address */
+#define EV_ENODEV		7	/* No such device */
+#define EV_EINVAL		8	/* An argument supplied to the hcall
+					   was out of range or invalid */
+#define EV_INTERNAL		9	/* An internal error occured */
+#define EV_CONFIG		10	/* A configuration error was detected */
+#define EV_INVALID_STATE	11	/* The object is in an invalid state */
+#define EV_UNIMPLEMENTED	12	/* Unimplemented hypercall */
+#define EV_BUFFER_OVERFLOW	13	/* Caller-supplied buffer too small */
+
+#endif /* _UAPI_ASM_POWERPC_EPAPR_HCALLS_H */
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 1bea4d8..2fba8a6 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -221,6 +221,12 @@ struct kvm_sregs {
 
 			__u32 dbsr;	/* KVM_SREGS_E_UPDATE_DBSR */
 			__u32 dbcr[3];
+			/*
+			 * iac/dac registers are 64bit wide, while this API
+			 * interface provides only lower 32 bits on 64 bit
+			 * processors. ONE_REG interface is added for 64bit
+			 * iac/dac registers.
+			 */
 			__u32 iac[4];
 			__u32 dac[2];
 			__u32 dvc[2];
@@ -325,6 +331,86 @@ struct kvm_book3e_206_tlb_params {
 	__u32 reserved[8];
 };
 
+/* For KVM_PPC_GET_HTAB_FD */
+struct kvm_get_htab_fd {
+	__u64	flags;
+	__u64	start_index;
+	__u64	reserved[2];
+};
+
+/* Values for kvm_get_htab_fd.flags */
+#define KVM_GET_HTAB_BOLTED_ONLY	((__u64)0x1)
+#define KVM_GET_HTAB_WRITE		((__u64)0x2)
+
+/*
+ * Data read on the file descriptor is formatted as a series of
+ * records, each consisting of a header followed by a series of
+ * `n_valid' HPTEs (16 bytes each), which are all valid.  Following
+ * those valid HPTEs there are `n_invalid' invalid HPTEs, which
+ * are not represented explicitly in the stream.  The same format
+ * is used for writing.
+ */
+struct kvm_get_htab_header {
+	__u32	index;
+	__u16	n_valid;
+	__u16	n_invalid;
+};
+
 #define KVM_REG_PPC_HIOR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
+#define KVM_REG_PPC_IAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
+#define KVM_REG_PPC_IAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
+#define KVM_REG_PPC_IAC3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4)
+#define KVM_REG_PPC_IAC4	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5)
+#define KVM_REG_PPC_DAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6)
+#define KVM_REG_PPC_DAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7)
+#define KVM_REG_PPC_DABR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8)
+#define KVM_REG_PPC_DSCR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9)
+#define KVM_REG_PPC_PURR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa)
+#define KVM_REG_PPC_SPURR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb)
+#define KVM_REG_PPC_DAR		(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc)
+#define KVM_REG_PPC_DSISR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xd)
+#define KVM_REG_PPC_AMR		(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xe)
+#define KVM_REG_PPC_UAMOR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xf)
+
+#define KVM_REG_PPC_MMCR0	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x10)
+#define KVM_REG_PPC_MMCR1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x11)
+#define KVM_REG_PPC_MMCRA	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x12)
+
+#define KVM_REG_PPC_PMC1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x18)
+#define KVM_REG_PPC_PMC2	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x19)
+#define KVM_REG_PPC_PMC3	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1a)
+#define KVM_REG_PPC_PMC4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1b)
+#define KVM_REG_PPC_PMC5	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1c)
+#define KVM_REG_PPC_PMC6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1d)
+#define KVM_REG_PPC_PMC7	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1e)
+#define KVM_REG_PPC_PMC8	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1f)
+
+/* 32 floating-point registers */
+#define KVM_REG_PPC_FPR0	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x20)
+#define KVM_REG_PPC_FPR(n)	(KVM_REG_PPC_FPR0 + (n))
+#define KVM_REG_PPC_FPR31	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3f)
+
+/* 32 VMX/Altivec vector registers */
+#define KVM_REG_PPC_VR0		(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x40)
+#define KVM_REG_PPC_VR(n)	(KVM_REG_PPC_VR0 + (n))
+#define KVM_REG_PPC_VR31	(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x5f)
+
+/* 32 double-width FP registers for VSX */
+/* High-order halves overlap with FP regs */
+#define KVM_REG_PPC_VSR0	(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x60)
+#define KVM_REG_PPC_VSR(n)	(KVM_REG_PPC_VSR0 + (n))
+#define KVM_REG_PPC_VSR31	(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x7f)
+
+/* FP and vector status/control registers */
+#define KVM_REG_PPC_FPSCR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x80)
+#define KVM_REG_PPC_VSCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x81)
+
+/* Virtual processor areas */
+/* For SLB & DTL, address in high (first) half, length in low half */
+#define KVM_REG_PPC_VPA_ADDR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x82)
+#define KVM_REG_PPC_VPA_SLB	(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x83)
+#define KVM_REG_PPC_VPA_DTL	(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
+
+#define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
 
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/linux-headers/asm-powerpc/kvm_para.h b/linux-headers/asm-powerpc/kvm_para.h
index 5e04383..e3af328 100644
--- a/linux-headers/asm-powerpc/kvm_para.h
+++ b/linux-headers/asm-powerpc/kvm_para.h
@@ -75,9 +75,10 @@ struct kvm_vcpu_arch_shared {
 };
 
 #define KVM_SC_MAGIC_R0		0x4b564d21 /* "KVM!" */
-#define HC_VENDOR_KVM		(42 << 16)
-#define HC_EV_SUCCESS		0
-#define HC_EV_UNIMPLEMENTED	12
+
+#define KVM_HCALL_TOKEN(num)     _EV_HCALL_TOKEN(EV_KVM_VENDOR_ID, num)
+
+#include <asm/epapr_hcalls.h>
 
 #define KVM_FEATURE_MAGIC_PAGE	1
 
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 81d2feb..bfdbf4d 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -167,10 +167,15 @@ struct kvm_pit_config {
 #define KVM_EXIT_OSI              18
 #define KVM_EXIT_PAPR_HCALL	  19
 #define KVM_EXIT_S390_UCONTROL	  20
+#define KVM_EXIT_WATCHDOG         21
 
 /* For KVM_EXIT_INTERNAL_ERROR */
-#define KVM_INTERNAL_ERROR_EMULATION 1
-#define KVM_INTERNAL_ERROR_SIMUL_EX 2
+/* Emulate instruction failed. */
+#define KVM_INTERNAL_ERROR_EMULATION	1
+/* Encounter unexpected simultaneous exceptions. */
+#define KVM_INTERNAL_ERROR_SIMUL_EX	2
+/* Encounter unexpected vm-exit due to delivery event. */
+#define KVM_INTERNAL_ERROR_DELIVERY_EV	3
 
 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
 struct kvm_run {
@@ -477,6 +482,8 @@ struct kvm_ppc_smmu_info {
 	struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
 };
 
+#define KVM_PPC_PVINFO_FLAGS_EV_IDLE   (1<<0)
+
 #define KVMIO 0xAE
 
 /* machine type bits, to be used as argument to KVM_CREATE_VM */
@@ -626,6 +633,8 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_READONLY_MEM 81
 #endif
 #define KVM_CAP_IRQFD_RESAMPLE 82
+#define KVM_CAP_PPC_BOOKE_WATCHDOG 83
+#define KVM_CAP_PPC_HTAB_FD 84
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -848,6 +857,11 @@ struct kvm_s390_ucas_mapping {
 #define KVM_PPC_GET_SMMU_INFO	  _IOR(KVMIO,  0xa6, struct kvm_ppc_smmu_info)
 /* Available with KVM_CAP_PPC_ALLOC_HTAB */
 #define KVM_PPC_ALLOCATE_HTAB	  _IOWR(KVMIO, 0xa7, __u32)
+#define KVM_CREATE_SPAPR_TCE	  _IOW(KVMIO,  0xa8, struct kvm_create_spapr_tce)
+/* Available with KVM_CAP_RMA */
+#define KVM_ALLOCATE_RMA	  _IOR(KVMIO,  0xa9, struct kvm_allocate_rma)
+/* Available with KVM_CAP_PPC_HTAB_FD */
+#define KVM_PPC_GET_HTAB_FD	  _IOW(KVMIO,  0xaa, struct kvm_get_htab_fd)
 
 /*
  * ioctls for vcpu fds
@@ -911,9 +925,6 @@ struct kvm_s390_ucas_mapping {
 /* Available with KVM_CAP_XCRS */
 #define KVM_GET_XCRS		  _IOR(KVMIO,  0xa6, struct kvm_xcrs)
 #define KVM_SET_XCRS		  _IOW(KVMIO,  0xa7, struct kvm_xcrs)
-#define KVM_CREATE_SPAPR_TCE	  _IOW(KVMIO,  0xa8, struct kvm_create_spapr_tce)
-/* Available with KVM_CAP_RMA */
-#define KVM_ALLOCATE_RMA	  _IOR(KVMIO,  0xa9, struct kvm_allocate_rma)
 /* Available with KVM_CAP_SW_TLB */
 #define KVM_DIRTY_TLB		  _IOW(KVMIO,  0xaa, struct kvm_dirty_tlb)
 /* Available with KVM_CAP_ONE_REG */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 2/3 v2] Reset qemu timers when guest reset
  2012-12-28  5:16 [Qemu-devel] [PATCH 0/3 v2] Enable and Handle in-kernel watchdog emulation Bharat Bhushan
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 1/3 v2] Synchronized the linux headers Bharat Bhushan
@ 2012-12-28  5:16 ` Bharat Bhushan
  2013-01-03 14:10   ` Alexander Graf
  2013-01-03 20:20   ` [Qemu-devel] [Qemu-ppc] " Scott Wood
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 3/3 v2] Enable kvm emulated watchdog Bharat Bhushan
  2 siblings, 2 replies; 14+ messages in thread
From: Bharat Bhushan @ 2012-12-28  5:16 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf; +Cc: Bharat Bhushan

This patch install the timer reset handler. This will be called when
the guest is reset.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 v2: same as v1

 hw/ppc_booke.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c
index d51e7fa..837a5b6 100644
--- a/hw/ppc_booke.c
+++ b/hw/ppc_booke.c
@@ -231,6 +231,16 @@ void store_booke_tcr(CPUPPCState *env, target_ulong val)
 
 }
 
+static void ppc_booke_timer_reset_handle(void *opaque)
+{
+    CPUPPCState *env = opaque;
+
+    env->spr[SPR_BOOKE_TSR] = 0;
+    env->spr[SPR_BOOKE_TCR] = 0;
+
+    booke_update_irq(env);
+}
+
 void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags)
 {
     ppc_tb_t *tb_env;
@@ -251,4 +261,6 @@ void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags)
         qemu_new_timer_ns(vm_clock, &booke_fit_cb, env);
     booke_timer->wdt_timer =
         qemu_new_timer_ns(vm_clock, &booke_wdt_cb, env);
+
+    qemu_register_reset(ppc_booke_timer_reset_handle, env);
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 3/3 v2] Enable kvm emulated watchdog
  2012-12-28  5:16 [Qemu-devel] [PATCH 0/3 v2] Enable and Handle in-kernel watchdog emulation Bharat Bhushan
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 1/3 v2] Synchronized the linux headers Bharat Bhushan
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 2/3 v2] Reset qemu timers when guest reset Bharat Bhushan
@ 2012-12-28  5:16 ` Bharat Bhushan
  2013-01-10 15:36   ` Alexander Graf
  2 siblings, 1 reply; 14+ messages in thread
From: Bharat Bhushan @ 2012-12-28  5:16 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, agraf; +Cc: Bharat Bhushan

Enable the KVM emulated watchdog if KVM supports (use the
capability enablement in watchdog handler). Also watchdog exit
(KVM_EXIT_WATCHDOG) handling is added.
Watchdog state machine is cleared whenever VM state changes to running.
This is to handle the cases like return from debug halt etc.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 v2:
  - access cap_* from target_ppc/kvm.c only.
  - Added wrapper functions in target_ppc/kvm.c for
    enable_watchdog and tsr_sregs synchronization.
  - Incorporated other Review comments

 hw/ppc.h             |    1 +
 hw/ppc_booke.c       |   36 +++++++++++++++++++++++++++++++-
 target-ppc/kvm.c     |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/kvm_ppc.h |   11 +++++++++
 4 files changed, 103 insertions(+), 1 deletions(-)

diff --git a/hw/ppc.h b/hw/ppc.h
index 2f3ea27..6ad9e1f 100644
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -90,3 +90,4 @@ enum {
 
 /* ppc_booke.c */
 void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags);
+void ppc_booke_watchdog_clear_tsr(CPUPPCState *env);
diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c
index 837a5b6..7273259 100644
--- a/hw/ppc_booke.c
+++ b/hw/ppc_booke.c
@@ -28,7 +28,7 @@
 #include "nvram.h"
 #include "qemu-log.h"
 #include "loader.h"
-
+#include "kvm_ppc.h"
 
 /* Timer Control Register */
 
@@ -203,6 +203,11 @@ static void booke_wdt_cb(void *opaque)
                              booke_timer->wdt_timer);
 }
 
+void ppc_booke_watchdog_clear_tsr(CPUPPCState *env)
+{
+    env->spr[SPR_BOOKE_TSR] &= ~(TSR_ENW | TSR_WIS | TSR_WRS_MASK);
+}
+
 void store_booke_tsr(CPUPPCState *env, target_ulong val)
 {
     env->spr[SPR_BOOKE_TSR] &= ~val;
@@ -241,10 +246,27 @@ static void ppc_booke_timer_reset_handle(void *opaque)
     booke_update_irq(env);
 }
 
+static void cpu_state_change_handler(void *opaque, int running, RunState state)
+{
+    CPUPPCState *env = opaque;
+
+    if (!running) {
+        return;
+    }
+
+    /*
+     * Clear watchdog interrupt condition by clearing TSR.
+     */
+    ppc_booke_watchdog_clear_tsr(env);
+
+    kvmppc_synch_sregs_tsr(env);
+}
+
 void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags)
 {
     ppc_tb_t *tb_env;
     booke_timer_t *booke_timer;
+    int ret = 0;
 
     tb_env      = g_malloc0(sizeof(ppc_tb_t));
     booke_timer = g_malloc0(sizeof(booke_timer_t));
@@ -262,5 +284,17 @@ void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags)
     booke_timer->wdt_timer =
         qemu_new_timer_ns(vm_clock, &booke_wdt_cb, env);
 
+    ret = kvmppc_booke_watchdog_enable(env);
+
+    if (ret) {
+        /* TODO: Start the QEMU emulated watchdog if not running on KVM.
+         * Also start the QEMU emulated watchdog if KVM does not support
+         * emulated watchdog or somehow it is not enabled (supported but
+         * not enabled is though some bug and requires debugging :)).
+         */
+    }
+
+    qemu_add_vm_change_state_handler(cpu_state_change_handler, env);
+
     qemu_register_reset(ppc_booke_timer_reset_handle, env);
 }
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 3f5df57..6828afa 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -32,10 +32,12 @@
 #include "device_tree.h"
 #include "hw/sysbus.h"
 #include "hw/spapr.h"
+#include "hw/watchdog.h"
 
 #include "hw/sysbus.h"
 #include "hw/spapr.h"
 #include "hw/spapr_vio.h"
+#include "hw/ppc.h"
 
 //#define DEBUG_KVM
 
@@ -61,6 +63,7 @@ static int cap_ppc_smt;
 static int cap_ppc_rma;
 static int cap_spapr_tce;
 static int cap_hior;
+static int cap_ppc_watchdog;
 
 /* XXX We have a race condition where we actually have a level triggered
  *     interrupt, but the infrastructure can't expose that yet, so the guest
@@ -90,6 +93,7 @@ int kvm_arch_init(KVMState *s)
     cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
     cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
     cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
+    cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
 
     if (!cap_interrupt_level) {
         fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
@@ -823,6 +827,12 @@ int kvm_arch_handle_exit(CPUPPCState *env, struct kvm_run *run)
         ret = 0;
         break;
 #endif
+    case KVM_EXIT_WATCHDOG:
+        dprintf("handle watchdog expiry\n");
+        watchdog_perform_action();
+        ret = 0;
+        break;
+
     default:
         fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
         ret = -1;
@@ -1239,3 +1249,49 @@ int kvm_arch_on_sigbus(int code, void *addr)
 {
     return 1;
 }
+
+int kvmppc_synch_sregs_tsr(CPUPPCState *env)
+{
+    struct kvm_sregs sregs;
+    int ret;
+
+    if (!kvm_enabled() || !cap_booke_sregs ||  !cap_ppc_watchdog) {
+        return -1;
+    }
+
+    ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
+
+    env->spr[SPR_BOOKE_TSR] = sregs.u.e.tsr;
+    ppc_booke_watchdog_clear_tsr(env);
+    sregs.u.e.tsr = env->spr[SPR_BOOKE_TSR];
+    sregs.u.e.update_special = KVM_SREGS_E_UPDATE_TSR;
+
+    ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
+
+    return ret;
+}
+
+int kvmppc_booke_watchdog_enable(CPUPPCState *env)
+{
+    int ret;
+    struct kvm_enable_cap encap = {};
+
+    if (!kvm_enabled()) {
+        return -1;
+    }
+
+    if (!cap_ppc_watchdog) {
+        printf("warning: KVM does not support watchdog");
+        return -1;
+    }
+
+    encap.cap = KVM_CAP_PPC_BOOKE_WATCHDOG;
+    ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &encap);
+    if (ret < 0) {
+        fprintf(stderr, "%s: couldn't enable KVM_CAP_PPC_BOOKE_WATCHDOG: %s\n",
+                __func__, strerror(-ret));
+        return ret;
+    }
+
+    return ret;
+}
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index baad6eb..4ccc9fa 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -23,6 +23,8 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
 int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level);
 void kvmppc_set_papr(CPUPPCState *env);
 int kvmppc_smt_threads(void);
+int kvmppc_synch_sregs_tsr(CPUPPCState *cenv);
+int kvmppc_booke_watchdog_enable(CPUPPCState *env);
 #ifndef CONFIG_USER_ONLY
 off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
 void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
@@ -79,6 +81,15 @@ static inline int kvmppc_smt_threads(void)
     return 1;
 }
 
+static inline int kvmppc_synch_sregs_tsr(CPUPPCState *env)
+{
+    return -1;
+}
+
+static inline int kvmppc_booke_watchdog_enable(CPUPPCState *env)
+{
+    return -1;
+}
 #ifndef CONFIG_USER_ONLY
 static inline off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
 {
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3 v2] Reset qemu timers when guest reset
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 2/3 v2] Reset qemu timers when guest reset Bharat Bhushan
@ 2013-01-03 14:10   ` Alexander Graf
  2013-01-03 20:20   ` [Qemu-devel] [Qemu-ppc] " Scott Wood
  1 sibling, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2013-01-03 14:10 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: Bharat Bhushan, qemu-ppc, qemu-devel


On 28.12.2012, at 06:16, Bharat Bhushan wrote:

> This patch install the timer reset handler. This will be called when
> the guest is reset.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>

Thanks, adjusted to the current QOM'ified code and applied this patch.


Alex

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/3 v2] Reset qemu timers when guest reset
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 2/3 v2] Reset qemu timers when guest reset Bharat Bhushan
  2013-01-03 14:10   ` Alexander Graf
@ 2013-01-03 20:20   ` Scott Wood
  2013-01-03 20:33     ` Alexander Graf
  2013-01-04  1:28     ` Bhushan Bharat-R65777
  1 sibling, 2 replies; 14+ messages in thread
From: Scott Wood @ 2013-01-03 20:20 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: Bharat Bhushan, qemu-ppc, qemu-devel, agraf

On 12/27/2012 11:16:51 PM, Bharat Bhushan wrote:
> This patch install the timer reset handler. This will be called when
> the guest is reset.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
>  v2: same as v1
> 
>  hw/ppc_booke.c |   12 ++++++++++++
>  1 files changed, 12 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c
> index d51e7fa..837a5b6 100644
> --- a/hw/ppc_booke.c
> +++ b/hw/ppc_booke.c
> @@ -231,6 +231,16 @@ void store_booke_tcr(CPUPPCState *env,  
> target_ulong val)
> 
>  }
> 
> +static void ppc_booke_timer_reset_handle(void *opaque)
> +{
> +    CPUPPCState *env = opaque;
> +
> +    env->spr[SPR_BOOKE_TSR] = 0;
> +    env->spr[SPR_BOOKE_TCR] = 0;
> +
> +    booke_update_irq(env);
> +}

When does KVM_SET_SREGS get called?

-Scott

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/3 v2] Reset qemu timers when guest reset
  2013-01-03 20:20   ` [Qemu-devel] [Qemu-ppc] " Scott Wood
@ 2013-01-03 20:33     ` Alexander Graf
  2013-01-03 20:37       ` Scott Wood
  2013-01-04  1:28     ` Bhushan Bharat-R65777
  1 sibling, 1 reply; 14+ messages in thread
From: Alexander Graf @ 2013-01-03 20:33 UTC (permalink / raw)
  To: Scott Wood
  Cc: Bharat Bhushan, <qemu-ppc@nongnu.org>,
	<qemu-devel@nongnu.org>, Bharat Bhushan



Am 03.01.2013 um 21:20 schrieb Scott Wood <scottwood@freescale.com>:

> On 12/27/2012 11:16:51 PM, Bharat Bhushan wrote:
>> This patch install the timer reset handler. This will be called when
>> the guest is reset.
>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>> ---
>> v2: same as v1
>> hw/ppc_booke.c |   12 ++++++++++++
>> 1 files changed, 12 insertions(+), 0 deletions(-)
>> diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c
>> index d51e7fa..837a5b6 100644
>> --- a/hw/ppc_booke.c
>> +++ b/hw/ppc_booke.c
>> @@ -231,6 +231,16 @@ void store_booke_tcr(CPUPPCState *env, target_ulong val)
>> }
>> +static void ppc_booke_timer_reset_handle(void *opaque)
>> +{
>> +    CPUPPCState *env = opaque;
>> +
>> +    env->spr[SPR_BOOKE_TSR] = 0;
>> +    env->spr[SPR_BOOKE_TCR] = 0;
>> +
>> +    booke_update_irq(env);
>> +}
> 
> When does KVM_SET_SREGS get called?

That's up to the next patch. 

Alex

> 
> -Scott

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/3 v2] Reset qemu timers when guest reset
  2013-01-03 20:33     ` Alexander Graf
@ 2013-01-03 20:37       ` Scott Wood
  2013-01-03 20:48         ` Alexander Graf
  0 siblings, 1 reply; 14+ messages in thread
From: Scott Wood @ 2013-01-03 20:37 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Bharat Bhushan, <qemu-ppc@nongnu.org>,
	<qemu-devel@nongnu.org>, Bharat Bhushan

On 01/03/2013 02:33:39 PM, Alexander Graf wrote:
> 
> 
> Am 03.01.2013 um 21:20 schrieb Scott Wood <scottwood@freescale.com>:
> 
> > On 12/27/2012 11:16:51 PM, Bharat Bhushan wrote:
> >> This patch install the timer reset handler. This will be called  
> when
> >> the guest is reset.
> >> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >> ---
> >> v2: same as v1
> >> hw/ppc_booke.c |   12 ++++++++++++
> >> 1 files changed, 12 insertions(+), 0 deletions(-)
> >> diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c
> >> index d51e7fa..837a5b6 100644
> >> --- a/hw/ppc_booke.c
> >> +++ b/hw/ppc_booke.c
> >> @@ -231,6 +231,16 @@ void store_booke_tcr(CPUPPCState *env,  
> target_ulong val)
> >> }
> >> +static void ppc_booke_timer_reset_handle(void *opaque)
> >> +{
> >> +    CPUPPCState *env = opaque;
> >> +
> >> +    env->spr[SPR_BOOKE_TSR] = 0;
> >> +    env->spr[SPR_BOOKE_TCR] = 0;
> >> +
> >> +    booke_update_irq(env);
> >> +}
> >
> > When does KVM_SET_SREGS get called?
> 
> That's up to the next patch.

The watchdog one?  I don't see any direct connection to this function.   
Does a reset always involve a CPU state change?  If that's what we're  
relying on, it least deserves a code comment in this function.   
Otherwise it looks like no special handling is required when setting  
SREG SPRs in KVM-compatible code (i.e. not code that is only used in  
TCG mode).

-Scott

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/3 v2] Reset qemu timers when guest reset
  2013-01-03 20:37       ` Scott Wood
@ 2013-01-03 20:48         ` Alexander Graf
  0 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2013-01-03 20:48 UTC (permalink / raw)
  To: Scott Wood
  Cc: Bharat Bhushan, <qemu-ppc@nongnu.org>,
	<qemu-devel@nongnu.org>, Bharat Bhushan


On 03.01.2013, at 21:37, Scott Wood wrote:

> On 01/03/2013 02:33:39 PM, Alexander Graf wrote:
>> Am 03.01.2013 um 21:20 schrieb Scott Wood <scottwood@freescale.com>:
>> > On 12/27/2012 11:16:51 PM, Bharat Bhushan wrote:
>> >> This patch install the timer reset handler. This will be called when
>> >> the guest is reset.
>> >> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>> >> ---
>> >> v2: same as v1
>> >> hw/ppc_booke.c |   12 ++++++++++++
>> >> 1 files changed, 12 insertions(+), 0 deletions(-)
>> >> diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c
>> >> index d51e7fa..837a5b6 100644
>> >> --- a/hw/ppc_booke.c
>> >> +++ b/hw/ppc_booke.c
>> >> @@ -231,6 +231,16 @@ void store_booke_tcr(CPUPPCState *env, target_ulong val)
>> >> }
>> >> +static void ppc_booke_timer_reset_handle(void *opaque)
>> >> +{
>> >> +    CPUPPCState *env = opaque;
>> >> +
>> >> +    env->spr[SPR_BOOKE_TSR] = 0;
>> >> +    env->spr[SPR_BOOKE_TCR] = 0;
>> >> +
>> >> +    booke_update_irq(env);
>> >> +}
>> >
>> > When does KVM_SET_SREGS get called?
>> That's up to the next patch.
> 
> The watchdog one?  I don't see any direct connection to this function.  Does a reset always involve a CPU state change?  If that's what we're relying on, it least deserves a code comment in this function.  Otherwise it looks like no special handling is required when setting SREG SPRs in KVM-compatible code (i.e. not code that is only used in TCG mode).

That's why we want an indication to the lower levels that TSR changed. Basically the code would look like:

cpu_synchronize_register_set(BOOKE_TIMERS); /* fetches current TSR, indicates internally that TSR is potentially dirty */
env->spr[TSR] = 0;

at which point the kvm entry code would know that it needs to write back TSR. Today, the infrastructure for that is missing, but Bharat is working on it.


Alex

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/3 v2] Reset qemu timers when guest reset
  2013-01-03 20:20   ` [Qemu-devel] [Qemu-ppc] " Scott Wood
  2013-01-03 20:33     ` Alexander Graf
@ 2013-01-04  1:28     ` Bhushan Bharat-R65777
  2013-01-04 15:58       ` Scott Wood
  1 sibling, 1 reply; 14+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-04  1:28 UTC (permalink / raw)
  To: Wood Scott-B07421
  Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, agraf@suse.de



> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Friday, January 04, 2013 1:51 AM
> To: Bhushan Bharat-R65777
> Cc: qemu-devel@nongnu.org; qemu-ppc@nongnu.org; agraf@suse.de; Bhushan Bharat-
> R65777
> Subject: Re: [Qemu-ppc] [PATCH 2/3 v2] Reset qemu timers when guest reset
> 
> On 12/27/2012 11:16:51 PM, Bharat Bhushan wrote:
> > This patch install the timer reset handler. This will be called when
> > the guest is reset.
> >
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> >  v2: same as v1
> >
> >  hw/ppc_booke.c |   12 ++++++++++++
> >  1 files changed, 12 insertions(+), 0 deletions(-)
> >
> > diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c index d51e7fa..837a5b6
> > 100644
> > --- a/hw/ppc_booke.c
> > +++ b/hw/ppc_booke.c
> > @@ -231,6 +231,16 @@ void store_booke_tcr(CPUPPCState *env,
> > target_ulong val)
> >
> >  }
> >
> > +static void ppc_booke_timer_reset_handle(void *opaque) {
> > +    CPUPPCState *env = opaque;
> > +
> > +    env->spr[SPR_BOOKE_TSR] = 0;
> > +    env->spr[SPR_BOOKE_TCR] = 0;
> > +
> > +    booke_update_irq(env);
> > +}
> 
> When does KVM_SET_SREGS get called?

This is part of reset processing and is not cpu_synchronize_state() called before all reset handlers are called and after that post_synchronize will do the KVM_SET_SREGS in kvm_put_registers().

Thanks
-Bharat

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/3 v2] Reset qemu timers when guest reset
  2013-01-04  1:28     ` Bhushan Bharat-R65777
@ 2013-01-04 15:58       ` Scott Wood
  0 siblings, 0 replies; 14+ messages in thread
From: Scott Wood @ 2013-01-04 15:58 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Wood Scott-B07421, qemu-ppc@nongnu.org, qemu-devel@nongnu.org,
	agraf@suse.de

On 01/03/2013 07:28:49 PM, Bhushan Bharat-R65777 wrote:
> 
> 
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Friday, January 04, 2013 1:51 AM
> > To: Bhushan Bharat-R65777
> > Cc: qemu-devel@nongnu.org; qemu-ppc@nongnu.org; agraf@suse.de;  
> Bhushan Bharat-
> > R65777
> > Subject: Re: [Qemu-ppc] [PATCH 2/3 v2] Reset qemu timers when guest  
> reset
> >
> > On 12/27/2012 11:16:51 PM, Bharat Bhushan wrote:
> > > This patch install the timer reset handler. This will be called  
> when
> > > the guest is reset.
> > >
> > > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > > ---
> > >  v2: same as v1
> > >
> > >  hw/ppc_booke.c |   12 ++++++++++++
> > >  1 files changed, 12 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c index  
> d51e7fa..837a5b6
> > > 100644
> > > --- a/hw/ppc_booke.c
> > > +++ b/hw/ppc_booke.c
> > > @@ -231,6 +231,16 @@ void store_booke_tcr(CPUPPCState *env,
> > > target_ulong val)
> > >
> > >  }
> > >
> > > +static void ppc_booke_timer_reset_handle(void *opaque) {
> > > +    CPUPPCState *env = opaque;
> > > +
> > > +    env->spr[SPR_BOOKE_TSR] = 0;
> > > +    env->spr[SPR_BOOKE_TCR] = 0;
> > > +
> > > +    booke_update_irq(env);
> > > +}
> >
> > When does KVM_SET_SREGS get called?
> 
> This is part of reset processing and is not cpu_synchronize_state()  
> called before all reset handlers are called and after that  
> post_synchronize will do the KVM_SET_SREGS in kvm_put_registers().

cpu_synchronize_state() does not do KVM_SET_SREGS.  I don't see  
"post_synchronize" anywhere in the QEMU sources.

As Alex said, there needs to be a way for this function to set a flag  
that TCR and TSR have been dirtied.

-Scott

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 3/3 v2] Enable kvm emulated watchdog
  2012-12-28  5:16 ` [Qemu-devel] [PATCH 3/3 v2] Enable kvm emulated watchdog Bharat Bhushan
@ 2013-01-10 15:36   ` Alexander Graf
  2013-01-11  6:42     ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 14+ messages in thread
From: Alexander Graf @ 2013-01-10 15:36 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: Bharat Bhushan, qemu-ppc, qemu-devel


On 28.12.2012, at 06:16, Bharat Bhushan wrote:

> Enable the KVM emulated watchdog if KVM supports (use the
> capability enablement in watchdog handler). Also watchdog exit
> (KVM_EXIT_WATCHDOG) handling is added.
> Watchdog state machine is cleared whenever VM state changes to running.
> This is to handle the cases like return from debug halt etc.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> v2:
>  - access cap_* from target_ppc/kvm.c only.
>  - Added wrapper functions in target_ppc/kvm.c for
>    enable_watchdog and tsr_sregs synchronization.
>  - Incorporated other Review comments
> 
> hw/ppc.h             |    1 +
> hw/ppc_booke.c       |   36 +++++++++++++++++++++++++++++++-
> target-ppc/kvm.c     |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++
> target-ppc/kvm_ppc.h |   11 +++++++++
> 4 files changed, 103 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/ppc.h b/hw/ppc.h
> index 2f3ea27..6ad9e1f 100644
> --- a/hw/ppc.h
> +++ b/hw/ppc.h
> @@ -90,3 +90,4 @@ enum {
> 
> /* ppc_booke.c */
> void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags);
> +void ppc_booke_watchdog_clear_tsr(CPUPPCState *env);
> diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c
> index 837a5b6..7273259 100644
> --- a/hw/ppc_booke.c
> +++ b/hw/ppc_booke.c
> @@ -28,7 +28,7 @@
> #include "nvram.h"
> #include "qemu-log.h"
> #include "loader.h"
> -
> +#include "kvm_ppc.h"
> 
> /* Timer Control Register */
> 
> @@ -203,6 +203,11 @@ static void booke_wdt_cb(void *opaque)
>                              booke_timer->wdt_timer);
> }
> 
> +void ppc_booke_watchdog_clear_tsr(CPUPPCState *env)
> +{
> +    env->spr[SPR_BOOKE_TSR] &= ~(TSR_ENW | TSR_WIS | TSR_WRS_MASK);
> +}
> +
> void store_booke_tsr(CPUPPCState *env, target_ulong val)
> {
>     env->spr[SPR_BOOKE_TSR] &= ~val;
> @@ -241,10 +246,27 @@ static void ppc_booke_timer_reset_handle(void *opaque)
>     booke_update_irq(env);
> }
> 
> +static void cpu_state_change_handler(void *opaque, int running, RunState state)
> +{

Needs a comment when this happens

> +    CPUPPCState *env = opaque;
> +
> +    if (!running) {
> +        return;
> +    }
> +
> +    /*
> +     * Clear watchdog interrupt condition by clearing TSR.
> +     */
> +    ppc_booke_watchdog_clear_tsr(env);
> +
> +    kvmppc_synch_sregs_tsr(env);

kvmppc_sync_tsr. Also please add the sync to store_booke_tsr(). Then here, you can just do

  store_booke_tsr(TSR_ENW | TSR_WIS | TSR_WRS_MASK);

> +}
> +
> void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags)
> {
>     ppc_tb_t *tb_env;
>     booke_timer_t *booke_timer;
> +    int ret = 0;
> 
>     tb_env      = g_malloc0(sizeof(ppc_tb_t));
>     booke_timer = g_malloc0(sizeof(booke_timer_t));
> @@ -262,5 +284,17 @@ void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags)
>     booke_timer->wdt_timer =
>         qemu_new_timer_ns(vm_clock, &booke_wdt_cb, env);
> 
> +    ret = kvmppc_booke_watchdog_enable(env);
> +
> +    if (ret) {
> +        /* TODO: Start the QEMU emulated watchdog if not running on KVM.
> +         * Also start the QEMU emulated watchdog if KVM does not support
> +         * emulated watchdog or somehow it is not enabled (supported but
> +         * not enabled is though some bug and requires debugging :)).
> +         */
> +    }
> +
> +    qemu_add_vm_change_state_handler(cpu_state_change_handler, env);
> +
>     qemu_register_reset(ppc_booke_timer_reset_handle, env);
> }
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 3f5df57..6828afa 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -32,10 +32,12 @@
> #include "device_tree.h"
> #include "hw/sysbus.h"
> #include "hw/spapr.h"
> +#include "hw/watchdog.h"
> 
> #include "hw/sysbus.h"
> #include "hw/spapr.h"
> #include "hw/spapr_vio.h"
> +#include "hw/ppc.h"
> 
> //#define DEBUG_KVM
> 
> @@ -61,6 +63,7 @@ static int cap_ppc_smt;
> static int cap_ppc_rma;
> static int cap_spapr_tce;
> static int cap_hior;
> +static int cap_ppc_watchdog;
> 
> /* XXX We have a race condition where we actually have a level triggered
>  *     interrupt, but the infrastructure can't expose that yet, so the guest
> @@ -90,6 +93,7 @@ int kvm_arch_init(KVMState *s)
>     cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
>     cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
>     cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
> +    cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
> 
>     if (!cap_interrupt_level) {
>         fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
> @@ -823,6 +827,12 @@ int kvm_arch_handle_exit(CPUPPCState *env, struct kvm_run *run)
>         ret = 0;
>         break;
> #endif
> +    case KVM_EXIT_WATCHDOG:
> +        dprintf("handle watchdog expiry\n");
> +        watchdog_perform_action();
> +        ret = 0;
> +        break;
> +
>     default:
>         fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
>         ret = -1;
> @@ -1239,3 +1249,49 @@ int kvm_arch_on_sigbus(int code, void *addr)
> {
>     return 1;
> }
> +
> +int kvmppc_synch_sregs_tsr(CPUPPCState *env)
> +{
> +    struct kvm_sregs sregs;
> +    int ret;
> +
> +    if (!kvm_enabled() || !cap_booke_sregs ||  !cap_ppc_watchdog) {
> +        return -1;
> +    }
> +
> +    ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
> +
> +    env->spr[SPR_BOOKE_TSR] = sregs.u.e.tsr;
> +    ppc_booke_watchdog_clear_tsr(env);

You're getting _and_ setting it in the same function? This is nonsense. Please split it into a get and a set function if you need it.

> +    sregs.u.e.tsr = env->spr[SPR_BOOKE_TSR];
> +    sregs.u.e.update_special = KVM_SREGS_E_UPDATE_TSR;
> +
> +    ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
> +
> +    return ret;
> +}
> +
> +int kvmppc_booke_watchdog_enable(CPUPPCState *env)
> +{
> +    int ret;
> +    struct kvm_enable_cap encap = {};
> +
> +    if (!kvm_enabled()) {
> +        return -1;
> +    }
> +
> +    if (!cap_ppc_watchdog) {
> +        printf("warning: KVM does not support watchdog");
> +        return -1;
> +    }
> +
> +    encap.cap = KVM_CAP_PPC_BOOKE_WATCHDOG;
> +    ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &encap);
> +    if (ret < 0) {
> +        fprintf(stderr, "%s: couldn't enable KVM_CAP_PPC_BOOKE_WATCHDOG: %s\n",
> +                __func__, strerror(-ret));
> +        return ret;
> +    }
> +
> +    return ret;
> +}
> diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
> index baad6eb..4ccc9fa 100644
> --- a/target-ppc/kvm_ppc.h
> +++ b/target-ppc/kvm_ppc.h
> @@ -23,6 +23,8 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
> int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level);
> void kvmppc_set_papr(CPUPPCState *env);
> int kvmppc_smt_threads(void);
> +int kvmppc_synch_sregs_tsr(CPUPPCState *cenv);
> +int kvmppc_booke_watchdog_enable(CPUPPCState *env);
> #ifndef CONFIG_USER_ONLY

Missing code for !CONFIG_KVM. Please always check compile your code on x86.


Alex

> off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
> void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
> @@ -79,6 +81,15 @@ static inline int kvmppc_smt_threads(void)
>     return 1;
> }
> 
> +static inline int kvmppc_synch_sregs_tsr(CPUPPCState *env)
> +{
> +    return -1;
> +}
> +
> +static inline int kvmppc_booke_watchdog_enable(CPUPPCState *env)
> +{
> +    return -1;
> +}
> #ifndef CONFIG_USER_ONLY
> static inline off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
> {
> -- 
> 1.7.0.4
> 
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 3/3 v2] Enable kvm emulated watchdog
  2013-01-10 15:36   ` Alexander Graf
@ 2013-01-11  6:42     ` Bhushan Bharat-R65777
  2013-01-11 11:01       ` Alexander Graf
  0 siblings, 1 reply; 14+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-11  6:42 UTC (permalink / raw)
  To: Alexander Graf; +Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Thursday, January 10, 2013 9:07 PM
> To: Bhushan Bharat-R65777
> Cc: qemu-devel@nongnu.org; qemu-ppc@nongnu.org; Bhushan Bharat-R65777
> Subject: Re: [PATCH 3/3 v2] Enable kvm emulated watchdog
> 
> 
> On 28.12.2012, at 06:16, Bharat Bhushan wrote:
> 
> > Enable the KVM emulated watchdog if KVM supports (use the capability
> > enablement in watchdog handler). Also watchdog exit
> > (KVM_EXIT_WATCHDOG) handling is added.
> > Watchdog state machine is cleared whenever VM state changes to running.
> > This is to handle the cases like return from debug halt etc.
> >
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> > v2:
> >  - access cap_* from target_ppc/kvm.c only.
> >  - Added wrapper functions in target_ppc/kvm.c for
> >    enable_watchdog and tsr_sregs synchronization.
> >  - Incorporated other Review comments
> >
> > hw/ppc.h             |    1 +
> > hw/ppc_booke.c       |   36 +++++++++++++++++++++++++++++++-
> > target-ppc/kvm.c     |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > target-ppc/kvm_ppc.h |   11 +++++++++
> > 4 files changed, 103 insertions(+), 1 deletions(-)
> >
> > diff --git a/hw/ppc.h b/hw/ppc.h
> > index 2f3ea27..6ad9e1f 100644
> > --- a/hw/ppc.h
> > +++ b/hw/ppc.h
> > @@ -90,3 +90,4 @@ enum {
> >
> > /* ppc_booke.c */
> > void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t
> > flags);
> > +void ppc_booke_watchdog_clear_tsr(CPUPPCState *env);
> > diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c index 837a5b6..7273259
> > 100644
> > --- a/hw/ppc_booke.c
> > +++ b/hw/ppc_booke.c
> > @@ -28,7 +28,7 @@
> > #include "nvram.h"
> > #include "qemu-log.h"
> > #include "loader.h"
> > -
> > +#include "kvm_ppc.h"
> >
> > /* Timer Control Register */
> >
> > @@ -203,6 +203,11 @@ static void booke_wdt_cb(void *opaque)
> >                              booke_timer->wdt_timer); }
> >
> > +void ppc_booke_watchdog_clear_tsr(CPUPPCState *env) {
> > +    env->spr[SPR_BOOKE_TSR] &= ~(TSR_ENW | TSR_WIS | TSR_WRS_MASK); }
> > +
> > void store_booke_tsr(CPUPPCState *env, target_ulong val) {
> >     env->spr[SPR_BOOKE_TSR] &= ~val;
> > @@ -241,10 +246,27 @@ static void ppc_booke_timer_reset_handle(void *opaque)
> >     booke_update_irq(env);
> > }
> >
> > +static void cpu_state_change_handler(void *opaque, int running,
> > +RunState state) {
> 
> Needs a comment when this happens
> 
> > +    CPUPPCState *env = opaque;
> > +
> > +    if (!running) {
> > +        return;
> > +    }
> > +
> > +    /*
> > +     * Clear watchdog interrupt condition by clearing TSR.
> > +     */
> > +    ppc_booke_watchdog_clear_tsr(env);
> > +
> > +    kvmppc_synch_sregs_tsr(env);
> 
> kvmppc_sync_tsr. Also please add the sync to store_booke_tsr(). Then here, you
> can just do
> 
>   store_booke_tsr(TSR_ENW | TSR_WIS | TSR_WRS_MASK);
> 
> > +}
> > +
> > void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t
> > flags) {
> >     ppc_tb_t *tb_env;
> >     booke_timer_t *booke_timer;
> > +    int ret = 0;
> >
> >     tb_env      = g_malloc0(sizeof(ppc_tb_t));
> >     booke_timer = g_malloc0(sizeof(booke_timer_t)); @@ -262,5 +284,17
> > @@ void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags)
> >     booke_timer->wdt_timer =
> >         qemu_new_timer_ns(vm_clock, &booke_wdt_cb, env);
> >
> > +    ret = kvmppc_booke_watchdog_enable(env);
> > +
> > +    if (ret) {
> > +        /* TODO: Start the QEMU emulated watchdog if not running on KVM.
> > +         * Also start the QEMU emulated watchdog if KVM does not support
> > +         * emulated watchdog or somehow it is not enabled (supported but
> > +         * not enabled is though some bug and requires debugging :)).
> > +         */
> > +    }
> > +
> > +    qemu_add_vm_change_state_handler(cpu_state_change_handler, env);
> > +
> >     qemu_register_reset(ppc_booke_timer_reset_handle, env); } diff
> > --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 3f5df57..6828afa
> > 100644
> > --- a/target-ppc/kvm.c
> > +++ b/target-ppc/kvm.c
> > @@ -32,10 +32,12 @@
> > #include "device_tree.h"
> > #include "hw/sysbus.h"
> > #include "hw/spapr.h"
> > +#include "hw/watchdog.h"
> >
> > #include "hw/sysbus.h"
> > #include "hw/spapr.h"
> > #include "hw/spapr_vio.h"
> > +#include "hw/ppc.h"
> >
> > //#define DEBUG_KVM
> >
> > @@ -61,6 +63,7 @@ static int cap_ppc_smt; static int cap_ppc_rma;
> > static int cap_spapr_tce; static int cap_hior;
> > +static int cap_ppc_watchdog;
> >
> > /* XXX We have a race condition where we actually have a level triggered
> >  *     interrupt, but the infrastructure can't expose that yet, so the guest
> > @@ -90,6 +93,7 @@ int kvm_arch_init(KVMState *s)
> >     cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
> >     cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
> >     cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
> > +    cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
> >
> >     if (!cap_interrupt_level) {
> >         fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
> > @@ -823,6 +827,12 @@ int kvm_arch_handle_exit(CPUPPCState *env, struct kvm_run
> *run)
> >         ret = 0;
> >         break;
> > #endif
> > +    case KVM_EXIT_WATCHDOG:
> > +        dprintf("handle watchdog expiry\n");
> > +        watchdog_perform_action();
> > +        ret = 0;
> > +        break;
> > +
> >     default:
> >         fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
> >         ret = -1;
> > @@ -1239,3 +1249,49 @@ int kvm_arch_on_sigbus(int code, void *addr)
> > {
> >     return 1;
> > }
> > +
> > +int kvmppc_synch_sregs_tsr(CPUPPCState *env)
> > +{
> > +    struct kvm_sregs sregs;
> > +    int ret;
> > +
> > +    if (!kvm_enabled() || !cap_booke_sregs ||  !cap_ppc_watchdog) {
> > +        return -1;
> > +    }
> > +
> > +    ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
> > +
> > +    env->spr[SPR_BOOKE_TSR] = sregs.u.e.tsr;
> > +    ppc_booke_watchdog_clear_tsr(env);
> 
> You're getting _and_ setting it in the same function? This is nonsense. Please
> split it into a get and a set function if you need it.
> 
> > +    sregs.u.e.tsr = env->spr[SPR_BOOKE_TSR];
> > +    sregs.u.e.update_special = KVM_SREGS_E_UPDATE_TSR;
> > +
> > +    ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
> > +
> > +    return ret;
> > +}
> > +
> > +int kvmppc_booke_watchdog_enable(CPUPPCState *env)
> > +{
> > +    int ret;
> > +    struct kvm_enable_cap encap = {};
> > +
> > +    if (!kvm_enabled()) {
> > +        return -1;
> > +    }
> > +
> > +    if (!cap_ppc_watchdog) {
> > +        printf("warning: KVM does not support watchdog");
> > +        return -1;
> > +    }
> > +
> > +    encap.cap = KVM_CAP_PPC_BOOKE_WATCHDOG;
> > +    ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &encap);
> > +    if (ret < 0) {
> > +        fprintf(stderr, "%s: couldn't enable KVM_CAP_PPC_BOOKE_WATCHDOG:
> %s\n",
> > +                __func__, strerror(-ret));
> > +        return ret;
> > +    }
> > +
> > +    return ret;
> > +}
> > diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
> > index baad6eb..4ccc9fa 100644
> > --- a/target-ppc/kvm_ppc.h
> > +++ b/target-ppc/kvm_ppc.h
> > @@ -23,6 +23,8 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int
> buf_len);
> > int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level);
> > void kvmppc_set_papr(CPUPPCState *env);
> > int kvmppc_smt_threads(void);
> > +int kvmppc_synch_sregs_tsr(CPUPPCState *cenv);
> > +int kvmppc_booke_watchdog_enable(CPUPPCState *env);
> > #ifndef CONFIG_USER_ONLY
> 
> Missing code for !CONFIG_KVM. Please always check compile your code on x86.

Alex is not the below code covers !CONFIG_KVM  ...

> 
> 
> Alex
> 
> > off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
> > void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
> > @@ -79,6 +81,15 @@ static inline int kvmppc_smt_threads(void)
> >     return 1;
> > }
> >
> > +static inline int kvmppc_synch_sregs_tsr(CPUPPCState *env)
> > +{
> > +    return -1;
> > +}
> > +
> > +static inline int kvmppc_booke_watchdog_enable(CPUPPCState *env)
> > +{
> > +    return -1;
> > +}

I mean this one

Thanks
-Bharat

> > #ifndef CONFIG_USER_ONLY
> > static inline off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
> > {
> > --
> > 1.7.0.4
> >
> >
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 3/3 v2] Enable kvm emulated watchdog
  2013-01-11  6:42     ` Bhushan Bharat-R65777
@ 2013-01-11 11:01       ` Alexander Graf
  0 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2013-01-11 11:01 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org



Am 11.01.2013 um 07:42 schrieb Bhushan Bharat-R65777 <R65777@freescale.com>:

> 
> 
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Thursday, January 10, 2013 9:07 PM
>> To: Bhushan Bharat-R65777
>> Cc: qemu-devel@nongnu.org; qemu-ppc@nongnu.org; Bhushan Bharat-R65777
>> Subject: Re: [PATCH 3/3 v2] Enable kvm emulated watchdog
>> 
>> 
>> On 28.12.2012, at 06:16, Bharat Bhushan wrote:
>> 
>>> Enable the KVM emulated watchdog if KVM supports (use the capability
>>> enablement in watchdog handler). Also watchdog exit
>>> (KVM_EXIT_WATCHDOG) handling is added.
>>> Watchdog state machine is cleared whenever VM state changes to running.
>>> This is to handle the cases like return from debug halt etc.
>>> 
>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>> ---
>>> v2:
>>> - access cap_* from target_ppc/kvm.c only.
>>> - Added wrapper functions in target_ppc/kvm.c for
>>>   enable_watchdog and tsr_sregs synchronization.
>>> - Incorporated other Review comments
>>> 
>>> hw/ppc.h             |    1 +
>>> hw/ppc_booke.c       |   36 +++++++++++++++++++++++++++++++-
>>> target-ppc/kvm.c     |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>> target-ppc/kvm_ppc.h |   11 +++++++++
>>> 4 files changed, 103 insertions(+), 1 deletions(-)
>>> 
>>> diff --git a/hw/ppc.h b/hw/ppc.h
>>> index 2f3ea27..6ad9e1f 100644
>>> --- a/hw/ppc.h
>>> +++ b/hw/ppc.h
>>> @@ -90,3 +90,4 @@ enum {
>>> 
>>> /* ppc_booke.c */
>>> void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t
>>> flags);
>>> +void ppc_booke_watchdog_clear_tsr(CPUPPCState *env);
>>> diff --git a/hw/ppc_booke.c b/hw/ppc_booke.c index 837a5b6..7273259
>>> 100644
>>> --- a/hw/ppc_booke.c
>>> +++ b/hw/ppc_booke.c
>>> @@ -28,7 +28,7 @@
>>> #include "nvram.h"
>>> #include "qemu-log.h"
>>> #include "loader.h"
>>> -
>>> +#include "kvm_ppc.h"
>>> 
>>> /* Timer Control Register */
>>> 
>>> @@ -203,6 +203,11 @@ static void booke_wdt_cb(void *opaque)
>>>                             booke_timer->wdt_timer); }
>>> 
>>> +void ppc_booke_watchdog_clear_tsr(CPUPPCState *env) {
>>> +    env->spr[SPR_BOOKE_TSR] &= ~(TSR_ENW | TSR_WIS | TSR_WRS_MASK); }
>>> +
>>> void store_booke_tsr(CPUPPCState *env, target_ulong val) {
>>>    env->spr[SPR_BOOKE_TSR] &= ~val;
>>> @@ -241,10 +246,27 @@ static void ppc_booke_timer_reset_handle(void *opaque)
>>>    booke_update_irq(env);
>>> }
>>> 
>>> +static void cpu_state_change_handler(void *opaque, int running,
>>> +RunState state) {
>> 
>> Needs a comment when this happens
>> 
>>> +    CPUPPCState *env = opaque;
>>> +
>>> +    if (!running) {
>>> +        return;
>>> +    }
>>> +
>>> +    /*
>>> +     * Clear watchdog interrupt condition by clearing TSR.
>>> +     */
>>> +    ppc_booke_watchdog_clear_tsr(env);
>>> +
>>> +    kvmppc_synch_sregs_tsr(env);
>> 
>> kvmppc_sync_tsr. Also please add the sync to store_booke_tsr(). Then here, you
>> can just do
>> 
>>  store_booke_tsr(TSR_ENW | TSR_WIS | TSR_WRS_MASK);
>> 
>>> +}
>>> +
>>> void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t
>>> flags) {
>>>    ppc_tb_t *tb_env;
>>>    booke_timer_t *booke_timer;
>>> +    int ret = 0;
>>> 
>>>    tb_env      = g_malloc0(sizeof(ppc_tb_t));
>>>    booke_timer = g_malloc0(sizeof(booke_timer_t)); @@ -262,5 +284,17
>>> @@ void ppc_booke_timers_init(CPUPPCState *env, uint32_t freq, uint32_t flags)
>>>    booke_timer->wdt_timer =
>>>        qemu_new_timer_ns(vm_clock, &booke_wdt_cb, env);
>>> 
>>> +    ret = kvmppc_booke_watchdog_enable(env);
>>> +
>>> +    if (ret) {
>>> +        /* TODO: Start the QEMU emulated watchdog if not running on KVM.
>>> +         * Also start the QEMU emulated watchdog if KVM does not support
>>> +         * emulated watchdog or somehow it is not enabled (supported but
>>> +         * not enabled is though some bug and requires debugging :)).
>>> +         */
>>> +    }
>>> +
>>> +    qemu_add_vm_change_state_handler(cpu_state_change_handler, env);
>>> +
>>>    qemu_register_reset(ppc_booke_timer_reset_handle, env); } diff
>>> --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 3f5df57..6828afa
>>> 100644
>>> --- a/target-ppc/kvm.c
>>> +++ b/target-ppc/kvm.c
>>> @@ -32,10 +32,12 @@
>>> #include "device_tree.h"
>>> #include "hw/sysbus.h"
>>> #include "hw/spapr.h"
>>> +#include "hw/watchdog.h"
>>> 
>>> #include "hw/sysbus.h"
>>> #include "hw/spapr.h"
>>> #include "hw/spapr_vio.h"
>>> +#include "hw/ppc.h"
>>> 
>>> //#define DEBUG_KVM
>>> 
>>> @@ -61,6 +63,7 @@ static int cap_ppc_smt; static int cap_ppc_rma;
>>> static int cap_spapr_tce; static int cap_hior;
>>> +static int cap_ppc_watchdog;
>>> 
>>> /* XXX We have a race condition where we actually have a level triggered
>>> *     interrupt, but the infrastructure can't expose that yet, so the guest
>>> @@ -90,6 +93,7 @@ int kvm_arch_init(KVMState *s)
>>>    cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
>>>    cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
>>>    cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
>>> +    cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
>>> 
>>>    if (!cap_interrupt_level) {
>>>        fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
>>> @@ -823,6 +827,12 @@ int kvm_arch_handle_exit(CPUPPCState *env, struct kvm_run
>> *run)
>>>        ret = 0;
>>>        break;
>>> #endif
>>> +    case KVM_EXIT_WATCHDOG:
>>> +        dprintf("handle watchdog expiry\n");
>>> +        watchdog_perform_action();
>>> +        ret = 0;
>>> +        break;
>>> +
>>>    default:
>>>        fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
>>>        ret = -1;
>>> @@ -1239,3 +1249,49 @@ int kvm_arch_on_sigbus(int code, void *addr)
>>> {
>>>    return 1;
>>> }
>>> +
>>> +int kvmppc_synch_sregs_tsr(CPUPPCState *env)
>>> +{
>>> +    struct kvm_sregs sregs;
>>> +    int ret;
>>> +
>>> +    if (!kvm_enabled() || !cap_booke_sregs ||  !cap_ppc_watchdog) {
>>> +        return -1;
>>> +    }
>>> +
>>> +    ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
>>> +
>>> +    env->spr[SPR_BOOKE_TSR] = sregs.u.e.tsr;
>>> +    ppc_booke_watchdog_clear_tsr(env);
>> 
>> You're getting _and_ setting it in the same function? This is nonsense. Please
>> split it into a get and a set function if you need it.
>> 
>>> +    sregs.u.e.tsr = env->spr[SPR_BOOKE_TSR];
>>> +    sregs.u.e.update_special = KVM_SREGS_E_UPDATE_TSR;
>>> +
>>> +    ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +int kvmppc_booke_watchdog_enable(CPUPPCState *env)
>>> +{
>>> +    int ret;
>>> +    struct kvm_enable_cap encap = {};
>>> +
>>> +    if (!kvm_enabled()) {
>>> +        return -1;
>>> +    }
>>> +
>>> +    if (!cap_ppc_watchdog) {
>>> +        printf("warning: KVM does not support watchdog");
>>> +        return -1;
>>> +    }
>>> +
>>> +    encap.cap = KVM_CAP_PPC_BOOKE_WATCHDOG;
>>> +    ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &encap);
>>> +    if (ret < 0) {
>>> +        fprintf(stderr, "%s: couldn't enable KVM_CAP_PPC_BOOKE_WATCHDOG:
>> %s\n",
>>> +                __func__, strerror(-ret));
>>> +        return ret;
>>> +    }
>>> +
>>> +    return ret;
>>> +}
>>> diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
>>> index baad6eb..4ccc9fa 100644
>>> --- a/target-ppc/kvm_ppc.h
>>> +++ b/target-ppc/kvm_ppc.h
>>> @@ -23,6 +23,8 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int
>> buf_len);
>>> int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level);
>>> void kvmppc_set_papr(CPUPPCState *env);
>>> int kvmppc_smt_threads(void);
>>> +int kvmppc_synch_sregs_tsr(CPUPPCState *cenv);
>>> +int kvmppc_booke_watchdog_enable(CPUPPCState *env);
>>> #ifndef CONFIG_USER_ONLY
>> 
>> Missing code for !CONFIG_KVM. Please always check compile your code on x86.
> 
> Alex is not the below code covers !CONFIG_KVM  ...
> 
>> 
>> 
>> Alex
>> 
>>> off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
>>> void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
>>> @@ -79,6 +81,15 @@ static inline int kvmppc_smt_threads(void)
>>>    return 1;
>>> }
>>> 
>>> +static inline int kvmppc_synch_sregs_tsr(CPUPPCState *env)
>>> +{
>>> +    return -1;
>>> +}
>>> +
>>> +static inline int kvmppc_booke_watchdog_enable(CPUPPCState *env)
>>> +{
>>> +    return -1;
>>> +}
> 
> I mean this one

Hrm. Somehow I didn't see those lines during review :). Yes, it's fine - sorry.

Alex

> 
> Thanks
> -Bharat
> 
>>> #ifndef CONFIG_USER_ONLY
>>> static inline off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
>>> {
>>> --
>>> 1.7.0.4
>>> 
>>> 
>> 
> 
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-01-11 11:00 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-28  5:16 [Qemu-devel] [PATCH 0/3 v2] Enable and Handle in-kernel watchdog emulation Bharat Bhushan
2012-12-28  5:16 ` [Qemu-devel] [PATCH 1/3 v2] Synchronized the linux headers Bharat Bhushan
2012-12-28  5:16 ` [Qemu-devel] [PATCH 2/3 v2] Reset qemu timers when guest reset Bharat Bhushan
2013-01-03 14:10   ` Alexander Graf
2013-01-03 20:20   ` [Qemu-devel] [Qemu-ppc] " Scott Wood
2013-01-03 20:33     ` Alexander Graf
2013-01-03 20:37       ` Scott Wood
2013-01-03 20:48         ` Alexander Graf
2013-01-04  1:28     ` Bhushan Bharat-R65777
2013-01-04 15:58       ` Scott Wood
2012-12-28  5:16 ` [Qemu-devel] [PATCH 3/3 v2] Enable kvm emulated watchdog Bharat Bhushan
2013-01-10 15:36   ` Alexander Graf
2013-01-11  6:42     ` Bhushan Bharat-R65777
2013-01-11 11:01       ` Alexander Graf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).