Skip to contentSkip to conversation

make KVM conform to sucky rdmsr interface

PATCH In review Rusty Russell 4 participants 7 messages Mar 22, 2007 – Mar 23, 2007 KVM

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 make KVM conform to sucky rdmsr interface

Grrr.... Andi refused to take my "rdmsr64" patch which moved to a function-like interface for MSRs, dismissing it as pointless churn.

paravirt_ops cleanups changed a macro to an inline and spotted this kvm bug.

drivers/kvm/vmx.c +1 -1
diff -r 47c6ee74a5c5 drivers/kvm/vmx.c
@@ -1127,7 +1127,7 @@ static int vmx_vcpu_setup(struct kvm_vcp
 		u64 data;
 		int j = vcpu->nmsrs;
 
-		if (rdmsr_safe(index, &data_low, &data_high) < 0)
+		if (rdmsr_safe(index, data_low, data_high) < 0)
 			continue;
 		if (wrmsr_safe(index, data_low, data_high) < 0)
 			continue;

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

#1 lore raw
Quoted 15 lines · Rusty Russell

Grrr.... Andi refused to take my "rdmsr64" patch which moved to a function-like interface for MSRs, dismissing it as pointless churn.

paravirt_ops cleanups changed a macro to an inline and spotted this kvm bug.

diff -r 47c6ee74a5c5 drivers/kvm/vmx.c

drivers/kvm/vmx.c static int vmx_vcpu_setup(struct kvm_vcp · line 1133

Quoted 8 lines
drivers/kvm/vmx.c +1 -1
@@ -1127,7 +1127,7 @@ static int vmx_vcpu_setup(struct kvm_vcp
 		u64 data;
 		int j = vcpu->nmsrs;
 
-		if (rdmsr_safe(index, &data_low, &data_high) < 0)
+		if (rdmsr_safe(index, data_low, data_high) < 0)
 			continue;
 		if (wrmsr_safe(index, data_low, data_high) < 0)
 			continue;

My rdmsr_safe (x86_64, i386 is similar/same) is

#define rdmsr_safe(msr,a,b) \
        ({ int ret__;                                           \
          asm volatile ("1:       rdmsr\n"                      \
                      "2:\n"                                    \
                      ".section .fixup,\"ax\"\n"                \
                      "3:       movl %4,%0\n"                   \
                      " jmp 2b\n"                               \
                      ".previous\n"                             \
                      ".section __ex_table,\"a\"\n"             \
                      " .align 8\n"                             \
                      " .quad 1b,3b\n"                          \
                      ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b))\
                      :"c"(msr), "i"(-EIO), "0"(0));            \
          ret__; })

Which seems quite happy to accept pointers to the values. The one in asm/i386/paravirt.h has a similar calling convention.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
#2 lore raw
Quoted 1 line · Avi Kivity

My rdmsr_safe (x86_64, i386 is similar/same) is

Erk. Andrew, please drop that patch, and take this one.

It was actually Jeremy's paravirt cleanup patch which changed the calling convention of rdmsr_safe() to match rdmsr().

I went "oh it's that fucking rdmsr interface" and "fixed" kvm.

Sorry for the bad patch,
Rusty.
==
rdmsr_safe() takes pointers. rdmsr() modifies its arguments. What a mess.

Fix rdmsr_safe() with !CONFIG_PARAVIRT.

include/asm-i386/msr.h +4 -4
diff -r a7f78e8eacc8 include/asm-i386/msr.h
@@ -96,12 +96,12 @@ static inline void wrmsrl (unsigned long
 	(native_write_msr(msr, ((unsigned long long)val2 << 32) | val1))
 
 /* rdmsr with exception handling */
-#define rdmsr_safe(msr,val1,val2)						\
+#define rdmsr_safe(msr,p1,p2)						\
 	({								\
 		int __err;						\
-		unsigned long long __val = native_read_msr(msr, &__err);	\
-		val1 = __val;						\
-		val2 = __val >> 32;					\
+		unsigned long long __val = native_read_msr(msr, &__err);\
+		(*p1) = __val;						\
+		(*p2) = __val >> 32;					\
 		__err;							\
 	})
 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

#3 lore raw
Quoted 3 lines · Rusty Russell

It was actually Jeremy's paravirt cleanup patch which changed the calling convention of rdmsr_safe() to match rdmsr().

Oops, my little mind hobgoblin is getting out of control...

J

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

#4 lore raw
In reply to Rusty Russell
Quoted 16 lines · On Thu, 22 Mar 2007 18:49:30 +1100 Rusty Russell…

rdmsr_safe() takes pointers. rdmsr() modifies its arguments. What a mess.

Fix rdmsr_safe() with !CONFIG_PARAVIRT.

diff -r a7f78e8eacc8 include/asm-i386/msr.h

include/asm-i386/msr.h +1 -1
@@ -96,12 +96,12 @@ static inline void wrmsrl (unsigned long
 	(native_write_msr(msr, ((unsigned long long)val2 << 32) | val1))
 
 /* rdmsr with exception handling */
-#define rdmsr_safe(msr,val1,val2)						\
+#define rdmsr_safe(msr,p1,p2)						\

include/asm-i386/msr.h static inline void wrmsrl (unsigned long · line 106

Quoted 10 lines
include/asm-i386/msr.h +3 -3
 	({								\
 		int __err;						\
-		unsigned long long __val = native_read_msr(msr, &__err);	\
-		val1 = __val;						\
-		val2 = __val >> 32;					\
+		unsigned long long __val = native_read_msr(msr, &__err);\
+		(*p1) = __val;						\
+		(*p2) = __val >> 32;					\
 		__err;							\
 	})

Linus's tree has

/* rdmsr with exception handling */

#define rdmsr_safe(msr,a,b) ({ int ret__;						\
	asm volatile("2: rdmsr ; xorl %0,%0\n"						\
		     "1:\n\t"								\
		     ".section .fixup,\"ax\"\n\t"					\
		     "3:  movl %4,%0 ; jmp 1b\n\t"					\
		     ".previous\n\t"							\
 		     ".section __ex_table,\"a\"\n"					\
		     "   .align 4\n\t"							\
		     "   .long 	2b,3b\n\t"						\
		     ".previous"							\
		     : "=r" (ret__), "=a" (*(a)), "=d" (*(b))				\
		     : "c" (msr), "i" (-EFAULT));\
	ret__; })

(secret decoder ring: resize your xterm to 100 cols to read the above. Sigh).

Which tree are you patching??

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

#5 lore raw
Quoted 2 lines · Andrew Morton

Which tree are you patching??
-

It looks like its against the previously posted "Cleanup: rationalize paravirt wrappers" patch.

J

#6 lore raw
In reply to Andrew Morton
Quoted 1 line · Andrew Morton

Which tree are you patching??

We crossed in the mail: you turfed out the paravirt.h cleanup patch it applied to.

We have rolled the fixes one patch, and am testing...

Rusty.

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV