RE: [PATCH] kvm/ia64: Add printk support for kvm-intel modules.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi, Avi 
Based on your comments. I worked out the new patch. Now I use the
vmm_has_log field of vcpu to indicate whether vmm has log to print. If
this flag is not set, it doesn't need to acquire the spin_lock to avoid
possible scalability issue. 
Xiantao

>From 688296c4a4784704e48b16dea9580abc271fa497 Mon Sep 17 00:00:00 2001
From: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
Date: Thu, 11 Sep 2008 17:04:22 +0800
Subject: [PATCH] kvm/ia64: Add printk support for kvm-intel modules.

Since this module will be reloated to an isolated address
space from host side, so kvm-intel can't call printk of host
kernel. This patch implements the printk function for kvm-intel
module, so it doesn't need to suffer no-printk pains.

Signed-off-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
---
 arch/ia64/include/asm/kvm_host.h |   19 +++++++++++++++++--
 arch/ia64/kvm/Makefile           |    2 +-
 arch/ia64/kvm/kvm-ia64.c         |   25 ++++++++++++++++++++++++-
 arch/ia64/kvm/kvm_lib.c          |   13 +++++++++++++
 arch/ia64/kvm/vmm.c              |   23 +++++++++++++++++++++++
 5 files changed, 78 insertions(+), 4 deletions(-)
 create mode 100644 arch/ia64/kvm/kvm_lib.c

diff --git a/arch/ia64/include/asm/kvm_host.h
b/arch/ia64/include/asm/kvm_host.h
index 1efe513..b71aba0 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -55,13 +55,17 @@
 #define KVM_VMM_SIZE (16UL<<20)
 #define KVM_VMM_SHIFT 24
 #define KVM_VMM_BASE 0xD000000000000000UL
-#define VMM_SIZE (8UL<<20)
+#define VMM_SIZE (4UL<<20)
+
+/*Define vmm log buffer*/
+#define KVM_VMM_LOG_BASE (KVM_VMM_BASE + VMM_SIZE)
+#define VMM_LOG_SIZE  (4UL<<20)
 
 /*
  * Define vm_buffer, used by PAL Services, base address.
  * Note: vmbuffer is in the VMM-BLOCK, the size must be < 8M
  */
-#define KVM_VM_BUFFER_BASE (KVM_VMM_BASE + VMM_SIZE)
+#define KVM_VM_BUFFER_BASE (KVM_VMM_LOG_BASE + VMM_LOG_SIZE)
 #define KVM_VM_BUFFER_SIZE (8UL<<20)
 
 /*Define Virtual machine data layout.*/
@@ -324,6 +328,8 @@ struct kvm_vcpu_arch {
 #define KVM_MP_STATE_INIT_RECEIVED     2
 #define KVM_MP_STATE_HALTED            3
 	int mp_state;
+	/*Flag to indicate vmm log.*/
+	int vmm_has_log;
 
 #define MAX_PTC_G_NUM			3
 	int ptc_g_count;
@@ -524,4 +530,13 @@ void kvm_sal_emul(struct kvm_vcpu *vcpu);
 
 static inline void kvm_inject_nmi(struct kvm_vcpu *vcpu) {}
 
+#define BYTES_PER_LOG 256
+
+struct kvm_vmm_log {
+	spinlock_t log_lock;
+	unsigned long w_pointer;
+	unsigned long r_pointer;
+	char log_slot[VMM_LOG_SIZE/BYTES_PER_LOG][BYTES_PER_LOG - 1];
+};
+
 #endif
diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile
index bf22fb9..0d17d84 100644
--- a/arch/ia64/kvm/Makefile
+++ b/arch/ia64/kvm/Makefile
@@ -52,7 +52,7 @@ obj-$(CONFIG_KVM) += kvm.o
 FORCE : $(obj)/$(offsets-file)
 EXTRA_CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127
 kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o
\
-	vtlb.o process.o
+	vtlb.o process.o kvm_lib.o
 #Add link memcpy and memset to avoid possible structure assignment
error
 kvm-intel-objs += memcpy.o memset.o
 obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 8a3b5fc..b92f6d1 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -50,6 +50,7 @@ static unsigned long kvm_vsa_base;
 static unsigned long kvm_vm_buffer;
 static unsigned long kvm_vm_buffer_size;
 unsigned long kvm_vmm_gp;
+struct kvm_vmm_log *vmm_log;
 
 static long vp_env_info;
 
@@ -496,6 +497,21 @@ static uint32_t kvm_get_exit_reason(struct kvm_vcpu
*vcpu)
 	return p_exit_data->exit_reason;
 }
 
+static void vcpu_print_vmm_log(struct kvm_vcpu *vcpu)
+{
+	unsigned int slot;
+
+	if (vcpu->arch.vmm_has_log) {
+		spin_lock(&vmm_log->log_lock);
+		while (vmm_log->r_pointer < vmm_log->w_pointer) {
+			slot = vmm_log->r_pointer %
(VMM_LOG_SIZE/BYTES_PER_LOG);
+			printk("%s", vmm_log->log_slot[slot]);
+			vmm_log->r_pointer++;
+		}
+		vcpu->arch.vmm_has_log = 0;
+		spin_unlock(&vmm_log->log_lock);
+	}
+}
 /*
  * The guest has exited.  See if we can fix it or if we need userspace
  * assistance.
@@ -505,6 +521,9 @@ static int kvm_handle_exit(struct kvm_run *kvm_run,
struct kvm_vcpu *vcpu)
 	u32 exit_reason = kvm_get_exit_reason(vcpu);
 	vcpu->arch.last_exit = exit_reason;
 
+	/*vcpu on behalf of VMM to print vmm's kernel log */
+	vcpu_print_vmm_log(vcpu);
+
 	if (exit_reason < kvm_vti_max_exit_handlers
 			&& kvm_vti_exit_handlers[exit_reason])
 		return kvm_vti_exit_handlers[exit_reason](vcpu,
kvm_run);
@@ -1011,6 +1030,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu
*vcpu,
 
 static int kvm_alloc_vmm_area(void)
 {
+
 	if (!kvm_vmm_base && (kvm_vm_buffer_size < KVM_VM_BUFFER_SIZE))
{
 		kvm_vmm_base = __get_free_pages(GFP_KERNEL,
 				get_order(KVM_VMM_SIZE));
@@ -1018,7 +1038,10 @@ static int kvm_alloc_vmm_area(void)
 			return -ENOMEM;
 
 		memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE);
-		kvm_vm_buffer = kvm_vmm_base + VMM_SIZE;
+		kvm_vm_buffer = kvm_vmm_base + VMM_SIZE + VMM_LOG_SIZE;
+		vmm_log = (struct kvm_vmm_log *)(kvm_vmm_base +
+					(KVM_VMM_LOG_BASE -
KVM_VMM_BASE));
+		spin_lock_init(&vmm_log->log_lock);
 
 		printk(KERN_DEBUG"kvm:VMM's Base Addr:0x%lx,
vm_buffer:0x%lx\n",
 				kvm_vmm_base, kvm_vm_buffer);
diff --git a/arch/ia64/kvm/kvm_lib.c b/arch/ia64/kvm/kvm_lib.c
new file mode 100644
index 0000000..4c43efe
--- /dev/null
+++ b/arch/ia64/kvm/kvm_lib.c
@@ -0,0 +1,13 @@
+
+/*
+ * vsprintf.c: Let kvm-intel module has the ability to use print
functions.
+ *	Just include kernel's library, and disable symbols export.
+ * 	Copyright (C) 2008, Intel Corporation.
+ *  	Xiantao Zhang  (xiantao.zhang@xxxxxxxxx)
+ *
+ */
+
+#undef CONFIG_MODULES
+
+#include "../../../lib/vsprintf.c"
+#include "../../../lib/ctype.c"
diff --git a/arch/ia64/kvm/vmm.c b/arch/ia64/kvm/vmm.c
index 2275bf4..c8b3c90 100644
--- a/arch/ia64/kvm/vmm.c
+++ b/arch/ia64/kvm/vmm.c
@@ -62,5 +62,28 @@ void vmm_spin_unlock(spinlock_t *lock)
 {
 	_vmm_raw_spin_unlock(lock);
 }
+
+asmlinkage int printk(const char *fmt, ...)
+{
+	struct kvm_vmm_log *vmm_log = (struct kvm_vmm_log
*)KVM_VMM_LOG_BASE;
+	struct kvm_vcpu *vcpu = current_vcpu;
+	unsigned int slot;
+	va_list args;
+	int r;
+
+	vmm_spin_lock(&vmm_log->log_lock);
+	slot = vmm_log->w_pointer % (VMM_LOG_SIZE/BYTES_PER_LOG);
+	memset(vmm_log->log_slot[slot], 0, BYTES_PER_LOG - 1);
+	va_start(args, fmt);
+	r = vsnprintf(vmm_log->log_slot[slot], BYTES_PER_LOG - 1, fmt,
args);
+	va_end(args);
+	vcpu->arch.vmm_has_log = 1;
+	vmm_log->w_pointer++;
+	wmb();
+	vmm_spin_unlock(&vmm_log->log_lock);
+
+	return r;
+}
+
 module_init(kvm_vmm_init)
 module_exit(kvm_vmm_exit)
-- 
1.5.1

Avi Kivity wrote:
> Zhang, Xiantao wrote:
>> 
>>>> +static void vcpu_print_vmm_log(void)
>>>> +{
>>>> +	unsigned int slot;
>>>> +
>>>> +	spin_lock(&vmm_log->log_lock);
>>>> 
>>>> 
>>> You're going to impact scalability with this.  Are per-vcpu logs
>>> workable? 
>>> 
>> 
>> OK, I will change it to per-vcpu style to avoid this possible
>> scalability issue. 
>> 
>> 
> 
> Actually, per-vcpu logs have a deficiency where log lines become
> unordered. 
> 
> So I suggest a per-vcpu flag that says "there may be something in the
> log", but keep a single log buffer.  Since printk()s are rare (and
> slow), it's enough that we make the case where the log is empty fast.
> 
> 
>>> I suspect this will start breaking when people start using the new
>>> printk("%pBLAH") functionality, which will require linking
>>> additional files. 
>>> 
>> 
>>  If the format string works with vsnprintf, it should be covered.
>> 
>> 
> 
> vsnprintf() may start to be linked with other stuff.  Well, we'll deal
> with that when it happens.
> 
>>> I can't think of a way on x86, but maybe ia64 varargs are different.
>>> 
>>> (worst case you can limit the number of arguments and just copy a
>>> bunch  of stack). 
>>> 
>> 
>> That maybe infeasible, since some args may be transferred by pointer,
>> and this pointer can't be reached in host side.
>> 
> 
> Okay.

Attachment: 0001-kvm-ia64-Add-printk-support-for-kvm-intel-modules.patch
Description: 0001-kvm-ia64-Add-printk-support-for-kvm-intel-modules.patch


[Index of Archives]     [Linux KVM Devel]     [Linux Virtualization]     [Big List of Linux Books]     [Linux SCSI]     [Yosemite Forum]

  Powered by Linux