ย้อนกลับไปในเดือนกรกฎาคมของ Intel Peter Zijlstra เสนอ”Call Depth Tracking”เป็นแนวทางในการลดปัญหาสำหรับการจัดการ Retbleed และหลีกเลี่ยง”การแสดงสยองขวัญด้านประสิทธิภาพ”ของการใช้ Indirect Branch Retbleed Speculation (IBRS) วันนี้เป็นเวอร์ชันล่าสุดของโค้ด Call Depth Tracking และผลการวัดประสิทธิภาพดูมีแนวโน้มมากที่จะลดความเจ็บปวดจากผลกระทบต่อประสิทธิภาพการบรรเทาผลกระทบจาก Retbleed CPU

สำหรับสิ่งที่ Peter ได้ทำกับโค้ด Call Depth Tracking นี้ เขาอธิบายด้วยแพตช์ v2:

เวอร์ชันนี้แตกต่างอย่างมากจากเวอร์ชันล่าสุดซึ่งไม่มีแล้ว การใช้ thunks การโทรภายนอกที่จัดสรรจากพื้นที่โมดูล แต่ทุกฟังก์ชันจะถูกจัดตำแหน่งเป็น 16 ไบต์และรับ 16 ไบต์ของ (pre-symbol)
padding (ช่องว่างภายในนี้จะมีประโยชน์สำหรับสิ่งอื่น เช่น งาน kCFI/FineIBT)

ก่อนการจัดตำแหน่งฟังก์ชันแพตช์เหล่านี้โดยพื้นฐานแล้วจะไม่มีอยู่จริง เนื่องจากการดึงคำสั่งใดๆ สำหรับคำสั่งแรกของฟังก์ชันจะมี ( โดยเฉลี่ย) ครึ่งหนึ่งของหน้าต่างดึงข้อมูลจะเต็มไปด้วยสิ่งที่มาก่อน ด้วยการผลักการจัดตำแหน่งสูงสุด 16 ไบต์ สิ่งนี้จะช่วยปรับปรุงเรื่องของชิปที่มีขนาดหน้าต่าง i-fetch ขนาด 16 ไบต์ (Intel) ในขณะที่ไม่ทำให้เรื่องแย่ลงสำหรับชิปที่มีหน้าต่าง i-fetch 32 ไบต์ที่ใหญ่กว่า (AMD Zen) อันที่จริง มันปรับปรุงกรณีที่เลวร้ายที่สุดสำหรับ Zen จากขยะ 31 ไบต์เป็นขยะ 16 ไบต์

เพราะฉะนั้น แพทช์แรกๆ ของซีรีส์นี้จะช่วยแก้ไขจุดบกพร่องในการจัดตำแหน่งได้มากมาย

ความแตกต่างที่สำคัญประการที่สองคือการแนะนำ struct pcpu_hot เนื่องจากคอมไพเลอร์จัดการวางตัวแปร DEFINE_PER_CPU() สองตัวที่อยู่ติดกัน (ในโค้ด) ในแคชไลน์แบบสุ่ม (ทำได้ฟรีอย่างแน่นอน) การแนะนำตัวแปร x86_call_deepth ต่อซีพียูในบางครั้ง ทำให้เกิดแรงดันแคชเพิ่มเติมในบางครั้ง อย่างดีในบรรทัดเดียวกันกับ preempt_count และไม่แสดงเลย

เพื่อบรรเทาปัญหานี้ แนะนำ struct pcpu_hot และรวบรวมตัวแปร hot per-cpu จำนวนหนึ่ง ในลักษณะที่คอมไพเลอร์ไม่สามารถทำผิดพลาดได้

เป็นข้อมูลพื้นฐานเพิ่มเติมเกี่ยวกับ Call Depth Tracking สำหรับ Retbleed Retbleed:

นอกเหนือจากการเปลี่ยนแปลงเหล่านี้ แก่นของการติดตามความลึกยังคงเหมือนเดิม

-objtool สร้างรายการไซต์การเรียกใช้ (ฟังก์ชัน)

-สำหรับทุกการโทร เขียนทับ padding ของฟังก์ชันเป้าหมายด้วย thunk การบัญชี (ถ้ายังไม่ได้ทำ) และปรับไซต์การโทรเพื่อกำหนดเป้าหมาย thunk นี้

-กลไกการส่งคืนแบบ retbleed ใช้สำหรับ thunk การส่งคืนแบบกำหนดเองที่รวมการบัญชีการส่งคืน และทำการบรรจุ RSB เมื่อจำเป็น

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

“retbleed=stuff”

บนบรรทัดคำสั่งเคอร์เนล

Return-Stack-Buffer (RSB) เป็น 16 deep stack ที่เติมเต็มในทุกการโทร ในการเก็งกำไรเส้นทางกลับจะ”ป๊อป”รายการและถือว่าเป็นเป้าหมายการส่งคืน เมื่อ RSB ว่างเปล่า CPU จะกลับไปใช้ตัวทำนายอื่นๆ เช่น บัฟเฟอร์ประวัติสาขา ซึ่งพื้นที่ของผู้ใช้อาจถูกฝึกผิดและทำให้เส้นทางการเก็งกำไร (ส่งคืน) ผิดพลาดไปยังแกดเจ็ตการเปิดเผยข้อมูลที่คุณเลือก ตามที่อธิบายไว้ในเอกสารอ้างอิง

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

สมมติฐานคือการบรรจุที่การส่งคืนครั้งที่ 12 นั้นเพียงพอที่จะทำลายการเก็งกำไรก่อนที่มันจะเข้าสู่อันเดอร์โฟลว์และการย้อนกลับไปยังตัวทำนายอื่นๆ การทดสอบยืนยันว่าใช้งานได้ Johannes หนึ่งในนักวิจัยที่เก่งกาจพยายามโจมตีแนวทางนี้และยืนยันว่าได้นำอัตราส่วนสัญญาณต่อสัญญาณรบกวนลงมาที่ระดับลูกบอลคริสตัล

ผลการวัดประสิทธิภาพดูมีแนวโน้มดีมาก:
รายละเอียดทั้งหมดและแพตช์ Call Depth Tracking v2 ใหม่ล่าสุดสำหรับเคอร์เนล Linux ผ่านชุดข้อความรายชื่ออีเมลนี้.

Categories: IT Info