Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ept-devel/vmm/core/asm.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (show annotations) (download) (as text)
Sat May 5 12:42:38 2012 UTC (12 months, 2 weeks ago) by yuichi_xy
File MIME type: text/x-chdr
File size: 16757 byte(s)
EPT が有効な場合は、 Guest OS が指定した PAT を物理 PAT として使用するようにした。つまり、VM-entry/VM-exitで Guest 用 PAT と Host 用 PAT を切り替える。
1 /*
2 * Copyright (c) 2007, 2008 University of Tsukuba
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. Neither the name of the University of Tsukuba nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*
30 * Copyright (c) 2010-2012 Yuichi Watanabe
31 */
32
33 #ifndef _CORE_ASM_H
34 #define _CORE_ASM_H
35
36 #include <core/linkage.h>
37 #include "desc.h"
38 #include <core/types.h>
39
40 struct vt_vmentry_regs {
41 ulong rax, rcx, rdx, rbx, cr2, rbp, rsi, rdi;
42 ulong r8, r9, r10, r11, r12, r13, r14, r15;
43 ulong cr3;
44 int pe, pg;
45 struct {
46 int enable, num;
47 u16 es, cs, ss, ds, fs, gs;
48 } sw;
49 };
50
51 struct svm_vmrun_regs {
52 ulong cr0, rcx, rdx, rbx, cr4, rbp, rsi, rdi;
53 ulong r8, r9, r10, r11, r12, r13, r14, r15;
54 ulong cr3;
55 };
56
57 #define SW_SREG_ES_BIT (1 << 0)
58 #define SW_SREG_CS_BIT (1 << 1)
59 #define SW_SREG_SS_BIT (1 << 2)
60 #define SW_SREG_DS_BIT (1 << 3)
61 #define SW_SREG_FS_BIT (1 << 4)
62 #define SW_SREG_GS_BIT (1 << 5)
63
64 #define ASM_VMCALL "vmcall"
65
66 asmlinkage int asm_vmlaunch_regs_32 (struct vt_vmentry_regs *p);
67 asmlinkage int asm_vmresume_regs_32 (struct vt_vmentry_regs *p);
68 asmlinkage int asm_vmlaunch_regs_64 (struct vt_vmentry_regs *p);
69 asmlinkage int asm_vmresume_regs_64 (struct vt_vmentry_regs *p);
70 asmlinkage void asm_vmrun_regs_32 (struct svm_vmrun_regs *p, ulong vmcb_phys,
71 ulong vmcbhost_phys);
72 asmlinkage void asm_vmrun_regs_64 (struct svm_vmrun_regs *p, ulong vmcb_phys,
73 ulong vmcbhost_phys);
74
75 static inline void
76 asm_cpuid (u32 num, u32 numc, u32 *a, u32 *b, u32 *c, u32 *d)
77 {
78 asm volatile ("cpuid"
79 : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
80 : "a" (num), "c" (numc));
81 }
82
83 static inline void
84 asm_rdmsr32 (ulong num, u32 *a, u32 *d)
85 {
86 asm volatile ("rdmsr"
87 : "=a" (*a), "=d" (*d)
88 : "c" (num));
89 }
90
91 static inline void
92 asm_wrmsr32 (ulong num, u32 a, u32 d)
93 {
94 asm volatile ("wrmsr"
95 :
96 : "c" (num), "a" (a), "d" (d));
97 }
98
99 static inline void
100 asm_rdmsr64 (ulong num, u64 *value)
101 {
102 u32 a, d;
103
104 asm_rdmsr32 (num, &a, &d);
105 *value = (u64)a | ((u64)d << 32);
106 }
107
108 static inline void
109 asm_wrmsr64 (ulong num, u64 value)
110 {
111 u32 a, d;
112
113 a = (u32)value;
114 d = (u32)(value >> 32);
115 asm_wrmsr32 (num, a, d);
116 }
117
118 static inline void
119 asm_rdmsr (ulong num, ulong *value)
120 {
121 #ifdef __x86_64__
122 u64 value64;
123 asm_rdmsr64 (num, &value64);
124 *value = value64;
125 #else
126 u32 value32;
127 u32 dummy;
128 asm_rdmsr32 (num, &value32, &dummy);
129 *value = value32;
130 #endif
131 }
132
133 static inline void
134 asm_wrmsr (ulong num, ulong value)
135 {
136 #ifdef __x86_64__
137 asm_wrmsr64 (num, (u64)value);
138 #else
139 asm_wrmsr32 (num, (u32)value, 0);
140 #endif
141 }
142
143 static inline void
144 asm_rdcr0 (ulong *cr0)
145 {
146 asm volatile ("mov %%cr0,%0"
147 : "=r" (*cr0));
148 }
149
150 static inline void
151 asm_wrcr0 (ulong cr0)
152 {
153 asm volatile ("mov %0,%%cr0"
154 :
155 : "r" (cr0));
156 }
157
158 static inline void
159 asm_rdcr2 (ulong *cr2)
160 {
161 asm volatile ("mov %%cr2,%0"
162 : "=r" (*cr2));
163 }
164
165 static inline void
166 asm_wrcr2 (ulong cr2)
167 {
168 asm volatile ("mov %0,%%cr2"
169 :
170 : "r" (cr2));
171 }
172
173 static inline void
174 asm_rdcr3 (ulong *cr3)
175 {
176 asm volatile ("mov %%cr3,%0"
177 : "=r" (*cr3));
178 }
179
180 static inline void
181 asm_wrcr3 (ulong cr3)
182 {
183 asm volatile ("mov %0,%%cr3"
184 :
185 : "r" (cr3));
186 }
187
188 static inline void
189 asm_rdcr4 (ulong *cr4)
190 {
191 asm volatile ("mov %%cr4,%0"
192 : "=r" (*cr4));
193 }
194
195 static inline void
196 asm_wrcr4 (ulong cr4)
197 {
198 asm volatile ("mov %0,%%cr4"
199 :
200 : "r" (cr4));
201 }
202
203 #ifdef __x86_64__
204 static inline void
205 asm_rdcr8 (u64 *cr8)
206 {
207 asm volatile ("mov %%cr8,%0"
208 : "=r" (*cr8));
209 }
210
211 static inline void
212 asm_wrcr8 (ulong cr8)
213 {
214 asm volatile ("mov %0,%%cr8"
215 :
216 : "r" (cr8));
217 }
218 #endif
219
220 /* f3 0f c7 33 vmxon (%ebx) */
221 static inline void
222 asm_vmxon (void *vmxon_region)
223 {
224 asm volatile ("vmxon %0"
225 :
226 : "m" (*(ulong *)vmxon_region)
227 : "cc", "memory");
228 }
229
230 /* 0f 01 c4 vmxoff */
231 static inline void
232 asm_vmxoff (void)
233 {
234 asm volatile ("vmxoff"
235 :
236 :
237 : "cc");
238 }
239
240 /* 66 0f c7 33 vmclear (%ebx) */
241 static inline void
242 asm_vmclear (void *p)
243 {
244 #ifdef AS_DOESNT_SUPPORT_VMX
245 asm volatile (".byte 0x66, 0x0f, 0xc7, 0x33"
246 :
247 : "b" (p)
248 : "cc", "memory");
249 #else
250 asm volatile ("vmclear %0"
251 :
252 : "m" (*(ulong *)p)
253 : "cc", "memory");
254 #endif
255 }
256
257 /* 0f c7 33 vmptrld (%ebx) */
258 static inline void
259 asm_vmptrld (void *p)
260 {
261 asm volatile ("vmptrld %0"
262 :
263 : "m" (*(ulong *)p)
264 : "cc", "memory");
265 }
266
267 /* 0f c7 3b vmptrst (%ebx) */
268 static inline void
269 asm_vmptrst (void *p)
270 {
271 asm volatile ("vmptrst %0"
272 :
273 : "m" (*(ulong *)p)
274 : "cc", "memory");
275 }
276
277 /* 0f 79 c2 vmwrite %edx,%eax */
278 static inline void
279 asm_vmwrite (ulong index, ulong val)
280 {
281 #ifdef AS_DOESNT_SUPPORT_VMX
282 asm volatile (".byte 0x0f, 0x79, 0xc2"
283 :
284 : "a" (index), "d" (val)
285 : "cc");
286 #else
287 asm volatile ("vmwrite %1,%0"
288 :
289 : "r" (index), "rm" (val)
290 : "cc");
291 #endif
292 }
293
294 static inline void
295 asm_vmwrite32(ulong index, u32 val)
296 {
297 ulong ulong_val = val;
298 asm volatile ("vmwrite %1,%0"
299 :
300 : "r" (index), "rm" (ulong_val)
301 : "cc");
302 }
303
304 static inline void
305 asm_vmwrite64(ulong index, u64 val)
306 {
307 #ifdef __x86_64__
308 asm volatile ("vmwrite %1,%0"
309 :
310 : "r" (index), "rm" (val)
311 : "cc");
312 #else
313 ulong low, high;
314 low = val;
315 high = val >> 32;
316 asm_vmwrite(index, low);
317 asm_vmwrite(index + 1, high);
318 #endif
319 }
320
321 /* 0f 01 c2 vmlaunch */
322 static inline int
323 asm_vmlaunch_regs (struct vt_vmentry_regs *p)
324 {
325 #ifdef __x86_64__
326 return asm_vmlaunch_regs_64 (p);
327 #else
328 return asm_vmlaunch_regs_32 (p);
329 #endif
330 }
331
332 /* 0f 01 c3 vmresume */
333 static inline int
334 asm_vmresume_regs (struct vt_vmentry_regs *p)
335 {
336 #ifdef __x86_64__
337 return asm_vmresume_regs_64 (p);
338 #else
339 return asm_vmresume_regs_32 (p);
340 #endif
341 }
342
343 /* 0f 78 c2 vmread %eax,%edx */
344 static inline void
345 asm_vmread (ulong index, ulong *val)
346 {
347 asm volatile ("vmread %1,%0"
348 : "=rm" (*val)
349 : "r" (index)
350 : "cc");
351 }
352
353 static inline void
354 asm_vmread32(ulong index, u32 *val)
355 {
356 ulong ulong_val;
357 asm volatile ("vmread %1,%0"
358 : "=rm" (ulong_val)
359 : "r" (index)
360 : "cc");
361 *val = ulong_val;
362 }
363
364 static inline void
365 asm_vmread64(ulong index, u64 *val)
366 {
367 #ifdef __x86_64__
368 asm volatile ("vmread %1,%0"
369 : "=rm" (*val)
370 : "r" (index)
371 : "cc");
372 #else
373 ulong low, high;
374 asm_vmread(index, &low);
375 asm_vmread(index + 1, &high);
376 *val = low | (high << 32);
377 #endif
378 }
379
380 static inline void
381 asm_invept(void *desc)
382 {
383 #ifdef __x86_64__
384 asm volatile ("invept (%0), %%rax"
385 :
386 : "r" (desc),
387 "a" (1)
388 : "cc");
389 #else
390 asm volatile ("invept (%0), %%eax"
391 :
392 : "r" (desc),
393 "a" (1)
394 : "cc");
395 #endif
396 }
397
398 static inline void
399 asm_rdes (u16 *es)
400 {
401 asm volatile ("mov %%es,%0"
402 : "=rm" (*es));
403 }
404
405 static inline void
406 asm_rdcs (u16 *cs)
407 {
408 asm volatile ("mov %%cs,%0"
409 : "=rm" (*cs));
410 }
411
412 static inline void
413 asm_rdss (u16 *ss)
414 {
415 asm volatile ("mov %%ss,%0"
416 : "=rm" (*ss));
417 }
418
419 static inline void
420 asm_rdds (u16 *ds)
421 {
422 asm volatile ("mov %%ds,%0"
423 : "=rm" (*ds));
424 }
425
426 static inline void
427 asm_rdfs (u16 *fs)
428 {
429 asm volatile ("mov %%fs,%0"
430 : "=rm" (*fs));
431 }
432
433 static inline void
434 asm_rdgs (u16 *gs)
435 {
436 asm volatile ("mov %%gs,%0"
437 : "=rm" (*gs));
438 }
439
440 static inline void
441 asm_wres (u16 es)
442 {
443 asm volatile ("mov %0, %%es"
444 :
445 : "rm" ((ulong)es));
446 }
447
448 static inline void
449 asm_wrcs (u16 cs)
450 {
451 #ifdef __x86_64__
452 asm volatile ("pushq %0; push $1f; lretq; 1:"
453 :
454 : "g" ((ulong)cs));
455 #else
456 asm volatile ("pushl %0; push $1f; lret; 1:"
457 :
458 : "g" ((ulong)cs));
459 #endif
460 }
461
462 static inline void
463 asm_wrss (u16 ss)
464 {
465 asm volatile ("mov %0, %%ss"
466 :
467 : "rm" ((ulong)ss));
468 }
469
470 static inline void
471 asm_wrds (u16 ds)
472 {
473 asm volatile ("mov %0, %%ds"
474 :
475 : "rm" ((ulong)ds));
476 }
477
478 static inline void
479 asm_wrfs (u16 fs)
480 {
481 asm volatile ("mov %0, %%fs"
482 :
483 : "rm" ((ulong)fs));
484 }
485
486 static inline void
487 asm_wrgs (u16 gs)
488 {
489 asm volatile ("mov %0, %%gs"
490 :
491 : "rm" ((ulong)gs));
492 }
493
494 static inline void
495 asm_rdldtr (u16 *ldtr)
496 {
497 asm volatile ("sldt %0"
498 : "=rm" (*ldtr));
499 }
500
501 static inline void
502 asm_wrldtr (u16 ldtr)
503 {
504 asm volatile ("lldt %0"
505 :
506 : "rm" (ldtr));
507 }
508
509 static inline void
510 asm_rdtr (u16 *tr)
511 {
512 asm volatile ("str %0"
513 : "=rm" (*tr));
514 }
515
516 static inline void
517 asm_wrtr (u16 tr)
518 {
519 asm volatile ("ltr %0"
520 :
521 : "rm" (tr));
522 }
523
524 static inline void
525 asm_lsl (u32 sel, ulong *limit)
526 {
527 asm volatile ("lsl %1,%0"
528 : "=r" (*limit)
529 : "rm" ((ulong)sel)); /* avoid assembler bug */
530 }
531
532 static inline void
533 asm_lar (u32 sel, ulong *ar)
534 {
535 asm volatile ("lar %1,%0"
536 : "=r" (*ar)
537 : "rm" ((ulong)sel)); /* avoid assembler bug */
538 }
539
540 static inline void
541 asm_rdgdtr (ulong *gdtbase, ulong *gdtlimit)
542 {
543 struct descreg gdtr;
544
545 asm volatile ("sgdt %0"
546 : "=m" (gdtr));
547 *gdtbase = gdtr.base;
548 *gdtlimit = gdtr.limit;
549 }
550
551 static inline void
552 asm_rdidtr (ulong *idtbase, ulong *idtlimit)
553 {
554 struct descreg idtr;
555
556 asm volatile ("sidt %0"
557 : "=m" (idtr));
558 *idtbase = idtr.base;
559 *idtlimit = idtr.limit;
560 }
561
562 static inline void
563 asm_wrgdtr (ulong gdtbase, ulong gdtlimit)
564 {
565 struct descreg gdtr;
566
567 gdtr.base = gdtbase;
568 gdtr.limit = gdtlimit;
569 asm volatile ("lgdt %0"
570 :
571 : "m" (gdtr));
572 }
573
574 static inline void
575 asm_wridtr (ulong idtbase, ulong idtlimit)
576 {
577 struct descreg idtr;
578
579 idtr.base = idtbase;
580 idtr.limit = idtlimit;
581 asm volatile ("lidt %0"
582 :
583 : "m" (idtr));
584 }
585
586 static inline void
587 asm_rddr7 (ulong *dr7)
588 {
589 asm volatile ("mov %%dr7,%0"
590 : "=r" (*dr7));
591 }
592
593 static inline void
594 asm_rdrflags (ulong *rflags)
595 {
596 asm volatile (
597 #ifdef __x86_64__
598 "pushfq ; popq %0"
599 #else
600 "pushfl ; popl %0"
601 #endif
602 : "=rm" (*rflags));
603 }
604
605 static inline void
606 asm_inb (ioport_t port, u8 *data)
607 {
608 asm volatile ("inb %%dx,%%al"
609 : "=a" (*data)
610 : "d" (port));
611 }
612
613 static inline void
614 asm_inw (ioport_t port, u16 *data)
615 {
616 asm volatile ("inw %%dx,%%ax"
617 : "=a" (*data)
618 : "d" (port));
619 }
620
621 static inline void
622 asm_inl (ioport_t port, u32 *data)
623 {
624 asm volatile ("inl %%dx,%%eax"
625 : "=a" (*data)
626 : "d" (port));
627 }
628
629 static inline void
630 asm_outb (ioport_t port, u8 data)
631 {
632 asm volatile ("outb %%al,%%dx"
633 :
634 : "a" (data)
635 , "d" (port));
636 }
637
638 static inline void
639 asm_outw (ioport_t port, u16 data)
640 {
641 asm volatile ("outw %%ax,%%dx"
642 :
643 : "a" (data)
644 , "d" (port));
645 }
646
647 static inline void
648 asm_outl (ioport_t port, u32 data)
649 {
650 asm volatile ("outl %%eax,%%dx"
651 :
652 : "a" (data)
653 , "d" (port));
654 }
655
656 static inline void
657 asm_cli (void)
658 {
659 asm volatile ("cli");
660 }
661
662 static inline void
663 asm_sti (void)
664 {
665 asm volatile ("sti");
666 }
667
668 static inline void
669 asm_wrrsp_and_jmp (ulong rsp, void *jmpto)
670 {
671 asm volatile (
672 #ifdef __x86_64__
673 "mov %0,%%rsp;"
674 "xor %%rbp,%%rbp;"
675 "push %%rbp;"
676 "jmp *%1"
677 #else
678 "mov %0,%%esp;"
679 "xor %%ebp,%%ebp;"
680 "push %%ebp;"
681 "jmp *%1"
682 #endif
683 :
684 : "g" (rsp)
685 , "r" (jmpto));
686 }
687
688 static inline void
689 asm_wrrsp_and_ret (ulong rsp, ulong rax)
690 {
691 asm volatile (
692 #ifdef __x86_64__
693 "mov %0,%%rsp; ret"
694 #else
695 "mov %0,%%esp; ret"
696 #endif
697 :
698 : "g" (rsp)
699 , "a" (rax));
700 }
701
702 static inline void
703 asm_wbinvd (void)
704 {
705 asm volatile ("wbinvd");
706 }
707
708 static inline void
709 asm_invlpg (void *p)
710 {
711 asm volatile ("invlpg %0"
712 :
713 : "m" (*(u8 *)p));
714 }
715
716 static inline void
717 asm_cli_and_hlt (void)
718 {
719 asm volatile ("cli; hlt");
720 }
721
722 static inline void
723 asm_pause (void)
724 {
725 asm volatile ("pause");
726 }
727
728 static inline void
729 asm_rdrsp (ulong *rsp)
730 {
731 #ifdef __x86_64__
732 asm volatile ("mov %%rsp,%0" : "=rm" (*rsp));
733 #else
734 asm volatile ("mov %%esp,%0" : "=rm" (*rsp));
735 #endif
736 }
737
738 static inline void
739 asm_rdtsc (u32 *a, u32 *d)
740 {
741 asm volatile ("rdtsc" : "=a" (*a), "=d" (*d));
742 }
743
744 static inline void
745 asm_mul_and_div (u32 mul1, u32 mul2, u32 div1, u32 *quotient, u32 *remainder)
746 {
747 asm volatile ("mull %4 ; divl %5"
748 : "=&a" (*quotient)
749 , "=&d" (*remainder)
750 : "0" (mul1)
751 , "1" (0)
752 , "rm" (mul2)
753 , "rm" (div1)
754 : "cc");
755 }
756
757 static inline void
758 asm_lock_incl (u32 *d)
759 {
760 asm volatile ("lock incl %0" : "=m" (*d));
761 }
762
763 /*
764 if (*dest == *cmp) {
765 *dest = eq;
766 return false;
767 } else {
768 *cmp = *dest;
769 return true;
770 }
771 */
772 static inline bool
773 asm_lock_cmpxchgl (u32 *dest, u32 *cmp, u32 eq)
774 {
775 int tmp = 0;
776
777 asm volatile ("lock cmpxchgl %4,%1 ; je 1f ; inc %2 ; 1:"
778 : "=&a" (*cmp)
779 , "=m" (*dest)
780 , "=&r" (tmp)
781 : "0" (*cmp)
782 , "r" (eq)
783 , "2" (0)
784 : "memory", "cc");
785 return (bool)tmp;
786 }
787
788 static inline bool
789 asm_lock_cmpxchgq (u64 *dest, u64 *cmp, u64 eq)
790 {
791 int tmp;
792
793 #ifdef __x86_64__
794 asm volatile ("lock cmpxchgq %4,%1 ; je 1f ; inc %2 ; 1:"
795 : "=&a" (*cmp)
796 , "=m" (*dest)
797 , "=&r" (tmp)
798 : "0" (*cmp)
799 , "r" (eq)
800 , "2" (0)
801 : "memory", "cc");
802 #else
803 asm volatile ("lock cmpxchg8b %1 ; je 1f ; inc %2 ; 1:"
804 : "=&A" (*cmp)
805 , "=m" (*dest)
806 , "=&r" (tmp)
807 : "0" (*cmp)
808 , "b" ((u32)eq)
809 , "c" ((u32)(eq >> 32))
810 , "2" (0)
811 : "memory", "cc");
812 #endif
813 return (bool)tmp;
814 }
815
816 /* old = *mem; *mem = newval; return old; */
817 static inline ulong
818 asm_lock_swap_ulong (ulong *mem, ulong newval)
819 {
820 ulong oldval;
821
822 asm volatile ("xchg %0,%1"
823 : "=r" (oldval)
824 , "=m" (*mem)
825 : "0" (newval));
826 return oldval;
827 }
828
829 static inline ulong
830 asm_lock_test_ulong (ulong *mem, int bit)
831 {
832 ulong val;
833 asm volatile ("bt %2,%0\n"
834 "setc %%al"
835 : "=m" (*mem)
836 , "=r" (val)
837 : "r" (bit)
838 , "1" (0));
839 return val;
840 }
841
842 static inline ulong
843 asm_lock_test_and_set_ulong (ulong *mem, int bit)
844 {
845 ulong oldval;
846 asm volatile ("lock bts %2,%0\n"
847 "setc %%al"
848 : "=m" (*mem)
849 , "=a" (oldval)
850 : "r" (bit)
851 , "1" (0));
852 return oldval;
853 }
854
855 static inline ulong
856 asm_lock_test_and_clear_ulong (ulong *mem, int bit)
857 {
858 ulong oldval;
859 asm volatile ("lock btr %2,%0\n"
860 "setc %%al"
861 : "=m" (*mem)
862 , "=a" (oldval)
863 : "r" (bit)
864 , "1" (0));
865 return oldval;
866 }
867
868 /*
869 * Bit scan reverse.
870 * Find the most significant set bit.
871 */
872 static inline long
873 asm_bsr_ulong (ulong *mem)
874 {
875 long bit;
876 if (*mem == 0) {
877 return -1;
878 }
879 asm volatile ("bsr %1,%0\n"
880 : "=r" (bit)
881 : "m" (*mem));
882 return bit;
883 }
884
885 /*
886 * BIT scan forward.
887 * Find the least significant set bit.
888 */
889 static inline long
890 asm_bsf_ulong (ulong *mem)
891 {
892 long bit;
893 if (*mem == 0) {
894 return -1;
895 }
896 asm volatile ("bsf %1,%0\n"
897 : "=r" (bit)
898 : "m" (*mem));
899 return bit;
900 }
901
902 /* 0f 01 d8 vmrun */
903 static inline void
904 asm_vmrun_regs (struct svm_vmrun_regs *p, ulong vmcb_phys, ulong vmcbhost_phys)
905 {
906 #ifdef __x86_64__
907 asm_vmrun_regs_64 (p, vmcb_phys, vmcbhost_phys);
908 #else
909 asm_vmrun_regs_32 (p, vmcb_phys, vmcbhost_phys);
910 #endif
911 }
912
913
914 static inline void
915 asm_monitor (void *addr, u32 c, u32 d)
916 {
917 asm volatile ("monitor"
918 :: "a" (addr), "c" (c), "d" (d));
919 }
920
921 static inline void
922 asm_mwait (u32 a, u32 c)
923 {
924 asm volatile ("mwait"
925 ::"a" (a), "c" (c));
926 }
927
928 #endif

SourceForge.JP is a Japanese version of SourceForge.net. For developments that are not related to Japan, we recommend you to use SourceForge.net.