คำแนะนำ x86 ต้องการการเข้ารหัสของตัวเองรวมถึงข้อโต้แย้งทั้งหมดของพวกเขาที่จะปรากฏในหน่วยความจำในเวลาเดียวกันหรือไม่?


64

ฉันพยายามที่จะคิดออกว่าเป็นไปได้ในการเรียกใช้ Linux VM ซึ่ง RAM ได้รับการสนับสนุนโดยเพจฟิสิคัลเดียวหรือไม่

หากต้องการจำลองสิ่งนี้ฉันได้แก้ไขตัวจัดการข้อผิดพลาดหน้าซ้อนใน KVM เพื่อลบบิตปัจจุบันออกจากรายการตารางหน้าที่ซ้อนกัน (NPT) ทั้งหมดยกเว้นรายการที่สอดคล้องกับข้อบกพร่องของเพจที่ประมวลผลในปัจจุบัน

ในขณะที่พยายามเริ่มต้นแขกลินุกซ์ฉันสังเกตว่าคำแนะนำการประกอบที่ใช้ตัวถูกดำเนินการหน่วยความจำเช่น

add [rbp+0x820DDA], ebp

นำไปสู่การวนรอบข้อบกพร่องของหน้าจนกว่าฉันจะคืนค่าบิตปัจจุบันสำหรับหน้าที่มีคำสั่งเช่นเดียวกับหน้าอ้างอิงในตัวถูกดำเนินการ (ในตัวอย่างนี้ [rbp+0x820DDA] )

ฉันสงสัยว่าทำไมในกรณีนี้ ซีพียูไม่ควรเข้าถึงหน้าหน่วยความจำตามลำดับหรือไม่เช่นอ่านคำสั่งก่อนจากนั้นจึงเข้าถึงตัวถูกดำเนินการหน่วยความจำ หรือ x86 ต้องการหน้าคำสั่งเช่นเดียวกับหน้าตัวถูกดำเนินการทั้งหมดในเวลาเดียวกันหรือไม่?

ฉันกำลังทดสอบกับ AMD Zen 1


2
ทำไมคุณต้องการทำเช่นนี้?
SS Anne

11
เพิ่งหมดความสนใจด้านเทคนิค :)
savvybug

14
การ upvoting สำหรับแนวคิดโครงการเฮฮา
ท่อ

10
นี่เป็นเรื่องบ้าในระดับ "บูต Linux บนอีมูเลเตอร์ 486 ที่รันใน JavaScript ในเบราว์เซอร์" ฉันรักมัน.
chrylis -on strike-

3
เห็นได้ชัดว่าฉันเอาคำถามนี้ไปสู่ข้อสรุปเชิงตรรกะแบบเดียวกับที่คุณคิดอยู่เกี่ยวกับชุดการทำงานขั้นต่ำสำหรับความคืบหน้าการรับประกัน ฉันได้ตอบไปแล้วก่อนที่คุณจะเพิ่มย่อหน้าใหม่ให้กับคำถาม : PI ได้เพิ่มลิงก์และรายละเอียดเพิ่มเติมในบางจุด (เช่นหน้าผู้ช่วยให้สามารถแคชรายการหน้าไดเรกทอรีแขกบางส่วนภายใน) เนื่องจากคำถามนี้ได้รับความสนใจมากกว่าที่ฉันคาดหวังด้วยเหตุใดจึงทำให้ HNQ
Peter Cordes

คำตอบ:


56

ใช่พวกเขาต้องการรหัสเครื่องและตัวถูกดำเนินการหน่วยความจำทั้งหมด

ซีพียูไม่ควรเข้าถึงหน้าหน่วยความจำตามลำดับหรือไม่เช่นอ่านคำสั่งก่อนจากนั้นจึงเข้าถึงตัวถูกดำเนินการหน่วยความจำ

ใช่นั่นคือเหตุผลที่เกิดขึ้น แต่ข้อผิดพลาดหน้าขัดจังหวะที่กระบวนการ 2 ขั้นตอนและยกเลิกความคืบหน้าใด ๆ ซีพียูไม่มีวิธีใดที่จะจำได้ว่าคำสั่งนั้นตรงไหนเมื่อเกิดข้อผิดพลาดของหน้า

เมื่อตัวจัดการ page-fault ส่งคืนหลังจากจัดการ page fault ที่ถูกต้อง RIP = ที่อยู่ของคำสั่ง faulting ดังนั้น CPU จะพยายามดำเนินการอีกครั้ง จากรอยขีดข่วน

มันจะถูกกฎหมายสำหรับระบบปฏิบัติการที่จะแก้ไขรหัสเครื่องของคำแนะนำการผิดพลาดและคาดว่ามันจะดำเนินการคำสั่งที่แตกต่างกันหลังจากiretจากตัวจัดการข้อบกพร่องหน้า (หรือข้อยกเว้นอื่น ๆ หรือตัวจัดการขัดจังหวะ) ดังนั้น AFAIK จำเป็นต้องใช้สถาปัตยกรรมในการที่ CPU ทำซ้ำการดึงรหัสจาก CS: RIP ในกรณีที่คุณกำลังพูดถึง (สมมติว่ามันจะกลับสู่ความผิดพลาด CS: RIP แทนการกำหนดเวลากระบวนการอื่นในขณะที่รอดิสก์ในความผิดพลาดของหน้ากระดาษหรือส่ง SIGSEGV ไปยังตัวจัดการสัญญาณบนความผิดพลาดของหน้าไม่ถูกต้อง)

อาจจำเป็นต้องมีสถาปัตยกรรมสำหรับการเข้า / ออกของไฮเปอร์ไวเซอร์ และถึงแม้ว่ามันจะไม่ถูกห้ามอย่างชัดเจนบนกระดาษก็ไม่ใช่วิธีการทำงานของซีพียู

@torek ความคิดเห็นที่ตัวประมวลผลไมโครโปรเซสเซอร์ (CISC) บางส่วนถอดรหัสคำสั่งและถ่ายโอนข้อมูลสถานะ microregister ในความผิดพลาดของหน้าแต่ x86 ไม่เป็นเช่นนั้น


คำแนะนำบางอย่างสามารถขัดจังหวะและสามารถทำให้บางส่วนความคืบหน้าเช่นrep movs(memcpy ในกระป๋อง) และคำแนะนำสตริงอื่น ๆ หรือรวบรวมร้านค้าโหลด / กระจาย แต่กลไกเดียวคือการอัพเดตรีจิสเตอร์สถาปัตยกรรมเช่น RCX / RSI / RDI สำหรับ string ops หรือปลายทางและมาสก์รีจิสเตอร์สำหรับการรวบรวม (เช่นคู่มือสำหรับAVX2vpgatherdd ) ไม่รักษา opcode / ถอดรหัสผลลัพธ์ในการลงทะเบียนภายในบางอย่างที่ซ่อนอยู่และเริ่มใหม่หลังจาก iret จากตัวจัดการข้อบกพร่องของหน้า เหล่านี้คือคำแนะนำที่เข้าถึงข้อมูลแยกกันหลายแห่ง

นอกจากนี้โปรดทราบว่า x86 (เหมือน ISAs ส่วนใหญ่) รับประกันได้ว่าคำแนะนำนั้นเป็นอะตอมมิก WRT การขัดจังหวะ / ข้อยกเว้น: พวกมันเกิดขึ้นอย่างเต็มที่หรือไม่เกิดขึ้นเลยก่อนที่จะถูกขัดจังหวะ ขัดขวางการเรียนการสอนการชุมนุมขณะที่มันเป็นปฏิบัติการ ตัวอย่างเช่นadd [mem], regจะต้องยกเลิกการโหลดถ้าส่วนร้านผิดพลาดแม้ไม่มีlockคำนำหน้า


จำนวนเคสที่แย่ที่สุดของเพจพื้นที่ผู้ใช้ของผู้เยี่ยมชมที่มีอยู่เพื่อดำเนินการไปข้างหน้าอาจเป็น 6 (รวมทั้งแผนผังย่อยของตารางเพจเกสต์เคอร์เนลแยกต่างหากสำหรับแต่ละอัน):

  • movsqหรือmovswคำสั่ง 2 ไบต์ขยายขอบเขตหน้าดังนั้นทั้งสองหน้าจึงจำเป็นต้องถอดรหัส
  • ตัวดำเนินการซอร์สของ qword [rsi]ยังเป็นการแบ่งหน้า
  • qword ปลายทางตัวถูกดำเนินการ[rdi]ยังแบ่งหน้า

หากความผิดพลาด 6 หน้าใด ๆ เรากลับไปที่สี่เหลี่ยมจัตุรัส

rep movsdยังเป็นคำสั่ง 2 ไบต์และทำให้ความคืบหน้าในขั้นตอนเดียวของมันจะมีความต้องการเดียวกัน กรณีที่คล้ายกันเช่นpush [mem]หรือpop [mem]สามารถสร้างขึ้นด้วยสแต็กที่ไม่ตรงแนว

หนึ่งในเหตุผล (หรือผลประโยชน์ด้านข้าง) สำหรับ / ของการรวบรวมเก็บ / กระจายร้านค้า "ขัดจังหวะ" (ปรับปรุงหน้ากากเวกเตอร์ด้วยความคืบหน้าของพวกเขา) คือการหลีกเลี่ยงการเพิ่มรอยขั้นต่ำนี้เพื่อดำเนินการคำสั่งเดียว นอกจากนี้เพื่อปรับปรุงประสิทธิภาพของการจัดการข้อบกพร่องหลายอย่างในระหว่างการรวบรวมหรือกระจาย


@Brandon ชี้ให้เห็นในความคิดเห็นว่าแขกจะต้องใช้หน้าตารางในหน่วยความจำและการแยกหน้าพื้นที่ผู้ใช้ยังสามารถแยก 1GiB เพื่อให้ทั้งสองฝ่ายอยู่ในต้นไม้ย่อยที่แตกต่างกันของ PML4 ระดับสูงสุด การเดินหน้า HW จะต้องแตะหน้าโต๊ะหน้าแขกเหล่านี้เพื่อดำเนินการ สถานการณ์ทางพยาธิวิทยานี้ไม่น่าจะเกิดขึ้นโดยบังเอิญ

TLB (และผู้ดำเนินการประกวดหน้า) ได้รับอนุญาตให้แคชข้อมูลบางส่วนของหน้าตารางและไม่จำเป็นต้องเริ่มต้นการเดินหน้าใหม่ตั้งแต่ต้นเว้นแต่ระบบปฏิบัติการทำinvlpgหรือตั้งค่าไดเรกทอรีหน้าระดับบนสุด CR3 ใหม่ สิ่งเหล่านี้ไม่จำเป็นเมื่อเปลี่ยนหน้าจากไม่เป็นปัจจุบัน; x86 บนกระดาษรับประกันได้ว่าไม่จำเป็น (ดังนั้นจึงไม่อนุญาตให้ "การแคชเชิงลบ" ของ PTE ที่ไม่อยู่ในปัจจุบันอย่างน้อยก็มองไม่เห็นด้วยซอฟต์แวร์) ดังนั้น CPU อาจไม่ VMexit แม้ว่าบางหน้าเพจตารางผู้เยี่ยมชมทางกายภาพจะไม่มีอยู่จริง

ตัวนับประสิทธิภาพ PMUสามารถเปิดใช้งานและกำหนดค่าเพื่อให้คำสั่งยังต้องการเหตุการณ์ perf เพื่อเขียนลงในบัฟเฟอร์ PEBSสำหรับคำสั่งนั้น ด้วยมาสก์ของตัวนับที่กำหนดค่าให้นับเฉพาะคำแนะนำพื้นที่ผู้ใช้ไม่ใช่เคอร์เนลอาจเป็นไปได้ว่ามันจะพยายามล้นตัวนับและเก็บตัวอย่างในบัฟเฟอร์ทุกครั้งที่คุณกลับไปที่ userspace ทำให้เกิดความผิดพลาดของหน้า


15
กรณีที่แย่ที่สุดสำหรับคำสั่งเดียวอาจเป็นอะไรบางอย่างเช่น " push dword [foo" (หรือแม้แต่เพียงcall [foo]) กับทุกสิ่งที่ไม่ตรงแนว "ขอบเขตไดเรกทอรีตารางตัวชี้หน้า" (เพิ่มได้สูงสุด 6 หน้า, 6 หน้าตาราง, 6 หน้าไดเรกทอรี 6 หน้า PDPTs หนึ่ง PML4) ด้วยคุณสมบัติ "การสุ่มตัวอย่างจากเหตุการณ์ที่แม่นยำพร้อมด้วยบัฟเฟอร์ PEBS" ของ CPU ที่เปิดใช้งานและกำหนดค่าเพื่อให้pushข้อมูลการตรวจสอบประสิทธิภาพเพิ่มลงในบัฟเฟอร์ PEBS สำหรับหน้าขั้นต่ำที่อนุรักษ์ไว้โดยโฮสต์เพื่อให้แขกสามารถดำเนินการในกรณีทางพยาธิวิทยาฉันต้องการหน้าอย่างน้อย 16 หน้า
เบรนแดน

4
โปรดทราบว่าสิ่งเหล่านี้มักเป็นเรื่องธรรมดาในสถาปัตยกรรม CISC-y ไมโครโปรเซสเซอร์บางตัวถอดรหัสคำสั่งบางส่วนและถ่ายโอนข้อมูลสถานะ microregister ในความผิดพลาดของหน้า แต่คนอื่นไม่ต้องการและ / หรือต้องการตัวถูกดำเนินการที่อยู่สำหรับคำแนะนำ "ลูป -y" (DBRA บน m68k, MOVC3 / MOVC5 บน Vax ฯลฯ ) ในตัวอย่าง REP MOVS ของคุณ
torek

1
@Brendan: มีคนนับกรณีที่เลวร้ายที่สุดในการเรียนการสอน VAX ประมาณ 50 หน้า ฉันลืมรายละเอียด แต่คุณเห็นได้ชัดว่าคุณใช้คำสั่งในขอบเขตหน้าใช้บางอย่างเช่นการค้นหาตารางแปลด้วยตารางซึ่งครอบคลุมขอบเขตหน้าใช้ (rX) [rY] กับทางอ้อมที่ขอบเขตหน้าและ เป็นต้น คำแนะนำผมใช้เวลาถึง 6 ตัวถูกดำเนินการ (โหลดลงใน r0-r5) และทั้งหกอาจเป็นทางอ้อมสองเท่าฉันคิดว่า
torek

3
ระบบปฏิบัติการสามารถเปลี่ยนคำสั่ง แต่ก็สามารถเปลี่ยนEIPได้ ดังนั้นจึงมีคำถามติดตามผลเชิงตรรกะ จำนวนหน้าขั้นต่ำที่ต้องการคืออะไรหากเป็นรูปแบบของชุดคำสั่งอัจฉริยะ เช่นคัดลอกค่าที่ไม่ได้จัดแนวไปยังบัฟเฟอร์บัฟเฟอร์ที่จัดแนว, เลียนแบบคำสั่งและ IRET ไปยังคำสั่งถัดไป
MSalters

1
หน้าที่มีiretคำสั่งของระบบปฏิบัติการนั้นจะต้องอยู่ในหน่วยความจำด้วย นี่คือคำสั่งแบบหนึ่งไบต์ดังนั้นจึงมีหนึ่งหน้าพิเศษ ที่อยู่ขัดจังหวะตัวจัดการข้อผิดพลาดของหน้าต้องอยู่ในหน่วยความจำด้วย แต่นั่นอาจเป็นหน้าเดียวกันกับด้านบน
เฮม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.