summaryrefslogtreecommitdiffstats
path: root/zarb-ml/mageia-dev/attachments/20120109/d93f433f/attachment-0003.obj
diff options
context:
space:
mode:
Diffstat (limited to 'zarb-ml/mageia-dev/attachments/20120109/d93f433f/attachment-0003.obj')
-rw-r--r--zarb-ml/mageia-dev/attachments/20120109/d93f433f/attachment-0003.obj93
1 files changed, 93 insertions, 0 deletions
diff --git a/zarb-ml/mageia-dev/attachments/20120109/d93f433f/attachment-0003.obj b/zarb-ml/mageia-dev/attachments/20120109/d93f433f/attachment-0003.obj
new file mode 100644
index 000000000..2bd391f8b
--- /dev/null
+++ b/zarb-ml/mageia-dev/attachments/20120109/d93f433f/attachment-0003.obj
@@ -0,0 +1,93 @@
+c::is_xen() use cpuid in order to detect we're under XEN
+
+diff -up ./c/stuff.xs.pl.tv2 ./c/stuff.xs.pl
+--- ./c/stuff.xs.pl.tv2 2012-01-09 10:49:22.807894338 +0100
++++ ./c/stuff.xs.pl 2012-01-09 11:03:04.124482279 +0100
+@@ -105,6 +105,40 @@ int length_of_space_padded(char *str, in
+ return len;
+ }
+
++int pv_context;
++static void cpuid(uint32_t idx,
++ uint32_t *eax,
++ uint32_t *ebx,
++ uint32_t *ecx,
++ uint32_t *edx)
++{
++ asm volatile (
++ "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid"
++ : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
++ : "0" (idx), "1" (pv_context) );
++}
++
++static int check_for_xen(void)
++{
++ uint32_t eax, ebx, ecx, edx;
++ char signature[13];
++
++ cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
++ *(uint32_t *)(signature + 0) = ebx;
++ *(uint32_t *)(signature + 4) = ecx;
++ *(uint32_t *)(signature + 8) = edx;
++ signature[12] = ' . "'\0'" . ';
++
++ if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
++ return 0;
++
++ cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
++ printf("Running in %s context on Xen v%d.%d.\n",
++ pv_context ? "PV" : "HVM", (uint16_t)(eax >> 16), (uint16_t)eax);
++ return 1;
++}
++
++
+ MODULE = c::stuff PACKAGE = c::stuff
+
+ ';
+@@ -116,6 +150,46 @@ pcmcia_probe()
+
+ print '
+ int
++is_xen()
++ CODE:
++ pid_t pid;
++ int status;
++ uint32_t dummy;
++
++ /* Check for execution in HVM context. */
++ if ( check_for_xen() )
++ return 0;
++
++ /* Now we check for execution in PV context. */
++ pv_context = 1;
++
++ /*
++ * Fork a child to test the paravirtualised CPUID instruction.
++ * If executed outside Xen PV context, the extended opcode will fault.
++ */
++ pid = fork();
++ switch ( pid )
++ {
++ case 0:
++ /* Child: test paravirtualised CPUID opcode and then exit cleanly. */
++ cpuid(0x40000000, &dummy, &dummy, &dummy, &dummy);
++ exit(0);
++ case -1:
++ fprintf(stderr, "Fork failed.\n");
++ return 0;
++ }
++
++ /*
++ * Parent waits for child to terminate and checks for clean exit.
++ * Only if the exit is clean is it safe for us to try the extended CPUID.
++ */
++ waitpid(pid, &status, 0);
++ if ( WIFEXITED(status) && check_for_xen() )
++ return 0;
++
++ return 0;
++
++int
+ del_partition(hd, part_number)
+ int hd
+ int part_number \ No newline at end of file