12

CPU虚拟化:虚拟机切入和退出

 3 years ago
source link: https://os.51cto.com/art/202012/634022.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

CPU铏氭嫙鍖栵細铏氭嫙鏈哄垏鍏ュ拰閫€鍑

鏈枃閲嶇偣璁ㄨ浜嗚櫄鎷熸満CPU濡備綍鍦℉ost妯″紡鍜孏uest妯″紡涔嬮棿鍒囨崲锛屼互鍙婂湪Host妯″紡鍜孏uest妯″紡鍒囨崲鏃讹紝KVM鍙婄墿鐞咰PU鏄浣曚繚瀛樿櫄鎷烠PU鐨勪笂涓嬫枃鐨勩€

鏈枃閲嶇偣璁ㄨ浜嗚櫄鎷熸満CPU濡備綍鍦℉ost妯″紡鍜孏uest妯″紡涔嬮棿鍒囨崲锛屼互鍙婂湪Host妯″紡鍜孏uest妯″紡鍒囨崲鏃讹紝KVM鍙婄墿鐞咰PU鏄浣曚繚瀛樿櫄鎷烠PU鐨勪笂涓嬫枃鐨勩€

b0d67c5c29a286d1efe08a1f758c924a.jpg-wh_651x-s_1755917119.jpg

涓€銆丟CC鍐呰仈姹囩紪

KVM妯″潡涓垏鍏uest妯″紡鐨勪唬鐮佷娇鐢℅CC鐨勫唴鑱旀眹缂栫紪鍐欙紝涓轰簡鐞嗚В杩欐浠g爜锛屾垜浠渶瑕佺畝瑕佸湴浠嬬粛涓€涓嬭繖娈靛唴鑱旀眹缂栨秹鍙婄殑璇硶锛屽叾鍩烘湰璇硶妯℃澘濡備笅锛

  1. asm聽volatile聽(聽assembler聽template聽聽
  2. 聽聽聽聽:聽output聽operands聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽/*聽optional聽*/聽
  3. 聽聽聽聽:聽input聽operands聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽/*聽optional聽*/聽
  4. 聽聽聽聽:聽list聽of聽clobbered聽registers聽聽聽聽聽聽/*聽optional聽*/聽

1. 鍏抽敭瀛梐sm鍜寁olatile

asm涓篏CC鍏抽敭瀛楋紝琛ㄧず鎺ヤ笅鏉ヨ宓屽叆姹囩紪浠g爜锛屽鏋渁sm涓庣▼搴忎腑鍏朵粬鍛藉悕鍐茬獊锛屽彲浠ヤ娇鐢╛_asm__銆

volatile涓哄彲閫夊叧閿瓧锛岃〃绀轰笉闇€瑕丟CC瀵逛笅闈㈢殑姹囩紪浠g爜鍋氫换浣曚紭鍖栵紝绫讳技鐨勶紝GCC涔熸敮鎸乢_volatile__銆

2. 姹囩紪鎸囦护(assembler template)

杩欓儴鍒嗗嵆瑕佸祵鍏ョ殑姹囩紪鎸囦护锛岀敱浜庢槸鍦–璇█涓唴鑱旀眹缂栦唬鐮侊紝鍥犳椤荤敤鍙屽紩鍙峰皢鍛戒护鎷捣鏉ャ€傚鏋滃唴宓屽琛屾眹缂栨寚浠わ紝鍒欐瘡鏉℃寚浠ゅ崰鐢1琛岋紝姣忚鎸囦护浣跨敤鍙屽紩鍙锋嫭璧锋潵锛屼互鍚庣紑\n\t缁撳熬锛屽叾涓璡n涓簄ewline鐨勭缉鍐欙紝\t涓簍ab鐨勭缉鍐欍€傜敱浜嶨CC灏嗘瘡鏉℃寚浠や互瀛楃涓茬殑褰㈠紡浼犻€掔粰姹囩紪鍣ˋS锛屾墍浠ユ垜浠娇鐢╘n\t鍒嗛殧绗︽潵鍒嗛殧姣忎竴鏉℃寚浠わ紝绀轰緥浠g爜濡備笅锛

  1. __asm__聽("movl聽%eax,聽%ebx聽\n\t"聽
  2. 聽聽聽聽聽聽聽聽聽聽"movl聽$56,聽%esi聽\n\t"聽
  3. 聽聽聽聽聽聽聽聽聽聽"movl聽%ecx,聽$label(%edx,%ebx,$4)聽\n\t"聽
  4. 聽聽聽聽聽聽聽聽聽聽"movb聽%ah,聽(%ebx)聽\n\t");聽

褰撲娇鐢ㄦ墿灞曟ā寮忥紝鍗冲寘鍚玱utput銆乮nput鍜宑lobber list閮ㄥ垎鏃讹紝姹囩紪鎸囦护涓渶瑕佷娇鐢ㄤ袱涓€%鈥濇潵寮曠敤瀵勫瓨鍣紝姣斿%%rax;浣跨敤涓€涓€%鈥濇潵寮曠敤杈撳叆銆佽緭鍑烘搷浣滄暟锛屾瘮濡%1锛屼互渚垮府鍔〨CC鍖哄垎瀵勫瓨鍣ㄥ拰鐢盋璇█鎻愪緵鐨勬搷浣滄暟銆

3. 杈撳嚭鎿嶄綔鏁(output operands)

鍐呰仈姹囩紪鏈夐浂涓垨澶氫釜杈撳嚭鎿嶄綔鏁帮紝鐢ㄦ潵鎸囩ず鍐呰仈姹囩紪鎸囦护淇敼浜咰浠g爜涓殑鍙橀噺銆傚鏋滄湁澶氫釜杈撳嚭鍙傛暟锛屽垯闇€瑕佸姣忎釜杈撳嚭鍙傛暟杩涜鍒嗛殧銆傛瘡涓緭鍑烘搷浣滄暟鐨勬牸寮忎负锛

  1. [[asmSymbolicName]]聽constraint聽(cvariablename)聽

鎴戜滑鍙互涓鸿緭鍑烘搷浣滄暟鎸囧畾涓€涓悕瀛梐smSymbolicName锛屾眹缂栨寚浠や腑鍙互浣跨敤杩欎釜鍚嶅瓧寮曠敤杈撳嚭鎿嶄綔鏁般€

闄や簡浣跨敤鍚嶅瓧寮曠敤鎿嶄綔鏁板锛岃繕鍙互浣跨敤搴忓彿寮曠敤鎿嶄綔鏁般€傛瘮濡傝緭鍑烘搷浣滄暟鏈変袱涓紝閭d箞鍙互鐢%0寮曠敤绗1涓緭鍑烘搷浣滄暟锛%1寮曠敤绗2涓搷浣滄暟锛屼互姝ょ被鎺ㄣ€

杈撳嚭鎿嶄綔鏁扮殑绾︽潫閮ㄥ垎蹇呴』浠モ€=鈥濇垨鑰呪€+鈥濅綔涓哄墠缂€锛屸€=鈥濊〃绀哄彧鍐欙紝鈥+鈥濊〃绀鸿鍐欍€傚湪鍓嶇紑涔嬪悗锛屽氨鍙互鏄悇绉嶇害鏉熶簡锛屾瘮濡傗€=a鈥濊〃绀哄厛灏嗙粨鏋滆緭鍑鸿嚦rax/eax瀵勫瓨鍣紝鐒跺悗鍐嶇敱rax/eax瀵勫瓨鍣ㄦ洿鏂扮浉搴旂殑杈撳嚭鍙橀噺銆

cvariablename涓轰唬鐮佷腑鐨凜鍙橀噺鍚嶅瓧锛岄渶瑕佷娇鐢ㄦ嫭鍙锋嫭璧锋潵銆

4. 杈撳叆鎿嶄綔鏁(input operands)

鍐呰仈姹囩紪鍙互鏈夐浂涓垨澶氫釜杈撳叆鎿嶄綔鏁帮紝杈撳叆鎿嶄綔鏁版潵鑷狢浠g爜涓殑鍙橀噺鎴栬€呰〃杈惧紡锛屼綔涓烘眹缂栨寚浠ょ殑杈撳叆锛屾瘡涓緭鍏ユ搷浣滄暟鐨勬牸寮忓涓嬶細

  1. [[asmSymbolicName]]聽constraint聽(cexpression)聽

鍚岃緭鍑烘搷浣滄暟鐩稿悓锛屼篃鍙互涓烘瘡涓緭鍏ユ搷浣滄暟鎸囧畾鍚嶅瓧asmSymbolicName锛屾眹缂栨寚浠や腑鍙互浣跨敤杩欎釜鍚嶅瓧寮曠敤杈撳叆鎿嶄綔鏁般€

闄や簡浣跨敤鍚嶅瓧寮曠敤杈撳叆鎿嶄綔鏁板锛岃繕鍙互浣跨敤搴忓彿寮曠敤杈撳叆鎿嶄綔鏁般€傝緭鍏ユ搷浣滄暟鐨勫簭鍙蜂互鏈€鍚庝竴涓緭鍑烘搷浣滄暟鐨勫簭鍙峰姞1寮€濮嬶紝姣斿杈撳嚭鎿嶄綔鏁版湁涓や釜锛岃緭鍏ユ搷浣滄暟鏈3涓紝閭d箞闇€瑕佷娇鐢%2寮曠敤绗1涓緭鍏ユ搷浣滄暟锛%3寮曠敤绗2涓緭鍏ユ搷浣滄暟锛屼互姝ょ被鎺ㄣ€

闄や簡涓嶅繀浠モ€=鈥濇垨鑰呪€+鈥濆墠缂€寮€澶村锛岃緭鍏ユ搷浣滄暟鐨勫墠缂€涓庤緭鍑烘搷浣滄暟鍩烘湰鐩稿悓銆傞櫎浜嗗瘎瀛樺櫒绾︽潫澶栵紝鍦ㄥ悗闈㈢殑浠g爜涓垜浠繕浼氱湅鍒扳€渋鈥濊繖涓害鏉燂紝琛ㄧず杩欎釜杈撳叆鎿嶄綔鏁版槸涓珛鍗虫暟(immediate integer)銆

cexpression涓轰唬鐮佷腑鐨凜鍙橀噺鎴栬€呰〃杈惧紡锛岄渶瑕佷娇鐢ㄦ嫭鍙锋嫭璧锋潵銆

5. clobber list

鏌愪簺姹囩紪鎸囦护鎵ц鍚庝細鏈変竴浜涘壇浣滅敤锛屽彲鑳戒細闅愭€у湴褰卞搷鏌愪簺瀵勫瓨鍣ㄦ垨鑰呭唴瀛樼殑鍊硷紝濡傛灉琚奖鍝嶇殑瀵勫瓨鍣ㄦ垨鑰呭唴瀛樺苟娌℃湁鍦ㄨ緭鍏ャ€佽緭鍑烘搷浣滄暟涓垪鍑烘潵锛岄偅涔堥渶瑕佸皢杩欎簺瀵勫瓨鍣ㄦ垨鑰呭唴瀛樺垪鍏lobber list銆傞€氳繃杩欑鏂瑰紡锛屽唴鑱旀眹缂栧憡鐭CC锛岄渶瑕丟CC鈥滅収椤锯€濆ソ杩欎簺琚奖鍝嶇殑瀵勫瓨鍣ㄦ垨鑰呭唴瀛橈紝姣斿蹇呰鏃堕渶瑕佸湪鎵ц鍐呰仈姹囩紪鎸囦护鍓嶄繚瀛樺ソ瀵勫瓨鍣紝鑰屽湪鎵ц鍐呰仈姹囩紪鎸囦护鍚庢仮澶嶅瘎瀛樺櫒鐨勫€笺€

鎺ヤ笅鏉ユ垜浠潵鐪嬩竴涓叿浣撶殑渚嬪瓙銆傝繖涓緥瀛愭槸涓€涓姞娉曡繍绠楋紝涓€涓姞鏁版槸val锛屽€间负100锛屽彟澶栦竴涓姞鏁版槸涓€涓珛鍗虫暟400锛岃绠楃粨鏋滀繚瀛樺埌鍙橀噺sum涓細

  1. int聽val聽=聽100,聽sum聽=聽0;聽
  2. 聽asm聽("movl聽%1,聽%%rax;聽\n\t"聽
  3. 聽聽聽聽聽聽聽"movl聽%c[addend],聽%%rbx;聽\n\t"聽
  4. 聽聽聽聽聽聽聽"addl聽%%rbx,聽%%rax;聽\n\t"聽
  5. 聽聽聽聽聽聽聽鈥渕ovl聽%%rax,聽%0;聽\n\t鈥澛
  6. 聽聽聽聽聽聽聽:聽鈥=鈥(sum)聽
  7. 聽聽聽聽聽聽:聽(c)(val),聽[addend]鈥漣鈥(400)聽
  8. 聽聽聽聽聽聽聽:聽鈥渞bx鈥澛

鎴戜滑鍏堟潵鐪嬬3琛岀殑姹囩紪鎸囦护銆傚洜涓哄瓨鍦ㄥ瘎瀛樺櫒寮曠敤鍜岄€氳繃搴忓彿寮曠敤鐨勬搷浣滄暟锛屾墍浠ヤ娇鐢ㄤ袱涓€%鈥濆紩鐢ㄥ瘎瀛樺櫒銆%1寮曠敤鐨勬槸杈撳叆鎿嶄綔鏁皏al锛屽叾涓璫琛ㄧず浣跨敤rcx瀵勫瓨鍣ㄤ繚瀛榲al锛屼篃灏辨槸璇村湪鎵ц杩欐潯姹囩紪鎸囦护鍓嶏紝棣栧厛灏唙al鐨勫€艰祴鍊煎埌rcx瀵勫瓨鍣ㄤ腑锛岀劧鍚庢眹缂栨寚浠ゅ啀灏唕cx瀵勫瓨鍣ㄧ殑鍊艰祴鍊煎埌rax瀵勫瓨鍣ㄤ腑銆

绗4琛岀殑姹囩紪鎸囦护寮曠敤鐨刟ddend鏄2涓緭鍏ユ搷浣滄暟鐨勭鍙峰悕瀛楋紝鍥犱负杩欐槸涓€涓珛鍗虫暟锛屾墍浠ヨ繖涓彉閲忓墠闈娇鐢ㄤ簡c淇グ绗︺€傝繖鏄疓CC鐨勪竴涓娉曪紝琛ㄧず鍚庨潰鏄釜绔嬪嵆鏁般€

绗5鏉℃寚浠ゆ眰rbx瀵勫瓨鍣ㄥ拰rax瀵勫瓨鍣ㄧ殑鍜岋紝骞跺皢缁撴灉淇濆瓨鍒皉ax瀵勫瓨鍣ㄤ腑銆

绗6鏉℃寚浠や腑鐨%0寮曠敤鐨勬槸杈撳嚭鎿嶄綔鏁皊um锛岃繖鏄疌浠g爜涓殑鍙橀噺锛屽洜涓簊um鏄彧鍐欑殑杈撳嚭鎿嶄綔鏁帮紝鎵€浠ヤ娇鐢ㄧ害鏉熲€=鈥濄€傛墍浠ョ6琛岀殑姹囩紪鎸囦护鏄皢璁$畻鐨勭粨鏋滃瓨鍌ㄥ埌鍙橀噺sum涓€

浠庤繖娈典唬鐮佷腑鎴戜滑鐪嬪埌锛屽湪姹囩紪浠g爜涓娇鐢ㄤ簡rbx瀵勫瓨鍣紝鑰宺bx瀵勫瓨鍣ㄦ病鏈夊嚭鐜板湪杈撳嚭銆佽緭鍏ユ搷浣滄暟涓紝鎵€浠ュ唴鑱旀眹缂栭渶瑕佹妸rbx瀵勫瓨鍣ㄥ垪鍏lobber list涓紝瑙佺10琛屼唬鐮侊紝鍛婅瘔GCC姹囩紪鎸囦护姹℃煋浜唕bx瀵勫瓨鍣紝濡傛灉鏈夊繀瑕侊紝鍒欓渶瑕佸湪鎵ц鍐呰仈姹囩紪鎸囦护鍓嶈嚜琛屼繚瀛榬bx瀵勫瓨鍣紝鎵ц鍐呰仈姹囩紪鎸囦护鍚庡啀鑷鎭㈠rbx瀵勫瓨鍣ㄣ€

浜屻€佽櫄鎷熸満鍒囧叆鍜岄€€鍑哄強鐩稿叧鐨勪笂涓嬫枃淇濆瓨

浜嗚В浜嗗唴鑱旀眹缂栫殑璇硶鍚庯紝鎺ヤ笅鏉ユ垜浠紑濮嬫帰璁ㄨ櫄鎷熸満鍒囧叆鍜岄€€鍑洪儴鍒嗙殑鍐呰仈姹囩紪鎸囦护锛

  1. static聽void聽vmx_vcpu_run(struct聽kvm_vcpu聽*vcpu)聽
  2. 聽聽聽聽struct聽vcpu_vmx聽*vmx聽=聽to_vmx(vcpu);聽
  3. 聽聽聽聽聽聽聽聽/*聽Store聽host聽registers聽*/聽
  4. 聽聽聽聽聽聽聽聽"push聽%%"R"dx;聽push聽%%"R"bp;"聽
  5. 聽聽聽聽聽聽聽聽"push聽%%"R"cx聽\n\t"聽
  6. 聽聽聽聽聽聽聽聽"cmp聽%%"R"sp,聽%c[host_rsp](%0)聽\n\t"聽
  7. 聽聽聽聽聽聽聽聽"je聽1f聽\n\t"聽
  8. 聽聽聽聽聽聽聽聽"mov聽%%"R"sp,聽%c[host_rsp](%0)聽\n\t"聽
  9. 聽聽聽聽聽聽聽聽__ex(ASM_VMX_VMWRITE_RSP_RDX)聽"\n\t"聽
  10. 聽聽聽聽聽聽聽聽"1:聽\n\t"聽
  11. 聽聽聽聽聽聽聽聽/*聽Reload聽cr2聽if聽changed聽*/聽
  12. 聽聽聽聽聽聽聽聽"mov聽%c[cr2](%0),聽%%"R"ax聽\n\t"聽
  13. 聽聽聽聽聽聽聽聽"mov聽%%cr2,聽%%"R"dx聽\n\t"聽
  14. 聽聽聽聽聽聽聽聽"cmp聽%%"R"ax,聽%%"R"dx聽\n\t"聽
  15. 聽聽聽聽聽聽聽聽"je聽2f聽\n\t"聽
  16. 聽聽聽聽聽聽聽聽"mov聽%%"R"ax,聽%%cr2聽\n\t"聽
  17. 聽聽聽聽聽聽聽聽"2:聽\n\t"聽
  18. 聽聽聽聽聽聽聽聽/*聽Check聽if聽vmlaunch聽of聽vmresume聽is聽needed聽*/聽
  19. 聽聽聽聽聽聽聽聽"cmpl聽$0,聽%c[launched](%0)聽\n\t"聽
  20. 聽聽聽聽聽聽聽聽/*聽Load聽guest聽registers.聽聽Don't聽clobber聽flags.聽*/聽
  21. 聽聽聽聽聽聽聽聽"mov聽%c[rax](%0),聽%%"R"ax聽\n\t"聽
  22. 聽聽聽聽聽聽聽聽"mov聽%c[rbx](%0),聽%%"R"bx聽\n\t"聽
  23. 聽聽聽聽聽聽聽聽"mov聽%c[rcx](%0),聽%%"R"cx聽\n\t"聽/*聽kills聽%0聽(ecx)聽*/聽
  24. 聽聽聽聽聽聽聽聽/*聽Enter聽guest聽mode聽*/聽
  25. 聽聽聽聽聽聽聽聽"jne聽.Llaunched聽\n\t"聽
  26. 聽聽聽聽聽聽聽聽__ex(ASM_VMX_VMLAUNCH)聽"\n\t"聽
  27. 聽聽聽聽聽聽聽聽"jmp聽.Lkvm_vmx_return聽\n\t"聽
  28. 聽聽聽聽聽聽聽聽".Llaunched:聽"聽__ex(ASM_VMX_VMRESUME)聽"\n\t"聽
  29. 聽聽聽聽聽聽聽聽".Lkvm_vmx_return:聽"聽
  30. 聽聽聽聽聽聽聽聽/*聽Save聽guest聽registers,聽load聽host聽registers,聽keep聽鈥*/聽
  31. 聽聽聽聽聽聽聽聽"xchg聽%0,聽聽聽聽聽(%%"R"sp)聽\n\t"聽
  32. 聽聽聽聽聽聽聽聽"mov聽%%"R"ax,聽%c[rax](%0)聽\n\t"聽
  33. 聽聽聽聽聽聽聽聽"mov聽%%"R"bx,聽%c[rbx](%0)聽\n\t"聽
  34. 聽聽聽聽聽聽聽聽"pop"Q"聽%c[rcx](%0)聽\n\t"聽
  35. 聽聽聽聽聽聽聽聽"mov聽%%"R"dx,聽%c[rdx](%0)聽\n\t"聽
  36. 聽聽聽聽聽聽聽聽"mov聽%%cr2,聽%%"R"ax聽聽聽\n\t"聽
  37. 聽聽聽聽聽聽聽聽"mov聽%%"R"ax,聽%c[cr2](%0)聽\n\t"聽
  38. 聽聽聽聽聽聽聽聽"pop聽聽%%"R"bp;聽pop聽聽%%"R"dx聽\n\t"聽
  39. 聽聽聽聽聽聽聽聽"setbe聽%c[fail](%0)聽\n\t"聽
  40. 聽聽聽聽聽聽聽聽聽聽:聽:聽"c"(vmx),聽"d"((unsigned聽long)HOST_RSP),聽
  41. 聽聽聽聽聽聽聽聽[launched]"i"(offsetof(struct聽vcpu_vmx,聽launched)),聽
  42. 聽聽聽聽聽聽聽聽[fail]"i"(offsetof(struct聽vcpu_vmx,聽fail)),聽
  43. 聽聽聽聽聽聽聽聽[host_rsp]"i"(offsetof(struct聽vcpu_vmx,聽host_rsp)),聽
  44. 聽聽聽聽聽聽聽聽[rax]"i"(offsetof(struct聽vcpu_vmx,聽聽
  45. 聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽vcpu.arch.regs[VCPU_REGS_RAX])),聽
  46. 聽聽聽聽聽聽聽聽[rbx]"i"(offsetof(struct聽vcpu_vmx,聽聽
  47. 聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽vcpu.arch.regs[VCPU_REGS_RBX])),聽
  48. 聽聽聽聽聽聽聽聽[cr2]"i"(offsetof(struct聽vcpu_vmx,聽vcpu.arch.cr2))聽
  49. 聽聽聽聽聽聽聽聽聽聽:聽"cc",聽"memory"聽
  50. 聽聽聽聽聽聽聽聽,聽R"ax",聽R"bx",聽R"di",聽R"si"聽
  51. #ifdef聽CONFIG_X86_64聽
  52. 聽聽聽聽聽聽聽聽,聽"r8",聽"r9",聽"r10",聽"r11",聽"r12",聽"r13",聽"r14",聽"r15"聽
  53. #endif聽

CPU浠嶩ost妯″紡鍒囨崲鍒癎uest妯″紡鏃讹紝骞朵笉浼氳嚜鍔ㄤ繚瀛橀儴鍒嗗瘎瀛樺櫒锛屽吀鍨嬬殑姣斿閫氱敤瀵勫瓨鍣ㄣ€傚洜姝わ紝绗7琛屼唬鐮並VM灏嗗涓绘満鐨勯€氱敤瀵勫瓨鍣ㄤ繚瀛樺埌鏍堜腑銆傚綋鍙戠敓VM閫€鍑烘椂锛孠VM浠庢爤涓皢杩欎簺淇濆瓨鐨勫涓绘満鐨勯€氱敤瀵勫瓨鍣ㄦ仮澶嶅埌CPU鐨勭墿鐞嗗瘎瀛樺櫒涓€傝繖閲岋紝瀹廟鍦64浣嶄笅鍊间负r锛32浣嶄笅涓篹锛屾墍浠ラ€氳繃瀹氫箟杩欎釜瀹忥紝浠庣紪鐮佸眰闈㈡洿绠€娲佸湴鏀寔64浣嶅拰32浣嶃€備絾鏄鑰呭彲鑳芥湁鐤戦棶锛屼负浠€涔堣繖閲屽彧淇濆瓨杩欎袱涓瘎瀛樺櫒?浜嬪疄涓婏紝KVM鏈€鍒濈殑瀹炵幇鏄皢鎵€鏈夌殑閫氱敤瀵勫瓨鍣ㄩ兘鍘嬪叆鏍堜腑浜嗐€傚悗鏉ヤ娇鐢ㄤ簡GCC鍐呰仈姹囩紪鐨刢lobber list鐗规€э紝灏嗘墍鏈夊彲鑳戒細琚唴鑱旀眹缂栦唬鐮佸奖鍝嶇殑瀵勫瓨鍣ㄩ兘鍐欏叆clobber list涓紝GCC鑷繁璐熻矗淇濆瓨鍜屾仮澶嶆搷浣滆繖浜涘瘎瀛樺櫒鐨勫唴瀹广€備唬鐮佺57锝61琛屽氨鏄痗lobber list銆傝繖閲岄潰鏈変袱涓壒娈婄殑瀵勫瓨鍣細rdx/edx鍜宺bp/ebp锛屽叾涓璻dx/edx瀵勫瓨鍣ㄦ槸GCC淇濈暀鐨剅egparm鐗规€э紝涓嶈兘鏀惧湪clobber list涓紝鍙﹀涓€涓猺bp/ebp瀵勫瓨鍣ㄤ篃涓嶇敓鏁堬紝鎵€浠VM鎵嬪姩淇濆瓨浜嗚繖涓や釜瀵勫瓨鍣ㄣ€

姝ゅ锛孠VM鍦ㄧ8琛屼唬鐮佷繚瀛樹簡rcx/ecx瀵勫瓨鍣紝杩欓噷鐨剅cx/ecx瀵勫瓨鍣ㄦ湁鐫€鐗规畩鐨勪娇鍛姐€傚綋浠嶨uest閫€鍑哄埌Host鏃讹紝CPU涓嶄細鑷姩淇濆瓨Guest鐨勪竴浜涘瘎瀛樺櫒锛屽吀鍨嬬殑濡傞€氱敤瀵勫瓨鍣紝KVM鎵嬪姩灏嗗叾淇濆瓨鍒颁簡缁撴瀯浣搗cpu_vmx涓殑瀛愮粨鏋勪綋涓€傚洜姝わ紝鍦℅uest閫€鍑虹殑閭d竴鍒伙紝棣栧厛蹇呴』瑕佽幏鍙栫粨鏋勪綋vcpu_vmx鐨勫疄渚嬶紝涔熷氨鏄3琛屼唬鐮佷腑鐨勫彉閲弙mx锛屽皢CPU瀵勫瓨鍣ㄤ腑鐨勭姸鎬佷繚瀛樺埌杩欎釜vmx涓紝涔熷氨鏄锛屽湪淇濆瓨瀹孏uest鐨勭姸鎬佸悗锛屾墠鑳借繘琛屽叾浠栨搷浣滐紝閬垮厤鐮村潖Guest鐨勭姸鎬併€備簬鏄紝姣忔浠嶩ost鍒囧叆Guest鍓嶇殑鏈€鍚庝竴鍒伙紝KVM灏唙mx鐨勫湴鍧€鍘嬪叆鏍堥《锛岀劧鍚庡湪Guest閫€鍑烘椂浠庢爤椤剁涓€鏃堕棿鍙栧嚭vmx銆傞偅涔堝浣曞皢vmx鍘嬪叆鏍堥《鍛?鍙傝绗47琛屼唬鐮侊紝杩欓噷浣跨敤浜咷CC鍐呰仈姹囩紪鐨刬nput绾︽潫锛屽嵆鍦ㄦ墽琛屾眹缂栦唬鐮佸墠锛屽憡璇夌紪璇戝櫒灏嗗彉閲弙mx鍔犺浇鍒皉cx/ecx瀵勫瓨鍣紝閭d箞鍦ㄦ墽琛岀8琛屼唬鐮侊紝鍗冲皢rcx/ecx瀵勫瓨鍣ㄧ殑鍐呭鍘嬪叆鏍堟椂锛屽疄闄呬笂鏄皢鍙橀噺vmx鍘嬪叆鏍堥《浜嗐€

鍦℅uest閫€鍑烘椂锛孋PU浼氳嚜鍔ㄥ皢VMCS涓璈ost鐨剅sp/esp瀵勫瓨鍣ㄦ仮澶嶅埌鐗╃悊CPU鐨剅sp/esp瀵勫瓨鍣ㄤ腑锛屾墍浠ユ鏃跺彲浠ヨ闂甐CPU绾跨▼鍦℉ost鎬佷笅鐨勬爤銆傚湪Guest閫€鍑哄悗鐨勭1琛屼唬鐮侊紝鍗崇36琛屼唬鐮侊紝璋冪敤xchg鎸囦护灏嗘爤椤剁殑鍊煎拰搴忓彿%0鎸囦唬鐨勫彉閲忚繘琛屼氦鎹紝鏍规嵁绗47琛屼唬鐮佸彲瑙侊紝%0鎸囦唬鍙橀噺vmx锛屽搴旂殑瀵勫瓨鍣ㄦ槸rcx/ecx锛屼篃灏辨槸璇达紝杩欒浠g爜灏嗗垏鍏uest涔嬪墠淇濆瓨鍒版爤椤剁殑鍙橀噺vmx鐨勫湴鍧€鎭㈠鍒颁簡rcx/ecx瀵勫瓨鍣ㄤ腑锛%0寮曠敤鐨勪篃鏄繖涓湴鍧€锛岄偅涔堝氨鍙互浣跨敤%0寮曠敤杩欎釜鍦板潃淇濆瓨Guest鐨勫瘎瀛樺櫒浜嗐€

璇昏€呭彲鑳戒細闂紝Guest娌℃湁浣跨敤鍙橀噺vmx锛屼篃娌℃湁鐮村潖瀹冿紝閭d箞Host鏄惁鍙互鐩存帴浣跨敤杩欎釜鍙橀噺鍛?浜嬪疄涓婏紝浠庡簳灞傛潵鐪嬶紝瀵逛簬瀛樻斁鍦ㄦ爤涓殑鍙橀噺vmx锛孏CC閫氬父浣跨敤鏍堝抚鍩哄潃鎸囬拡rbp/ebp鎴栧瘎瀛樺櫒寮曠敤銆備絾鏄紝鍦℅uest閫€鍑虹殑绗竴鏃堕棿锛岄櫎浜嗕笓鐢ㄥ瘎瀛樺櫒锛岃繖浜涢€氱敤瀵勫瓨鍣ㄤ腑淇濆瓨鐨勯兘鏄疓uest鐨勭姸鎬侊紝鎵€浠ヨ嚜鐒朵篃鏃犳硶閫氳繃rbp/ebp鍔犲亸绉荤殑鏂瑰紡鏉ュ紩鐢╲mx銆傚洜涓洪€€鍑篏uest鏃禖PU鑷姩鎭㈠Host鐨勬爤椤舵寚閽堬紝鎵€浠VM宸у鍦板埄鐢ㄤ簡杩欎竴鐐癸紝鍊熷姪鏍堥《淇濆瓨vmx銆傜劧鍚庯紝閫氳繃浜ゆ崲鏍堥《鐨勫彉閲忓拰rcx/ecx瀵勫瓨鍣紝瀹炵幇浜嗗湪rcx/ecx瀵勫瓨鍣ㄤ腑寮曠敤vmx鐨勫悓鏃讹紝鍙堝皢Guest鐨剅cx/ecx瀵勫瓨鍣ㄧ殑鐘舵€佷繚瀛樺埌浜嗘爤涓€

鑾峰彇鍒颁簡淇濆瓨Guest鐘舵€佺殑鍦板潃锛屾帴涓嬫潵淇濆瓨Guest鐨勭姸鎬侊紝瑙佷唬鐮佺37锝43琛屻€

閫€鍑篏uest鍚庣殑绗1琛屼唬鐮(鍗崇36琛)灏咷uest鐨剅cx/ecx瀵勫瓨鍣ㄧ殑鍊间繚瀛樺埌浜嗘爤涓紝鎵€浠ョ39琛屼唬鐮佷粠鏍堥《寮瑰嚭Guest鐨剅cx/ecx鐨勫€煎埌淇濆瓨Guest鐘舵€佺殑鍐呭瓨涓璻cx/ecx鐩稿簲鐨勪綅缃€

骞朵笉鏄瘡娆uest閫€鍑哄埌鍒囧叆锛孒ost鐨勬爤閮戒細鍙戠敓鍙樺寲锛屽洜姝ost鐨剅sp/esp涔熸棤椤绘瘡娆¢兘鏇存柊銆傚彧鏈塺sp/esp鍙樺寲浜嗭紝鎵嶉渶瑕佹洿鏂癡MCS涓璈ost鐨剅sp/esp瀛楁锛屼互鍑忓皯涓嶅繀瑕佺殑鍐橵MCS鎿嶄綔銆傛墍浠VM鍦╒CPU涓褰曚簡host_rsp鐨勫€硷紝鐢ㄦ潵姣旇緝rsp/esp鏄惁鍙戠敓浜嗗彉鍖栵紝瑙佷唬鐮佺9锝13琛屻€

灏咹ost鐨剅sp/esp鍐欏叆VMCS涓殑鎸囦护鏄細

  1. ASM_VMX_VMWRITE_RSP_RDX聽

鍐橵MCS鐨勬寚浠ゆ湁涓や釜鍙傛暟锛屼竴涓寚鏄庡啓VMCS涓摢涓瓧娈碉紝鍙﹀涓€涓槸鍐欏叆鐨勫€笺€俽sp/esp寰堝ソ鐞嗚В锛屾寚鏄庡啓鍏ョ殑鍊煎湪rsp/esp瀵勫瓨鍣ㄩ噷銆傞偅涔坮dx鏄粈涔堝憿?瑙佺47琛屼唬鐮佸瀵勫瓨鍣╮dx/edx鐨勭害鏉燂細

  1. "d"((unsigned聽long)HOST_RSP)聽

缁撳悎瀹廐OST_RSP鐨勫畾涔夛細

  1. /*聽VMCS聽Encodings聽*/聽
  2. enum聽vmcs_field聽{聽
  3. 聽聽聽聽HOST_RSP聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽=聽0x00006c14,聽

鍙锛孉SM_VMX_VMWRITE_RSP_RDX灏辨槸灏唕sp/esp鐨勫€煎啓鍏MCS涓璈ost鐨剅sp瀛楁銆

VMX娌℃湁瀹氫箟CPU鑷姩淇濆瓨cr2瀵勫瓨鍣紝浣嗘槸浜嬪疄涓婏紝Host鍙兘鏇存敼cr2鐨勫€硷紝浠ヤ笅闈㈣繖娈典唬鐮佷负渚嬶細

  1. commit聽1c696d0e1b7c10e1e8b34cb6c797329e3c33f262聽
  2. KVM:聽VMX:聽Simplify聽saving聽guest聽rcx聽in聽vmx_vcpu_run聽
  3. linux.git/arch/x86/kvm/x86.c聽
  4. void聽kvm_inject_page_fault(struct聽kvm_vcpu聽*vcpu,聽鈥)聽
  5. 聽聽聽聽++vcpu->stat.pf_guest;聽
  6. 聽聽聽聽vcpu->arch.cr2聽=聽fault->address;聽
  7. 聽聽聽聽kvm_queue_exception_e(vcpu,聽PF_VECTOR,聽fault->error_code);聽

鎵€浠ワ紝鍦ㄥ垏鍏uest鍓嶏紝KVM妫€娴嬬墿鐞咰PU鐨刢r2瀵勫瓨鍣ㄤ笌VCPU涓繚瀛樼殑Guest鐨刢r2瀵勫瓨鍣ㄦ槸鍚︾浉鍚岋紝濡傛灉涓嶅悓锛屽垯闇€瑕佷娇鐢℅uest鐨刢r2瀵勫瓨鍣ㄦ洿鏂扮墿鐞咰PU鐨刢r2瀵勫瓨鍣紝瑙佺14锝20琛屼唬鐮併€備絾鏄粷澶ф暟鎯呭喌涓嬶紝浠嶨uest閫€鍑哄埌涓嬩竴娆″垏鍏uest锛宑r2瀵勫瓨鍣ㄧ殑鍊间笉浼氬彂鐢熷彉鍖栵紝鍙︿竴鏂归潰锛屽姞杞絚r2瀵勫瓨鍣ㄧ殑寮€閿€寰堝ぇ锛屾墍浠ュ彧鏈夊湪cr2瀵勫瓨鍣ㄥ彂鐢熷彉鍖栨椂鎵嶉渶瑕侀噸鏂板姞杞絚r2瀵勫瓨鍣ㄣ€

鏈変簺Guest鐨勯€€鍑烘槸鐢遍〉闈㈠紓甯稿紩璧风殑锛屾瘮濡傞€氳繃MMIO鏂瑰紡璁块棶澶栬鐨処/O锛岃€岄〉闈㈠紓甯哥殑鍦板潃浼氳褰曞湪cr2瀵勫瓨鍣ㄤ腑锛屽洜姝ゅ湪Guest閫€鍑烘椂锛孠VM闇€瑕佷繚瀛楪uest鐨刢r2锛岃浠g爜绗42锝43琛屻€傜敱浜庢寚浠ゆ牸寮忕殑闄愬埗锛宮ov鎸囦护涓嶆敮鎸佹帶鍒跺瘎瀛樺櫒鍒板唴瀛樺湴鍧€鐨勫鍒讹紝鍥犳闇€瑕侀€氳繃rax/eax瀵勫瓨鍣ㄤ腑杞竴涓嬨€

鍦ㄥ垏鍏uest鍓嶏紝闄や簡鍔犺浇cr2瀵勫瓨鍣ㄥ锛岃繕闇€瑕佸姞杞介偅浜涚墿鐞咰PU涓嶄細鑷姩鍔犺浇鐨勯€氱敤瀵勫瓨鍣紝瑙佷唬鐮佺24锝27琛屻€

鑰冭檻鍒皒chg鏄釜鍘熷瓙鎿嶄綔锛屼細閿佷綇鍦板潃鎬荤嚎锛屽洜姝や负浜嗘彁楂樻晥鐜囷紝鍚庢潵KVM鎽掑純浜嗚繖鏉℃寚浠わ紝璁捐浜嗕竴绉嶆柊鐨勬柟妗堛€侹VM鍦╒CPU鐨勬爤涓负Guest鐨剅cx/ecx瀵勫瓨鍣ㄥ垎閰嶄簡涓€涓綅缃€傝繖鏍凤紝褰揋uest閫€鍑烘椂锛屽湪浣跨敤rcx/ecx瀵勫瓨鍣ㄥ紩鐢ㄥ彉閲弙mx鍓嶏紝鍙互灏咷uest鐨剅cx/ecx瀵勫瓨鍣ㄤ复鏃朵繚瀛樺埌VCPU鐨勬爤涓负鍏堕鐣欑殑浣嶇疆锛

  1. commit聽40712faeb84dacfcb3925a88231daa08b3624d34聽
  2. KVM:聽VMX:聽Avoid聽atomic聽operation聽in聽vmx_vcpu_run聽
  3. linux.git/arch/x86/kvm/vmx.c聽
  4. 聽static聽void聽vmx_vcpu_run(struct聽kvm_vcpu聽*vcpu)聽
  5. 聽聽聽聽聽聽聽聽聽/*聽Store聽host聽registers聽*/聽
  6. 聽聽聽聽聽聽聽聽聽"push聽%%"R"dx;聽push聽%%"R"bp;"聽
  7. 聽聽聽聽聽聽聽聽聽"push聽%%"R"cx聽\n\t"聽/*聽placeholder聽for聽guest聽rcx聽*/聽
  8. 聽聽聽聽聽聽聽聽聽"push聽%%"R"cx聽\n\t"聽
  9. 聽聽聽聽聽聽聽聽聽".Lkvm_vmx_return:聽"聽
  10. 聽聽聽聽聽聽聽聽聽/*聽Save聽guest聽registers,聽load聽host聽registers,聽鈥*/聽
  11. 聽聽聽聽聽聽聽聽聽"mov聽%0,聽%c[wordsize](%%"R"sp)聽\n\t"聽
  12. 聽聽聽聽聽聽聽聽聽"pop聽%0聽\n\t"聽
  13. 聽聽聽聽聽聽聽聽聽"mov聽%%"R"ax,聽%c[rax](%0)聽\n\t"聽
  14. 聽聽聽聽聽聽聽聽聽"mov聽%%"R"bx,聽%c[rbx](%0)聽\n\t"聽
  15. 聽聽聽聽聽聽聽聽聽"pop"Q"聽%c[rcx](%0)聽\n\t"聽
  16. 聽聽聽聽聽聽聽聽聽[wordsize]"i"(sizeof(ulong))聽

绗7琛屼唬鐮佸氨鏄疜VM涓篏uest鐨剅cx/ecx瀵勫瓨鍣ㄥ湪鏍堜笂棰勭暀鐨勭┖闂达紝绗8琛屼唬鐮佹槸灏嗗彉閲弙mx鍘嬪叆鏍堜腑銆

鍦℅uest閫€鍑虹殑閭d竴鍒伙紝CPU鐨剅cx/ecx瀵勫瓨鍣ㄤ腑瀛樺偍鐨勬槸Guest鐨勭姸鎬侊紝鎵€浠ヤ娇鐢╮cx/ecx瀵勫瓨鍣ㄥ墠锛岄渶瑕佸皢Guest鐨勭姸鎬佷繚瀛樿捣鏉ャ€備繚瀛樼殑浣嶇疆灏辨槸杩涘叆Guest鍓嶏紝KVM涓哄叾鍦ㄦ爤涓婇鐣欑殑浣嶇疆锛屽嵆鏍堥《鐨勪笅涓€涓綅缃紝瑙佺12琛屼唬鐮侊紝鍗虫爤椤跺姞涓婁竴涓瓧(word)鐨勫亸绉汇€

淇濆瓨濂紾uest鐨勫€煎悗锛宺cx/ecx瀵勫瓨鍣ㄥ氨鍙互浣跨敤浜嗭紝绗13琛屼唬鐮佸皢鏍堥《鐨勫€煎嵆vmx寮瑰嚭鍒皉cx/ecx瀵勫瓨鍣ㄤ腑銆傚脊鍑烘爤椤剁殑vmx鍚庯紝涓嬮潰灏辨槸Guest鐨剅cx/ecx瀵勫瓨鍣ㄤ簡锛屾墍浠ョ16琛屼唬鐮佸皢Guest鐨剅cx/ecx瀵勫瓨鍣ㄤ繚瀛樺埌缁撴瀯浣揤CPU涓殑鐩稿叧瀵勫瓨鍣ㄦ暟缁勪腑銆

銆愯矗浠荤紪杈戯細璧靛畞瀹 TEL锛氾紙010锛68476606銆
鐐硅禐 0

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK