* [LTP] [PATCH 1/2] lib: provide a way to detect if we are running on KVM or Xen
@ 2015-02-24 8:27 Wei,Jiangang
2015-02-24 8:27 ` [LTP] [PATCH 2/2] lib/tst_virt.c: distinguish between KVM and QEMU Wei,Jiangang
0 siblings, 1 reply; 4+ messages in thread
From: Wei,Jiangang @ 2015-02-24 8:27 UTC (permalink / raw)
To: ltp-list; +Cc: jjaburek
The command virt-what can be used to detect if the program is
running in a virtual machine, and prints out a list of "facts"
about the virtual machine. such as hyperv, lxc, qemu, kvm, xen
and so on.
Refer to the following for more details,
<http://people.redhat.com/~rjones/virt-what/>
This patch references the method that has already proposed
and implemented in the code of virt-what.
Signed-off-by: Wei,Jiangang <weijg.fnst@cn.fujitsu.com>
---
lib/tst_virt.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/lib/tst_virt.c b/lib/tst_virt.c
index 87f73dc..eb3b487 100644
--- a/lib/tst_virt.c
+++ b/lib/tst_virt.c
@@ -23,9 +23,78 @@
*/
#include <unistd.h>
+#include <string.h>
#include "test.h"
#include "safe_macros.h"
+#define SIG_MAX_LEN 13 // Limit the length of the CPU sign array
+
+#if defined(__i386__) || defined(__x86_64__)
+
+static unsigned int
+cpuid (unsigned int eax, char *sigp)
+{
+ unsigned int *sig32 = (unsigned int *) sigp;
+
+ asm volatile (
+ "xor %%ebx, %%ebx; cpuid"
+ : "=a" (eax), "=b" (sig32[0]), "=c" (sig32[1]), "=d" (sig32[2])
+ : "0" (eax));
+ sigp[SIG_MAX_LEN - 1] = 0;
+
+ return eax;
+}
+
+/*
+ * confirm that we are running inside KVM or Xen HVM by CPU sign
+ *
+ * Inputs:
+ * char* sigp - the pointer of CPU sign array, sig[].
+ * Possible Values of sig[]:
+ * String - Virtual Type
+ * KVMKVMKVM - KVM guest
+ * XenVMMXenVMM - Xen HVM guest
+ *
+ * Returns:
+ * 0 - success
+ * -1 - an error has occurred (unsupported architecture)
+ */
+static int
+cpu_sign (char* sigp)
+{
+ unsigned int base = 0x40000000, leaf = base;
+ unsigned int max_entries;
+
+ memset (sigp, 0, SIG_MAX_LEN);
+ max_entries = cpuid (leaf, sigp);
+
+ /* Most hypervisors only have information in leaf 0x40000000, but
+ * upstream Xen contains further leaf entries (in particular when
+ * used with Viridian [HyperV] extensions). CPUID is supposed to
+ * return the maximum leaf offset in %eax, so that's what we use,
+ * but only if it looks sensible.
+ */
+ if (max_entries > 3 && max_entries < 0x10000) {
+ for (leaf = base + 0x100; leaf <= base + max_entries; leaf += 0x100) {
+ memset (sigp, 0, SIG_MAX_LEN);
+ cpuid (leaf, sigp);
+ }
+ }
+
+ return 0;
+}
+
+#else /* !i386, !x86_64 */
+
+static int
+cpu_sign (char* sigp)
+{
+ /* nothing for other architectures */
+ return -1;
+}
+
+#endif
+
static int is_kvm(void)
{
FILE *cpuinfo;
--
1.9.3
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [LTP] [PATCH 2/2] lib/tst_virt.c: distinguish between KVM and QEMU
2015-02-24 8:27 [LTP] [PATCH 1/2] lib: provide a way to detect if we are running on KVM or Xen Wei,Jiangang
@ 2015-02-24 8:27 ` Wei,Jiangang
2015-02-24 11:36 ` Jiri Jaburek
0 siblings, 1 reply; 4+ messages in thread
From: Wei,Jiangang @ 2015-02-24 8:27 UTC (permalink / raw)
To: ltp-list; +Cc: jjaburek
KVM guest is on top of QEMU, It's necessary that figure out
the difference between the two.
Signed-off-by: Wei,Jiangang <weijg.fnst@cn.fujitsu.com>
---
lib/tst_virt.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/lib/tst_virt.c b/lib/tst_virt.c
index eb3b487..1d9960e 100644
--- a/lib/tst_virt.c
+++ b/lib/tst_virt.c
@@ -100,14 +100,24 @@ static int is_kvm(void)
FILE *cpuinfo;
char line[64];
int found;
+ char sig[SIG_MAX_LEN];
- /* this doesn't work with custom -cpu values, since there's
- * no easy, reasonable or reliable way to work around those */
cpuinfo = SAFE_FOPEN(NULL, "/proc/cpuinfo", "r");
found = 0;
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
if (strstr(line, "QEMU Virtual CPU")) {
- found = 1;
+ /*
+ * Is it an KVM(on top of QEMU) or Only a QEMU?
+ */
+ if (cpu_sign(&sig[0]) == 0) {
+ if (strcmp(sig, "KVMKVMKVM") == 0) {
+ found = 1;
+ } else {
+ // QEMU Guest
+ }
+ } else {
+ found = 1;
+ }
break;
}
}
--
1.9.3
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [LTP] [PATCH 2/2] lib/tst_virt.c: distinguish between KVM and QEMU
2015-02-24 8:27 ` [LTP] [PATCH 2/2] lib/tst_virt.c: distinguish between KVM and QEMU Wei,Jiangang
@ 2015-02-24 11:36 ` Jiri Jaburek
2015-02-25 3:31 ` [LTP] 答复: " Wei, Jiangang
0 siblings, 1 reply; 4+ messages in thread
From: Jiri Jaburek @ 2015-02-24 11:36 UTC (permalink / raw)
To: Wei,Jiangang; +Cc: ltp-list
Hello and thanks for the patch. Aside from indent issues (please use
tabs, Linux kernel style), I have some comments/questions:
On 02/24/2015 09:27 AM, Wei,Jiangang wrote:
> KVM guest is on top of QEMU, It's necessary that figure out
> the difference between the two.
>
> Signed-off-by: Wei,Jiangang <weijg.fnst@cn.fujitsu.com>
> ---
> lib/tst_virt.c | 16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/lib/tst_virt.c b/lib/tst_virt.c
> index eb3b487..1d9960e 100644
> --- a/lib/tst_virt.c
> +++ b/lib/tst_virt.c
> @@ -100,14 +100,24 @@ static int is_kvm(void)
> FILE *cpuinfo;
> char line[64];
> int found;
> + char sig[SIG_MAX_LEN];
>
> - /* this doesn't work with custom -cpu values, since there's
> - * no easy, reasonable or reliable way to work around those */
When writing this, I was well aware of virt-what, which is exactly
why I wrote that comment the way I did - the code used by virt-what
is not easy, reliable or (IMO) reasonable to copy/paste into LTP.
Specifically with kvm, the KVMKVMKVM detection used to fail (IIRC)
with some specific hosts and qemu versions. It can also be easily
bypassed with -cpu host,kvm=off (which doesn't disable kvm accel).
> cpuinfo = SAFE_FOPEN(NULL, "/proc/cpuinfo", "r");
> found = 0;
> while (fgets(line, sizeof(line), cpuinfo) != NULL) {
> if (strstr(line, "QEMU Virtual CPU")) {
> - found = 1;
> + /*
> + * Is it an KVM(on top of QEMU) or Only a QEMU?
> + */
Well, yes, I'm aware that "KVM" is really just QEMU + accel, which
is why my original series actually had VIRT_QEMU instead of VIRT_KVM,
but then it was pointed out to me that VIRT_KVM would make sense to
most people not knowledgeable enough in this area.
I'm not against renaming it, but I'm a bit baffled by the separation.
> + if (cpu_sign(&sig[0]) == 0) {
> + if (strcmp(sig, "KVMKVMKVM") == 0) {
> + found = 1;
> + } else {
> + // QEMU Guest
This leads me to ask why did you create the patches - why should the
default QEMU with TCG be any different w.r.t. the only test that
currently uses the tst_is_virt() function?
Again, I'm not against renaming VIRT_KVM to VIRT_QEMU as it would be
technically more correct, but why separate accel=kvm from accel=tcg?
What about accel=xen?
> + }
> + } else {
> + found = 1;
> + }
> break;
> }
> }
>
Thanks,
Jiri
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 4+ messages in thread
* [LTP] 答复: [PATCH 2/2] lib/tst_virt.c: distinguish between KVM and QEMU
2015-02-24 11:36 ` Jiri Jaburek
@ 2015-02-25 3:31 ` Wei, Jiangang
0 siblings, 0 replies; 4+ messages in thread
From: Wei, Jiangang @ 2015-02-25 3:31 UTC (permalink / raw)
To: Jiri Jaburek; +Cc: ltp-list@lists.sourceforge.net
Hi,
> Hello and thanks for the patch. Aside from indent issues (please use
> tabs, Linux kernel style), I have some comments/questions:
Thanks for your reminder.
I'll take care of it.
> On 02/24/2015 09:27 AM, Wei,Jiangang wrote:
> > KVM guest is on top of QEMU, It's necessary that figure out
> > the difference between the two.
> >
> > Signed-off-by: Wei,Jiangang <weijg.fnst@cn.fujitsu.com>
> > ---
> > lib/tst_virt.c | 16 +++++++++++++---
> > 1 file changed, 13 insertions(+), 3 deletions(-)
> >
> > diff --git a/lib/tst_virt.c b/lib/tst_virt.c
> > index eb3b487..1d9960e 100644
> > --- a/lib/tst_virt.c
> > +++ b/lib/tst_virt.c
> > @@ -100,14 +100,24 @@ static int is_kvm(void)
> > FILE *cpuinfo;
> > char line[64];
> > int found;
> > + char sig[SIG_MAX_LEN];
> >
> > - /* this doesn't work with custom -cpu values, since there's
> > - * no easy, reasonable or reliable way to work around those */
>
> When writing this, I was well aware of virt-what, which is exactly
> why I wrote that comment the way I did - the code used by virt-what
> is not easy, reliable or (IMO) reasonable to copy/paste into LTP.
> Specifically with kvm, the KVMKVMKVM detection used to fail (IIRC)
So far, I haven't met such an error.
Maybe it's depended on the different version.
In fact, The case of its' failure had been considered in this patch.
When cpu_sign() returns non-zero,
It will degenerate and determine the Guest Type by the original method,
Which just check the string ' QEMU Virtual CPU ' in /proc/cpuinfo.
As following,
if (cpu_sign(&sig[0]) == 0) {
...
} else {
found = 1;
}
> with some specific hosts and qemu versions. It can also be easily
> bypassed with -cpu host,kvm=off (which doesn't disable kvm accel).
Indeed, I agree with you.
>
> > cpuinfo = SAFE_FOPEN(NULL, "/proc/cpuinfo", "r");
> > found = 0;
> > while (fgets(line, sizeof(line), cpuinfo) != NULL) {
> > if (strstr(line, "QEMU Virtual CPU")) {
> > - found = 1;
> > + /*
> > + * Is it an KVM(on top of QEMU) or Only a QEMU?
> > + */
>
> Well, yes, I'm aware that "KVM" is really just QEMU + accel, which
> is why my original series actually had VIRT_QEMU instead of VIRT_KVM,
> but then it was pointed out to me that VIRT_KVM would make sense to
> most people not knowledgeable enough in this area.
>
> I'm not against renaming it, but I'm a bit baffled by the separation.
>
> > + if (cpu_sign(&sig[0]) == 0) {
> > + if (strcmp(sig, "KVMKVMKVM") == 0) {
> > + found = 1;
> > + } else {
> > + // QEMU Guest
>
> This leads me to ask why did you create the patches - why should the
> default QEMU with TCG be any different w.r.t. the only test that
> currently uses the tst_is_virt() function?
>
> Again, I'm not against renaming VIRT_KVM to VIRT_QEMU as it would be
> technically more correct, but why separate accel=kvm from accel=tcg?
> What about accel=xen?
Initially, I found that,
The function named is_kvm() is only can be applied to determine QEMU,
Which couldn't distinguish QEMU and QEMU-KVM.
So, I tried to make this function has the ability to determine
the difference between the two.
The only test that uses the tst_is_virt() skips,
no matter what QEMU or QEMU-KVM.
My effort seems pointless.
For is_kvm and VIRT_KVM,
I still regard that its' name doesn't match its' content and function.
is_qemu() more reasonable.
If you don't mind,
I will push a new patch to improve it.
Thanks,
Wei
> > + }
> > + } else {
> > + found = 1;
> > + }
> > break;
> > }
> > }
> >
>
> Thanks,
> Jiri
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-02-25 3:31 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-24 8:27 [LTP] [PATCH 1/2] lib: provide a way to detect if we are running on KVM or Xen Wei,Jiangang
2015-02-24 8:27 ` [LTP] [PATCH 2/2] lib/tst_virt.c: distinguish between KVM and QEMU Wei,Jiangang
2015-02-24 11:36 ` Jiri Jaburek
2015-02-25 3:31 ` [LTP] 答复: " Wei, Jiangang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox