অ্যান্ড্রয়েড ভার্চুয়ালাইজেশন ফ্রেমওয়ার্ক বাস্তবায়নের জন্য প্রয়োজনীয় সমস্ত উপাদানের একটি রেফারেন্স ইমপ্লিমেন্টেশন অ্যান্ড্রয়েড সরবরাহ করে। বর্তমানে এই ইমপ্লিমেন্টেশনটি শুধুমাত্র ARM64-এর জন্য সীমাবদ্ধ। এই পৃষ্ঠাটি ফ্রেমওয়ার্কটির স্থাপত্য ব্যাখ্যা করে।
পটভূমি
Arm আর্কিটেকচারে সর্বোচ্চ চারটি এক্সেপশন লেভেল রয়েছে, যেখানে এক্সেপশন লেভেল ০ (EL0) হলো সর্বনিম্ন সুবিধাপ্রাপ্ত এবং এক্সেপশন লেভেল ৩ (EL3) হলো সর্বোচ্চ। অ্যান্ড্রয়েড কোডবেসের সবচেয়ে বড় অংশ (সমস্ত ইউজারস্পেস কম্পোনেন্ট) EL0 লেভেলে চলে। সাধারণভাবে যাকে "অ্যান্ড্রয়েড" বলা হয়, তার বাকি অংশ হলো লিনাক্স কার্নেল, যা EL1 লেভেলে চলে।
EL2 লেয়ার এমন একটি হাইপারভাইজর প্রবর্তনের সুযোগ দেয়, যা শক্তিশালী গোপনীয়তা ও অখণ্ডতার নিশ্চয়তাসহ EL1/EL0 পর্যায়ে মেমরি এবং ডিভাইসগুলোকে স্বতন্ত্র pVM-এ বিচ্ছিন্ন করতে সক্ষম করে।
হাইপারভাইজর
সুরক্ষিত কার্নেল-ভিত্তিক ভার্চুয়াল মেশিন (pKVM) লিনাক্স KVM হাইপারভাইজরের উপর ভিত্তি করে নির্মিত, যাকে এই ক্ষমতা দিয়ে সম্প্রসারিত করা হয়েছে যে, তৈরির সময় 'সুরক্ষিত' হিসেবে চিহ্নিত গেস্ট ভার্চুয়াল মেশিনগুলিতে চলমান পেলোডগুলির অ্যাক্সেস সীমাবদ্ধ করা যায়।
KVM/arm64 নির্দিষ্ট কিছু সিপিইউ ফিচারের প্রাপ্যতার উপর নির্ভর করে বিভিন্ন এক্সিকিউশন মোড সমর্থন করে, যেমন—ভার্চুয়ালাইজেশন হোস্ট এক্সটেনশনস (VHE) (ARMv8.1 এবং তার পরবর্তী সংস্করণ)। এই মোডগুলোর মধ্যে একটি, যা সাধারণত নন-VHE মোড নামে পরিচিত, সেখানে বুট করার সময় হাইপারভাইজর কোডটি কার্নেল ইমেজ থেকে আলাদা করে EL2-তে ইনস্টল করা হয়, যেখানে কার্নেলটি নিজে EL1-এ চলে। যদিও লিনাক্স কোডবেসের একটি অংশ, KVM-এর EL2 কম্পোনেন্টটি একটি ছোট উপাদান যা একাধিক EL1-এর মধ্যে সুইচ করার দায়িত্বে থাকে। হাইপারভাইজর কম্পোনেন্টটি লিনাক্স দিয়ে কম্পাইল করা হলেও, এটি vmlinux ইমেজের একটি পৃথক, নির্দিষ্ট মেমরি সেকশনে অবস্থান করে। pKVM এই ডিজাইনটিকে কাজে লাগিয়ে হাইপারভাইজর কোডকে নতুন ফিচার দিয়ে প্রসারিত করে, যা এটিকে অ্যান্ড্রয়েড হোস্ট কার্নেল এবং ইউজার স্পেসের উপর বিধিনিষেধ আরোপ করতে এবং গেস্ট মেমরি ও হাইপারভাইজরে হোস্টের অ্যাক্সেস সীমিত করতে সক্ষম করে।
pKVM বিক্রেতা মডিউল
একটি pKVM ভেন্ডর মডিউল হলো একটি হার্ডওয়্যার-নির্দিষ্ট মডিউল, যাতে ডিভাইস-নির্দিষ্ট কার্যকারিতা, যেমন ইনপুট-আউটপুট মেমরি ম্যানেজমেন্ট ইউনিট (IOMMU) ড্রাইভার থাকে। এই মডিউলগুলো আপনাকে pKVM-এ এক্সেপশন লেভেল 2 (EL2) অ্যাক্সেসের প্রয়োজন হয় এমন নিরাপত্তা বৈশিষ্ট্য পোর্ট করতে দেয়।
কিভাবে একটি pKVM ভেন্ডর মডিউল ইমপ্লিমেন্ট এবং লোড করতে হয় তা জানতে, "Implement a pKVM vendor module" দেখুন।
বুট পদ্ধতি
নিম্নোক্ত চিত্রে pKVM বুট প্রক্রিয়াটি দেখানো হয়েছে:

- প্রারম্ভিকীকরণ: বুটলোডার EL2 পর্যায়ে জেনেরিক কার্নেলে প্রবেশ করে। এরপর EL2 এবং EL1 উভয় পর্যায়ের বিশ্বস্ত কার্নেল কোড pKVM এবং এর মডিউলগুলোকে প্রারম্ভিকীকরণ করে। এই পর্যায়ে, EL2 দ্বারা EL1 বিশ্বস্ত থাকে, ফলে কোনো অবিশ্বস্ত কোড কার্যকর হয় না।
- কার্নেলের বিশেষাধিকার হরণ: জেনেরিক কার্নেলটি শনাক্ত করে যে এটি EL2 স্তরে চলছে এবং নিজের বিশেষাধিকার কমিয়ে EL1 স্তরে নেমে আসে। pKVM এবং এর মডিউলগুলো EL2 স্তরেই চলতে থাকে।
- রানটাইম : জেনেরিক কার্নেল স্বাভাবিকভাবে বুট হতে থাকে এবং ইউজার স্পেসে পৌঁছানো পর্যন্ত সমস্ত প্রয়োজনীয় ডিভাইস ড্রাইভার লোড করে। এই পর্যায়ে, pKVM স্থাপিত থাকে এবং স্টেজ-২ পেজ টেবিলগুলো পরিচালনা করে।
বুট প্রক্রিয়াটি প্রারম্ভিক পর্যায়ে কার্নেল ইমেজের অখণ্ডতা যাচাই ও বজায় রাখার জন্য বুটলোডারের উপর আস্থা রাখে। কার্নেলকে বিশেষাধিকারহীন করার পর, হাইপারভাইজর এটিকে আর বিশ্বস্ত বলে মনে করে না, ফলে কার্নেল ক্ষতিগ্রস্ত হলেও নিজেকে রক্ষা করার দায়িত্ব তখন হাইপারভাইজরের উপর বর্তায়।
অ্যান্ড্রয়েড কার্নেল এবং হাইপারভাইজর একই বাইনারি ইমেজে থাকায় তাদের মধ্যে একটি অত্যন্ত নিবিড়ভাবে সংযুক্ত যোগাযোগ ইন্টারফেস তৈরি হয়। এই নিবিড় সংযোগ দুটি উপাদানের অ্যাটমিক আপডেট নিশ্চিত করে, যা তাদের মধ্যকার ইন্টারফেসকে স্থিতিশীল রাখার প্রয়োজনীয়তা দূর করে এবং দীর্ঘমেয়াদী রক্ষণাবেক্ষণযোগ্যতার সাথে আপোস না করেই প্রচুর নমনীয়তা প্রদান করে। এই নিবিড় সংযোগ পারফরম্যান্স অপ্টিমাইজেশনেরও সুযোগ করে দেয়, যখন উভয় উপাদান হাইপারভাইজরের দেওয়া নিরাপত্তা নিশ্চয়তাকে প্রভাবিত না করেই একসাথে কাজ করতে পারে।
তাছাড়া, অ্যান্ড্রয়েড ইকোসিস্টেমে GKI গৃহীত হওয়ায় pKVM হাইপারভাইজরটি স্বয়ংক্রিয়ভাবে কার্নেলের সাথে একই বাইনারিতে অ্যান্ড্রয়েড ডিভাইসগুলোতে স্থাপন করা যায়।
সিপিইউ মেমরি অ্যাক্সেস সুরক্ষা
Arm আর্কিটেকচারে একটি মেমরি ম্যানেজমেন্ট ইউনিট (MMU) নির্দিষ্ট করা আছে যা দুটি স্বাধীন স্টেজে বিভক্ত, এবং এই দুটি স্টেজই মেমরির বিভিন্ন অংশে অ্যাড্রেস ট্রান্সলেশন ও অ্যাক্সেস কন্ট্রোল বাস্তবায়নের জন্য ব্যবহার করা যেতে পারে। স্টেজ ১ MMU-টি EL1 দ্বারা নিয়ন্ত্রিত হয় এবং এটি প্রথম স্তরের অ্যাড্রেস ট্রান্সলেশনের সুযোগ দেয়। লিনাক্স প্রতিটি ইউজারস্পেস প্রসেসকে প্রদত্ত ভার্চুয়াল অ্যাড্রেস স্পেস এবং তার নিজের ভার্চুয়াল অ্যাড্রেস স্পেস পরিচালনা করার জন্য স্টেজ ১ MMU ব্যবহার করে।
স্টেজ ২ MMU, EL2 দ্বারা নিয়ন্ত্রিত হয় এবং স্টেজ ১ MMU-এর আউটপুট অ্যাড্রেসে একটি দ্বিতীয় অ্যাড্রেস ট্রান্সলেশন প্রয়োগ করতে সক্ষম করে, যার ফলে একটি ফিজিক্যাল অ্যাড্রেস (PA) তৈরি হয়। হাইপারভাইজরগুলো সমস্ত গেস্ট VM থেকে মেমরি অ্যাক্সেস নিয়ন্ত্রণ ও অনুবাদ করার জন্য এই স্টেজ ২ ট্রান্সলেশন ব্যবহার করতে পারে। চিত্র ২-এ যেমন দেখানো হয়েছে, যখন ট্রান্সলেশনের উভয় পর্যায় সক্রিয় থাকে, তখন স্টেজ ১-এর আউটপুট অ্যাড্রেসকে ইন্টারমিডিয়েট ফিজিক্যাল অ্যাড্রেস (IPA) বলা হয়। দ্রষ্টব্য: ভার্চুয়াল অ্যাড্রেস (VA) প্রথমে একটি IPA-তে এবং তারপর একটি PA-তে রূপান্তরিত হয়।

ঐতিহাসিকভাবে, KVM গেস্ট চালানোর সময় স্টেজ ২ ট্রান্সলেশন সক্রিয় রেখে এবং হোস্ট লিনাক্স কার্নেল চালানোর সময় স্টেজ ২ নিষ্ক্রিয় রেখে চলে। এই আর্কিটেকচারটি হোস্ট স্টেজ ১ MMU থেকে স্টেজ ২ MMU-এর মধ্য দিয়ে মেমরি অ্যাক্সেস করতে দেয়, যার ফলে হোস্ট থেকে গেস্ট মেমরি পেজগুলিতে অবাধ অ্যাক্সেস সম্ভব হয়। অন্যদিকে, pKVM হোস্ট প্রেক্ষাপটেও স্টেজ ২ সুরক্ষা সক্রিয় করে এবং হোস্টের পরিবর্তে হাইপারভাইজরের উপর গেস্ট মেমরি পেজগুলি সুরক্ষিত করার দায়িত্ব অর্পণ করে।
KVM স্টেজ ২-এ অ্যাড্রেস ট্রান্সলেশনের পূর্ণ ব্যবহার করে গেস্টদের জন্য জটিল IPA/PA ম্যাপিং বাস্তবায়ন করে, যা ফিজিক্যাল ফ্র্যাগমেন্টেশন থাকা সত্ত্বেও গেস্টদের জন্য কন্টিগিউয়াস মেমোরির একটি বিভ্রম তৈরি করে। তবে, হোস্টের জন্য স্টেজ ২ MMU-এর ব্যবহার শুধুমাত্র অ্যাক্সেস কন্ট্রোলের মধ্যে সীমাবদ্ধ থাকে। হোস্ট স্টেজ ২ আইডেন্টিটি-ম্যাপড, যা নিশ্চিত করে যে হোস্ট IPA স্পেসের কন্টিগিউয়াস মেমোরি PA স্পেসেও কন্টিগিউয়াস থাকে। এই আর্কিটেকচারটি পেজ টেবিলে বড় ম্যাপিং ব্যবহারের সুযোগ দেয় এবং ফলস্বরূপ ট্রান্সলেশন লুকাসাইড বাফারের (TLB) উপর চাপ কমায়। যেহেতু একটি আইডেন্টিটি ম্যাপিং PA দ্বারা ইনডেক্স করা যায়, তাই পেজ টেবিলে সরাসরি পেজের মালিকানা ট্র্যাক করার জন্যও হোস্ট স্টেজ ২ ব্যবহৃত হয়।
সরাসরি মেমরি অ্যাক্সেস (ডিএমএ) সুরক্ষা
পূর্বে যেমন বর্ণনা করা হয়েছে, সিপিইউ পেজ টেবিলে লিনাক্স হোস্ট থেকে গেস্ট পেজগুলোকে আনম্যাপ করা গেস্ট মেমরি সুরক্ষার জন্য একটি প্রয়োজনীয় কিন্তু অপর্যাপ্ত পদক্ষেপ। pKVM-কে হোস্ট কার্নেলের নিয়ন্ত্রণে থাকা ডিএমএ-সক্ষম ডিভাইস দ্বারা করা মেমরি অ্যাক্সেস এবং একটি ক্ষতিকারক হোস্ট দ্বারা শুরু করা ডিএমএ আক্রমণের সম্ভাবনা থেকেও সুরক্ষা প্রদান করতে হয়। এই ধরনের কোনো ডিভাইসকে গেস্ট মেমরি অ্যাক্সেস করা থেকে বিরত রাখতে, pKVM-এর সিস্টেমের প্রতিটি ডিএমএ-সক্ষম ডিভাইসের জন্য ইনপুট-আউটপুট মেমরি ম্যানেজমেন্ট ইউনিট (IOMMU) হার্ডওয়্যার প্রয়োজন, যেমনটি চিত্র ৩-এ দেখানো হয়েছে।

ন্যূনতমপক্ষে, IOMMU হার্ডওয়্যার কোনো ডিভাইসকে পেজ গ্র্যানুলারিটিতে ফিজিক্যাল মেমরিতে রিড/রাইট অ্যাক্সেস মঞ্জুর ও প্রত্যাহার করার উপায় প্রদান করে। তবে, এই IOMMU হার্ডওয়্যার pVM-এ ডিভাইসের ব্যবহারকে সীমিত করে, কারণ pVM-গুলো একটি আইডেন্টিটি-ম্যাপড স্টেজ ২ ধরে নেয়।
ভার্চুয়াল মেশিনগুলোর মধ্যে বিচ্ছিন্নতা নিশ্চিত করার জন্য, বিভিন্ন সত্তার পক্ষ থেকে তৈরি হওয়া মেমরি ট্রানজ্যাকশনগুলোকে IOMMU দ্বারা পৃথকযোগ্য হতে হবে, যাতে অনুবাদের জন্য পেজ টেবিলের উপযুক্ত সেট ব্যবহার করা যায়।
এছাড়াও, pKVM-এর সামগ্রিক বিশ্বস্ত কম্পিউটিং ভিত্তি (TCB) কমানোর জন্য EL2-তে SoC-নির্দিষ্ট কোডের পরিমাণ হ্রাস করা একটি মূল কৌশল এবং এটি হাইপারভাইজরে IOMMU ড্রাইভার অন্তর্ভুক্ত করার পরিপন্থী। এই সমস্যাটি প্রশমিত করার জন্য, EL1-এর হোস্ট সহায়ক IOMMU ব্যবস্থাপনার কাজগুলোর জন্য দায়ী থাকে, যেমন পাওয়ার ম্যানেজমেন্ট, ইনিশিয়ালাইজেশন এবং, যেখানে প্রযোজ্য, ইন্টারাপ্ট হ্যান্ডলিং।
তবে, ডিভাইসের অবস্থার নিয়ন্ত্রণ হোস্টের হাতে তুলে দিলে IOMMU হার্ডওয়্যারের প্রোগ্রামিং ইন্টারফেসের উপর অতিরিক্ত কিছু শর্ত আরোপিত হয়, যাতে অন্য কোনো উপায়ে, যেমন ডিভাইস রিসেট করার পর, অনুমতি যাচাই প্রক্রিয়া এড়িয়ে যাওয়া না যায়।
আর্ম ডিভাইসগুলির জন্য একটি আদর্শ এবং সুসমর্থিত IOMMU হলো আর্ম সিস্টেম মেমোরি ম্যানেজমেন্ট ইউনিট (SMMU) আর্কিটেকচার, যা আইসোলেশন এবং ডাইরেক্ট অ্যাসাইনমেন্ট উভয়ই সম্ভব করে তোলে। এই আর্কিটেকচারটিই প্রস্তাবিত রেফারেন্স সলিউশন।
স্মৃতি মালিকানা
বুট করার সময়, হাইপারভাইজর-বহির্ভূত সমস্ত মেমরি হোস্টের মালিকানাধীন বলে ধরে নেওয়া হয় এবং হাইপারভাইজর সেভাবেই সেটিকে ট্র্যাক করে। যখন একটি pVM তৈরি করা হয়, তখন হোস্ট সেটিকে বুট করার জন্য মেমরি পেজ দান করে এবং হাইপারভাইজর সেই পেজগুলোর মালিকানা হোস্ট থেকে pVM-এর কাছে হস্তান্তর করে। এইভাবে, হাইপারভাইজর হোস্টের স্টেজ ২ পেজ টেবিলে অ্যাক্সেস-কন্ট্রোল বিধিনিষেধ আরোপ করে যাতে হোস্ট পুনরায় সেই পেজগুলো অ্যাক্সেস করতে না পারে, যা গেস্টকে গোপনীয়তা প্রদান করে।
হোস্ট এবং গেস্টদের মধ্যে নিয়ন্ত্রিত মেমরি শেয়ারিংয়ের মাধ্যমে যোগাযোগ সম্ভব হয়। গেস্টদের একটি হাইপারকল ব্যবহার করে তাদের কিছু পেজ হোস্টের সাথে পুনরায় শেয়ার করার অনুমতি দেওয়া হয়, যা হাইপারভাইজরকে হোস্ট স্টেজ ২ পেজ টেবিলে সেই পেজগুলোকে রিম্যাপ করার নির্দেশ দেয়। একইভাবে, ট্রাস্টজোনের সাথে হোস্টের যোগাযোগ মেমরি শেয়ারিং এবং/অথবা লেন্ডিং অপারেশনের মাধ্যমে সম্ভব হয়, যার সবগুলোই ফার্মওয়্যার ফ্রেমওয়ার্ক ফর আর্ম (FF-A) স্পেসিফিকেশন ব্যবহার করে pKVM দ্বারা নিবিড়ভাবে পর্যবেক্ষণ ও নিয়ন্ত্রণ করা হয়।
যেহেতু একটি pVM-এর মেমরির প্রয়োজনীয়তা সময়ের সাথে সাথে পরিবর্তিত হতে পারে, তাই একটি হাইপারকল প্রদান করা হয়েছে যা কলারের নির্দিষ্ট পেজগুলোর মালিকানা হোস্টকে ফিরিয়ে দেওয়ার সুযোগ দেয়। বাস্তবে, এই হাইপারকলটি ভার্চুও বেলুন প্রোটোকলের সাথে ব্যবহৃত হয়, যা VMM-কে pVM-এর কাছ থেকে মেমরি ফেরত অনুরোধ করার এবং pVM-কে একটি নিয়ন্ত্রিত পদ্ধতিতে VMM-কে ছেড়ে দেওয়া পেজগুলো সম্পর্কে অবহিত করার সুযোগ দেয়।
সিস্টেমের সমস্ত মেমরি পেজের মালিকানা ট্র্যাক করা এবং সেগুলি অন্য কোনো সত্তার সাথে শেয়ার বা ধার দেওয়া হচ্ছে কিনা, তা দেখার দায়িত্ব হাইপারভাইজরের। এই স্টেট ট্র্যাকিংয়ের বেশিরভাগই করা হয় হোস্ট এবং গেস্টের স্টেজ ২ পেজ টেবিলের সাথে সংযুক্ত মেটাডেটা ব্যবহার করে। এর জন্য পেজ টেবিল এন্ট্রি (PTE)-তে সংরক্ষিত বিট ব্যবহার করা হয়, যা নাম থেকেই বোঝা যায়, সফটওয়্যার ব্যবহারের জন্য সংরক্ষিত থাকে।
হোস্টকে অবশ্যই নিশ্চিত করতে হবে যে এটি হাইপারভাইজর দ্বারা অ্যাক্সেস-অযোগ্য করে দেওয়া পেজগুলো অ্যাক্সেস করার চেষ্টা না করে। একটি অবৈধ হোস্ট অ্যাক্সেসের ফলে হাইপারভাইজর দ্বারা হোস্টে একটি সিনক্রোনাস এক্সেপশন ইনজেক্ট করা হয়, যার ফলে হয় সংশ্লিষ্ট ইউজারস্পেস টাস্কটি একটি SEGV সিগন্যাল পায়, অথবা হোস্ট কার্নেল ক্র্যাশ করে। দুর্ঘটনাজনিত অ্যাক্সেস প্রতিরোধ করার জন্য, গেস্টদেরকে দান করা পেজগুলোকে হোস্ট কার্নেল দ্বারা সোয়াপিং বা মার্জ করার জন্য অযোগ্য করে দেওয়া হয়।
বাধা পরিচালনা এবং টাইমার
গেস্ট যেভাবে ডিভাইসগুলোর সাথে যোগাযোগ করে এবং সিপিইউগুলোর মধ্যে যোগাযোগের জন্য ইন্টারাপ্ট একটি অপরিহার্য অংশ, যেখানে ইন্টারপ্রসেসর ইন্টারাপ্ট (IPI) হলো প্রধান যোগাযোগ ব্যবস্থা। KVM মডেলে EL1-এ সমস্ত ভার্চুয়াল ইন্টারাপ্ট ব্যবস্থাপনার দায়িত্ব হোস্টের উপর অর্পণ করা হয়, যার জন্য হোস্ট হাইপারভাইজরের একটি অবিশ্বস্ত অংশ হিসেবে কাজ করে।
pKVM বিদ্যমান KVM কোডের উপর ভিত্তি করে একটি পূর্ণাঙ্গ জেনেরিক ইন্টারাপ্ট কন্ট্রোলার সংস্করণ ৩ (GICv3) এমুলেশন প্রদান করে। টাইমার এবং IPI-গুলো এই অবিশ্বস্ত এমুলেশন কোডের অংশ হিসেবে পরিচালিত হয়।
GICv3 সমর্থন
EL1 এবং EL2-এর মধ্যকার ইন্টারফেসকে অবশ্যই নিশ্চিত করতে হবে যে, ইন্টারাপ্ট-সম্পর্কিত হাইপারভাইজর রেজিস্টারগুলোর অনুলিপিসহ সম্পূর্ণ ইন্টারাপ্ট অবস্থাটি EL1 হোস্টের কাছে দৃশ্যমান থাকে। এই দৃশ্যমানতা সাধারণত শেয়ার্ড মেমরি রিজিয়ন ব্যবহার করে সম্পন্ন করা হয়, যা প্রতিটি ভার্চুয়াল সিপিইউ (vCPU)-এর জন্য একটি করে থাকে।
সিস্টেম রেজিস্টার রানটাইম সাপোর্ট কোডকে সরলীকরণ করে শুধুমাত্র সফটওয়্যার জেনারেটেড ইন্টারাপ্ট রেজিস্টার (SGIR) এবং ডিঅ্যাকটিভেট ইন্টারাপ্ট রেজিস্টার (DIR) রেজিস্টার ট্র্যাপিং সমর্থন করার ব্যবস্থা করা যেতে পারে। আর্কিটেকচার অনুযায়ী এই রেজিস্টারগুলো সর্বদা EL2-তে ট্র্যাপ করবে, যেখানে অন্যান্য ট্র্যাপগুলো এখন পর্যন্ত শুধুমাত্র ত্রুটি সংশোধনের জন্য কার্যকর ছিল। বাকি সবকিছু হার্ডওয়্যারে পরিচালিত হচ্ছে।
MMIO প্রান্তে, KVM-এর সমস্ত বর্তমান পরিকাঠামো পুনঃব্যবহার করে সবকিছু EL1-এ অনুকরণ করা হয়। পরিশেষে, Wait for Interrupt (WFI) সর্বদা EL1-এ রিলে করা হয়, কারণ এটি KVM-এর ব্যবহৃত অন্যতম মৌলিক শিডিউলিং প্রিমিটিভ।
টাইমার সমর্থন
প্রতিটি ট্র্যাপিং WFI-তে ভার্চুয়াল টাইমারের কম্পারেটর মান অবশ্যই EL1-এর কাছে প্রকাশ করতে হবে, যাতে vCPU ব্লক থাকা অবস্থায় EL1 টাইমার ইন্টারাপ্ট ইনজেক্ট করতে পারে। ফিজিক্যাল টাইমারটি সম্পূর্ণরূপে এমুলেট করা হয় এবং সমস্ত ট্র্যাপ EL1-এ রিলে করা হয়।
MMIO হ্যান্ডলিং
ভার্চুয়াল মেশিন মনিটর (VMM)-এর সাথে যোগাযোগ করতে এবং GIC এমুলেশন সম্পাদন করতে, পরবর্তী বাছাইয়ের জন্য MMIO ট্র্যাপগুলিকে অবশ্যই EL1-এ থাকা হোস্টে ফেরত পাঠাতে হবে। pKVM-এর জন্য নিম্নলিখিতগুলি প্রয়োজন:
- আইপিএ এবং অ্যাক্সেসের আকার
- লেখার ক্ষেত্রে ডেটা
- ট্র্যাপিং পয়েন্টে সিপিইউ-এর এন্ডিয়ানেস
অতিরিক্তভাবে, একটি অ্যাবস্ট্রাক্ট ট্রান্সফার সিউডো-রেজিস্টার ব্যবহার করে জেনারেল পারপাস রেজিস্টার (GPR)-কে উৎস/গন্তব্য হিসেবে থাকা ট্র্যাপগুলো রিলে করা হয়।
অতিথি ইন্টারফেস
একজন গেস্ট হাইপারকল এবং ট্র্যাপড রিজিয়নে মেমরি অ্যাক্সেসের সমন্বয় ব্যবহার করে একজন প্রোটেক্টেড গেস্টের সাথে যোগাযোগ করতে পারে। হাইপারকলগুলো SMCCC স্ট্যান্ডার্ড অনুযায়ী উন্মুক্ত করা হয়, যার একটি রেঞ্জ KVM দ্বারা ভেন্ডর অ্যালোকেশনের জন্য সংরক্ষিত থাকে। নিম্নলিখিত হাইপারকলগুলো pKVM গেস্টদের জন্য বিশেষভাবে গুরুত্বপূর্ণ।
জেনেরিক হাইপারকল
- PSCI গেস্টকে তার vCPU-গুলির জীবনচক্র নিয়ন্ত্রণ করার জন্য একটি আদর্শ ব্যবস্থা প্রদান করে, যার মধ্যে অনলাইনিং, অফলাইনিং এবং সিস্টেম শাটডাউন অন্তর্ভুক্ত।
- TRNG গেস্টকে pKVM-এর কাছে এনট্রপি অনুরোধ করার জন্য একটি আদর্শ ব্যবস্থা প্রদান করে, যা সেই অনুরোধটি EL3-তে পাঠিয়ে দেয়। এই ব্যবস্থাটি বিশেষভাবে উপযোগী, যেখানে কোনো হোস্ট একটি হার্ডওয়্যার র্যান্ডম নম্বর জেনারেটর (RNG) ভার্চুয়ালাইজ করার ক্ষেত্রে নির্ভরযোগ্য নয়।
pKVM হাইপারকল
- হোস্টের সাথে মেমরি শেয়ারিং। গেস্টের সমস্ত মেমরি প্রাথমিকভাবে হোস্টের কাছে অ্যাক্সেসযোগ্য থাকে না, কিন্তু শেয়ার্ড-মেমরি কমিউনিকেশন এবং শেয়ার্ড বাফারের উপর নির্ভরশীল প্যারাভার্চুয়ালাইজড ডিভাইসগুলোর জন্য হোস্ট অ্যাক্সেস প্রয়োজন। হোস্টের সাথে পেজ শেয়ার এবং আনশেয়ার করার জন্য হাইপারকলগুলো গেস্টকে হ্যান্ডশেক ছাড়াই মেমরির ঠিক কোন অংশগুলো অ্যান্ড্রয়েডের বাকি অংশের জন্য অ্যাক্সেসযোগ্য করা হবে, তা নির্ধারণ করার সুযোগ দেয়।
- হোস্টের কাছে মেমরি হস্তান্তর। গেস্ট ধ্বংস না হওয়া পর্যন্ত সমস্ত গেস্ট মেমরি সাধারণত গেস্টেরই থাকে। এই অবস্থাটি দীর্ঘস্থায়ী ভিএম-এর জন্য অপর্যাপ্ত হতে পারে, যাদের মেমরির চাহিদা সময়ের সাথে সাথে পরিবর্তিত হয়।
relinquishহাইপারকলটি গেস্টকে টার্মিনেশন ছাড়াই পেজগুলির মালিকানা স্পষ্টভাবে হোস্টের কাছে হস্তান্তর করার সুযোগ দেয়। - হোস্টে মেমরি অ্যাক্সেস ট্র্যাপিং। প্রথাগতভাবে, যদি একটি KVM গেস্ট এমন কোনো অ্যাড্রেস অ্যাক্সেস করে যা কোনো বৈধ মেমরি অঞ্চলের সাথে সঙ্গতিপূর্ণ নয়, তাহলে vCPU থ্রেডটি হোস্টে এক্সিট করে এবং এই অ্যাক্সেসটি সাধারণত MMIO-এর জন্য ব্যবহৃত হয় ও ইউজার স্পেসে VMM দ্বারা এমুলেট করা হয়। এই হ্যান্ডলিং সহজ করার জন্য, pKVM-কে ফল্টিং ইনস্ট্রাকশনটির অ্যাড্রেস, রেজিস্টার প্যারামিটার এবং সম্ভাব্য সেগুলোর বিষয়বস্তুর মতো বিবরণ হোস্টে ফেরত পাঠাতে হয়, যা ট্র্যাপটি প্রত্যাশিত না হলে একটি সুরক্ষিত গেস্টের সংবেদনশীল ডেটা অনিচ্ছাকৃতভাবে প্রকাশ করে দিতে পারে। pKVM এই সমস্যাটি সমাধান করে এই ফল্টগুলোকে মারাত্মক (fatal) হিসেবে গণ্য করার মাধ্যমে, যদি না গেস্টটি পূর্বে একটি হাইপারকল জারি করে ফল্টিং IPA রেঞ্জটিকে এমন একটি হিসেবে চিহ্নিত করে যার জন্য অ্যাক্সেসগুলো হোস্টে ট্র্যাপ করার অনুমতিপ্রাপ্ত। এই সমাধানটিকে MMIO গার্ড (MMIO guard) বলা হয়।
ভার্চুয়াল আই/ও ডিভাইস (virtio)
ভার্টিও হলো প্যারাভার্চুয়ালাইজড ডিভাইস বাস্তবায়ন এবং সেগুলোর সাথে যোগাযোগের জন্য একটি জনপ্রিয়, পোর্টেবল এবং পরিপক্ক স্ট্যান্ডার্ড। প্রোটেক্টেড গেস্টদের কাছে উন্মুক্ত বেশিরভাগ ডিভাইস ভার্টিও ব্যবহার করে বাস্তবায়িত হয়। এছাড়াও, একটি প্রোটেক্টেড গেস্ট এবং অ্যান্ড্রয়েডের বাকি অংশের মধ্যে যোগাযোগের জন্য ব্যবহৃত vsock ইমপ্লিমেন্টেশনের ভিত্তি হিসেবেও ভার্টিও কাজ করে।
ভার্টিও ডিভাইসগুলো সাধারণত হোস্টের ইউজার স্পেসে VMM দ্বারা বাস্তবায়িত হয়, যা গেস্ট থেকে ভার্টিও ডিভাইসের MMIO ইন্টারফেসে ট্র্যাপড মেমরি অ্যাক্সেসকে বাধা দেয় এবং প্রত্যাশিত আচরণ অনুকরণ করে। MMIO অ্যাক্সেস তুলনামূলকভাবে ব্যয়বহুল, কারণ ডিভাইসে প্রতিটি অ্যাক্সেসের জন্য VMM-এ যাওয়া-আসা করতে হয়, তাই ডিভাইস এবং গেস্টের মধ্যে বেশিরভাগ প্রকৃত ডেটা স্থানান্তর মেমরিতে থাকা এক সেট ভার্চকিউ ব্যবহার করে সম্পন্ন হয়। ভার্টিওর একটি মূল ধারণা হলো, হোস্ট গেস্টের মেমরিকে ইচ্ছামতো অ্যাক্সেস করতে পারে। এই ধারণাটি ভার্চকিউ-এর ডিজাইনে সুস্পষ্ট, যেখানে গেস্টের বাফারগুলোর পয়েন্টার থাকতে পারে, যেগুলোকে ডিভাইস এমুলেশন সরাসরি অ্যাক্সেস করার জন্য তৈরি।
যদিও পূর্বে বর্ণিত মেমরি শেয়ারিং হাইপারকলগুলো গেস্ট থেকে হোস্টে ভার্চুও ডেটা বাফার শেয়ার করার জন্য ব্যবহার করা যেত, এই শেয়ারিং অনিবার্যভাবে পেজ গ্র্যানুলারিটিতে সম্পাদিত হয় এবং বাফারের আকার একটি পেজের চেয়ে কম হলে এর ফলে প্রয়োজনের চেয়ে বেশি ডেটা উন্মুক্ত হয়ে যেতে পারে। এর পরিবর্তে, গেস্টকে শেয়ার্ড মেমরির একটি নির্দিষ্ট উইন্ডো থেকে ভার্চুওকিউ এবং তাদের সংশ্লিষ্ট ডেটা বাফার উভয়ই বরাদ্দ করার জন্য কনফিগার করা হয়, এবং প্রয়োজন অনুযায়ী ডেটা সেই উইন্ডোতে কপি (বাউন্স) করা হয়।

TrustZone-এর সাথে মিথস্ক্রিয়া
যদিও গেস্টরা সরাসরি ট্রাস্টজোনের সাথে যোগাযোগ করতে পারে না, তবুও হোস্টকে অবশ্যই সুরক্ষিত জগতে SMC কল করতে সক্ষম হতে হবে। এই কলগুলিতে এমন ফিজিক্যালি অ্যাড্রেস করা মেমরি বাফার নির্দিষ্ট করা থাকতে পারে যা হোস্টের জন্য অ্যাক্সেসযোগ্য নয়। যেহেতু সুরক্ষিত সফটওয়্যারটি সাধারণত বাফারের অ্যাক্সেসযোগ্যতা সম্পর্কে অবগত থাকে না, তাই একটি ক্ষতিকারক হোস্ট এই বাফারটি ব্যবহার করে একটি কনফিউজড ডেপুটি অ্যাটাক (যা একটি DMA অ্যাটাকের অনুরূপ) চালাতে পারে। এই ধরনের আক্রমণ প্রতিরোধ করার জন্য, pKVM হোস্টের EL2-তে করা সমস্ত SMC কল ট্র্যাপ করে এবং হোস্ট ও EL3-তে থাকা সুরক্ষিত মনিটরের মধ্যে একটি প্রক্সি হিসেবে কাজ করে।
হোস্ট থেকে আসা PSCI কলগুলো সামান্য কিছু পরিবর্তনসহ EL3 ফার্মওয়্যারে ফরোয়ার্ড করা হয়। বিশেষত, একটি সিপিইউ অনলাইন হওয়া বা সাসপেন্ড থেকে পুনরায় চালু হওয়ার এন্ট্রি পয়েন্টটি এমনভাবে পুনর্লিখন করা হয়, যাতে স্টেজ ২ পেজ টেবিলটি EL1-এ হোস্টে ফিরে আসার আগে EL2-তে ইনস্টল হয়। বুট করার সময়, এই সুরক্ষা pKVM দ্বারা প্রয়োগ করা হয়।
এই আর্কিটেকচারটি এমন SoC-এর উপর নির্ভর করে যা PSCI সমর্থন করে, এবং এর EL3 ফার্মওয়্যার হিসেবে TF-A- এর একটি হালনাগাদ সংস্করণ ব্যবহার করা বাঞ্ছনীয়।
ফার্মওয়্যার ফ্রেমওয়ার্ক ফর আর্ম (FF-A) সাধারণ এবং সুরক্ষিত জগতের মধ্যেকার মিথস্ক্রিয়াকে মানসম্মত করে, বিশেষ করে একটি সুরক্ষিত হাইপারভাইজরের উপস্থিতিতে। স্পেসিফিকেশনটির একটি প্রধান অংশ সুরক্ষিত জগতের সাথে মেমরি শেয়ার করার জন্য একটি প্রক্রিয়া সংজ্ঞায়িত করে, যেখানে একটি সাধারণ মেসেজ ফরম্যাট এবং অন্তর্নিহিত পেজগুলোর জন্য একটি সু-সংজ্ঞায়িত পারমিশন মডেল উভয়ই ব্যবহৃত হয়। pKVM, FF-A মেসেজগুলোকে প্রক্সি করে এটি নিশ্চিত করার জন্য যে, হোস্টটি সুরক্ষিত জগতের সাথে এমন কোনো মেমরি শেয়ার করার চেষ্টা করছে না যার জন্য তার পর্যাপ্ত পারমিশন নেই।
এই আর্কিটেকচারটি মেমরি অ্যাক্সেস মডেল প্রয়োগ করার জন্য সিকিওর ওয়ার্ল্ড সফটওয়্যারের উপর নির্ভর করে, যাতে বিশ্বস্ত অ্যাপ এবং সিকিওর ওয়ার্ল্ডে চলমান অন্য যেকোনো সফটওয়্যার কেবল তখনই মেমরি অ্যাক্সেস করতে পারে, যদি সেই মেমরিটি হয় একচেটিয়াভাবে সিকিওর ওয়ার্ল্ডের মালিকানাধীন থাকে অথবা FF-A ব্যবহার করে এর সাথে স্পষ্টভাবে শেয়ার করা হয়ে থাকে। S-EL2 যুক্ত একটি সিস্টেমে, মেমরি অ্যাক্সেস মডেল প্রয়োগের কাজটি একটি সিকিওর পার্টিশন ম্যানেজার কোর (SPMC), যেমন Hafnium , দ্বারা করা উচিত, যা সিকিওর ওয়ার্ল্ডের জন্য স্টেজ ২ পেজ টেবিল রক্ষণাবেক্ষণ করে। S-EL2 বিহীন একটি সিস্টেমে, TEE এর পরিবর্তে তার স্টেজ ১ পেজ টেবিলের মাধ্যমে একটি মেমরি অ্যাক্সেস মডেল প্রয়োগ করতে পারে।
যদি EL2-তে করা SMC কলটি কোনো PSCI কল বা FF-A দ্বারা সংজ্ঞায়িত মেসেজ না হয়, তাহলে হ্যান্ডেল না করা SMC-গুলো EL3-তে ফরোয়ার্ড করা হয়। এক্ষেত্রে ধরে নেওয়া হয় যে (অগত্যা বিশ্বস্ত) সুরক্ষিত ফার্মওয়্যারটি হ্যান্ডেল না করা SMC-গুলো নিরাপদে হ্যান্ডেল করতে পারে, কারণ ফার্মওয়্যারটি pVM আইসোলেশন বজায় রাখার জন্য প্রয়োজনীয় সতর্কতাগুলো বোঝে।
ভার্চুয়াল মেশিন মনিটর
crosvm হলো একটি ভার্চুয়াল মেশিন মনিটর (VMM) যা লিনাক্সের KVM ইন্টারফেসের মাধ্যমে ভার্চুয়াল মেশিনগুলো চালায়। crosvm-কে যা অনন্য করে তোলে তা হলো এর নিরাপত্তার উপর গুরুত্ব দেওয়া, যার জন্য এতে রাস্ট (Rust) প্রোগ্রামিং ভাষা ব্যবহার করা হয় এবং হোস্ট কার্নেলকে সুরক্ষিত রাখতে ভার্চুয়াল ডিভাইসগুলোর চারপাশে একটি স্যান্ডবক্স তৈরি করা হয়। crosvm সম্পর্কে আরও জানতে, এখানে এর অফিসিয়াল ডকুমেন্টেশন দেখুন।
ফাইল বর্ণনাকারী এবং ioctls
KVM, KVM API গঠনকারী ioctl-গুলোর মাধ্যমে /dev/kvm ক্যারেক্টার ডিভাইসটিকে ইউজারস্পেসের কাছে উন্মুক্ত করে। ioctl-গুলো নিম্নলিখিত বিভাগগুলোর অন্তর্ভুক্ত:
- সিস্টেম ioctl-গুলি সমগ্র KVM সাবসিস্টেমকে প্রভাবিত করে এমন গ্লোবাল অ্যাট্রিবিউটগুলি কোয়েরি ও সেট করে এবং pVM তৈরি করে।
- ভিএম ioctls এমন অ্যাট্রিবিউটগুলো কোয়েরি ও সেট করে যা ভার্চুয়াল সিপিইউ (vCPU) এবং ডিভাইস তৈরি করে, এবং একটি সম্পূর্ণ pVM-কে প্রভাবিত করে, যেমন মেমরি লেআউট এবং ভার্চুয়াল সিপিইউ (vCPU) ও ডিভাইসের সংখ্যা অন্তর্ভুক্ত করে।
- vCPU ioctl-এর মাধ্যমে একটিমাত্র ভার্চুয়াল সিপিইউ-এর কার্যক্রম নিয়ন্ত্রণকারী অ্যাট্রিবিউটগুলো কোয়েরি ও সেট করা হয়।
- ডিভাইস ioctl-এর মাধ্যমে একটিমাত্র ভার্চুয়াল ডিভাইসের কার্যক্রম নিয়ন্ত্রণকারী অ্যাট্রিবিউটগুলো কোয়েরি ও সেট করা হয়।
প্রতিটি crosvm প্রসেস একটি ভার্চুয়াল মেশিনের ঠিক একটি ইনস্ট্যান্স চালায়। এই প্রসেসটি KVM_CREATE_VM সিস্টেম ioctl ব্যবহার করে একটি VM ফাইল ডেসক্রিপ্টর তৈরি করে, যা pVM ioctl জারি করার জন্য ব্যবহার করা যেতে পারে। একটি VM FD-তে KVM_CREATE_VCPU বা KVM_CREATE_DEVICE ioctl একটি vCPU/ডিভাইস তৈরি করে এবং নতুন রিসোর্সটিকে নির্দেশকারী একটি ফাইল ডেসক্রিপ্টর ফেরত দেয়। একটি vCPU বা ডিভাইস FD-তে থাকা ioctl-গুলো সেই ডিভাইসটিকে নিয়ন্ত্রণ করতে ব্যবহার করা যেতে পারে, যা VM FD-তে থাকা ioctl ব্যবহার করে তৈরি করা হয়েছিল। vCPU-এর ক্ষেত্রে, এর মধ্যে গেস্ট কোড চালানোর মতো গুরুত্বপূর্ণ কাজটিও অন্তর্ভুক্ত থাকে।
অভ্যন্তরীণভাবে, crosvm এজ-ট্রিগারড epoll ইন্টারফেস ব্যবহার করে কার্নেলের কাছে VM-এর ফাইল ডেসক্রিপ্টরগুলো রেজিস্টার করে। এরপর যখনই কোনো ফাইল ডেসক্রিপ্টরে কোনো নতুন ইভেন্ট পেন্ডিং থাকে, কার্নেল crosvm-কে অবহিত করে।
pKVM একটি নতুন ক্যাপাবিলিটি, KVM_CAP_ARM_PROTECTED_VM যোগ করেছে, যা pVM এনভায়রনমেন্ট সম্পর্কে তথ্য পেতে এবং একটি VM-এর জন্য প্রোটেক্টেড মোড সেট আপ করতে ব্যবহার করা যেতে পারে। pVM তৈরির সময় --protected-vm ফ্ল্যাগটি পাস করা হলে, crosvm এটি ব্যবহার করে pVM ফার্মওয়্যারের জন্য উপযুক্ত পরিমাণ মেমরি কোয়েরি ও রিজার্ভ করে এবং তারপর প্রোটেক্টেড মোড চালু করে।
মেমরি বরাদ্দ
একটি ভিএমএম-এর অন্যতম প্রধান দায়িত্ব হলো ভিএম-এর মেমরি বরাদ্দ করা এবং এর মেমরি লেআউট পরিচালনা করা। crosvm একটি নির্দিষ্ট মেমরি লেআউট তৈরি করে, যা নিচের সারণিতে মোটামুটিভাবে বর্ণনা করা হয়েছে।
| সাধারণ মোডে FDT | PHYS_MEMORY_END - 0x200000 |
| মুক্ত স্থান | ... |
| রামডিস্ক | ALIGN_UP(KERNEL_END, 0x1000000) |
| কার্নেল | 0x80080000 |
| বুটলোডার | 0x80200000 |
| BIOS মোডে FDT | 0x80000000 |
| শারীরিক স্মৃতি ভিত্তি | 0x80000000 |
| পিভিএম ফার্মওয়্যার | 0x7FE00000 |
| ডিভাইস মেমরি | 0x10000 - 0x40000000 |
mmap ব্যবহার করে ফিজিক্যাল মেমরি বরাদ্দ করা হয় এবং KVM_SET_USER_MEMORY_REGION ioctl-এর মাধ্যমে VM-কে তার memslots নামক মেমরি রিজিয়নগুলো পূরণ করার জন্য মেমরি দান করা হয়। তাই, সমস্ত গেস্ট pVM মেমরি সেটিকে পরিচালনাকারী crosvm ইনস্ট্যান্সের অধীনে চলে যায় এবং হোস্টের ফ্রি মেমরি ফুরিয়ে আসতে শুরু করলে প্রসেসটি কিল (VM টার্মিনেট) হয়ে যেতে পারে। যখন একটি VM বন্ধ করা হয়, তখন হাইপারভাইজর দ্বারা মেমরিটি স্বয়ংক্রিয়ভাবে মুছে ফেলা হয় এবং হোস্ট কার্নেলে ফেরত দেওয়া হয়।
সাধারণ KVM-এর অধীনে, VMM সমস্ত গেস্ট মেমরিতে অ্যাক্সেস বজায় রাখে। pKVM-এর ক্ষেত্রে, যখন গেস্টকে মেমরি দান করা হয়, তখন তা হোস্ট ফিজিক্যাল অ্যাড্রেস স্পেস থেকে আনম্যাপ করা হয়। এর একমাত্র ব্যতিক্রম হলো সেই মেমরি যা গেস্ট স্পষ্টভাবে শেয়ার ব্যাক করে, যেমন ভার্চুও ডিভাইসের ক্ষেত্রে।
গেস্টের অ্যাড্রেস স্পেসের MMIO রিজিয়নগুলো আনম্যাপড রাখা হয়। গেস্ট কর্তৃক এই রিজিয়নগুলোতে অ্যাক্সেস ট্র্যাপ করা হয় এবং এর ফলে VM FD-তে একটি I/O ইভেন্ট ঘটে। এই মেকানিজমটি ভার্চুয়াল ডিভাইস বাস্তবায়নের জন্য ব্যবহৃত হয়। প্রোটেক্টেড মোডে, দুর্ঘটনাবশত তথ্য ফাঁসের ঝুঁকি কমাতে, গেস্টকে অবশ্যই একটি হাইপারকলের মাধ্যমে স্বীকার করতে হবে যে তার অ্যাড্রেস স্পেসের কোনো একটি রিজিয়ন MMIO-এর জন্য ব্যবহৃত হচ্ছে।
সময়সূচী
প্রতিটি ভার্চুয়াল সিপিইউ একটি POSIX থ্রেড দ্বারা প্রতিনিধিত্ব করা হয় এবং হোস্ট লিনাক্স শিডিউলার দ্বারা নির্ধারিত হয়। থ্রেডটি vCPU FD-তে KVM_RUN ioctl কল করে, যার ফলে হাইপারভাইজর গেস্ট vCPU কনটেক্সটে সুইচ করে। হোস্ট শিডিউলার গেস্ট কনটেক্সটে কাটানো সময়কে সংশ্লিষ্ট vCPU থ্রেড দ্বারা ব্যবহৃত সময় হিসাবে গণ্য করে। যখন এমন কোনো ঘটনা ঘটে যা VMM দ্বারা পরিচালনা করা আবশ্যক, যেমন I/O, ইন্টারাপ্টের সমাপ্তি, বা vCPU বন্ধ হয়ে যাওয়া, তখন KVM_RUN রিটার্ন করে। VMM ঘটনাটি পরিচালনা করে এবং আবার KVM_RUN কল করে।
KVM_RUN চলাকালীন, থ্রেডটি হোস্ট শিডিউলার দ্বারা প্রিএম্পটিবল থাকে, তবে EL2 হাইপারভাইজর কোডের এক্সিকিউশন এর ব্যতিক্রম, কারণ সেটি প্রিএম্পটিবল নয়। গেস্ট pVM-এর নিজের এই আচরণ নিয়ন্ত্রণ করার কোনো ব্যবস্থা নেই।
যেহেতু সমস্ত vCPU থ্রেডকে অন্য যেকোনো ইউজারস্পেস টাস্কের মতোই শিডিউল করা হয়, তাই সেগুলো সমস্ত স্ট্যান্ডার্ড QoS পদ্ধতির আওতাধীন থাকে। বিশেষত, প্রতিটি vCPU থ্রেডকে ফিজিক্যাল সিপিইউ-এর সাথে অ্যাফাইন করা, সিপিইউসেটে রাখা, ইউটিলাইজেশন ক্ল্যাম্পিং ব্যবহার করে বুস্ট বা ক্যাপ করা, তাদের প্রায়োরিটি/শিডিউলিং পলিসি পরিবর্তন করা এবং আরও অনেক কিছু করা যায়।
ভার্চুয়াল ডিভাইস
crosvm নিম্নলিখিত সহ বেশ কিছু ডিভাইস সমর্থন করে:
- কম্পোজিট ডিস্ক ইমেজের জন্য ভার্চিও-বিএলকে, রিড-অনলি অথবা রিড-রাইট।
- হোস্টের সাথে যোগাযোগের জন্য vhost-vsock
- ভার্চিও ট্রান্সপোর্ট হিসেবে ভার্চিও-পিসিআই
- pl030 রিয়েল টাইম ক্লক (RTC)
- ক্রমিক যোগাযোগের জন্য 16550a UART
পিভিএম ফার্মওয়্যার
pVM ফার্মওয়্যার (pvmfw) হলো একটি pVM দ্বারা সম্পাদিত প্রথম কোড, যা একটি ভৌত ডিভাইসের বুট রম-এর অনুরূপ। pvmfw-এর প্রাথমিক লক্ষ্য হলো সিকিওর বুট চালু করা এবং pVM-এর অনন্য সিক্রেটটি ডিরাইভ করা। pvmfw কোনো নির্দিষ্ট OS, যেমন মাইক্রোড্রয়েড , এর সাথে ব্যবহারের জন্য সীমাবদ্ধ নয়, যতক্ষণ পর্যন্ত OS-টি crosvm দ্বারা সমর্থিত এবং যথাযথভাবে স্বাক্ষরিত থাকে।
pvmfw বাইনারিটি একই নামের একটি ফ্ল্যাশ পার্টিশনে সংরক্ষিত থাকে এবং OTA ব্যবহার করে আপডেট করা হয়।
ডিভাইস বুট
pKVM-সক্ষম ডিভাইসের বুট পদ্ধতিতে নিম্নলিখিত ধাপগুলো যোগ করা হয়:
- অ্যান্ড্রয়েড বুটলোডার (ABL) তার পার্টিশন থেকে pvmfw মেমরিতে লোড করে এবং ইমেজটি যাচাই করে।
- ABL তার ডিভাইস আইডেন্টিফায়ার কম্পোজিশন ইঞ্জিন (DICE)-এর গোপনীয় তথ্য (কম্পাউন্ড ডিভাইস আইডেন্টিফায়ার (CDI) এবং DICE সার্টিফিকেট চেইন) একটি রুট অফ ট্রাস্ট থেকে সংগ্রহ করে।
- ABL, pvmfw-এর জন্য প্রয়োজনীয় CDI-গুলো ডিরাইভ করে এবং সেগুলোকে pvmfw বাইনারির সাথে যুক্ত করে দেয়।
- ABL, DT-তে একটি
linux,pkvm-guest-firmware-memoryসংরক্ষিত মেমরি অঞ্চল নোড যোগ করে, যা pvmfw বাইনারির অবস্থান ও আকার এবং পূর্ববর্তী ধাপে এটি দ্বারা প্রাপ্ত গোপনীয় তথ্য বর্ণনা করে। - ABL লিনাক্সের কাছে নিয়ন্ত্রণ হস্তান্তর করে এবং লিনাক্স pKVM চালু করে।
- pKVM হোস্টের স্টেজ ২ পেজ টেবিল থেকে pvmfw মেমরি অঞ্চলকে আনম্যাপ করে এবং ডিভাইস চালু থাকার পুরো সময় জুড়ে এটিকে হোস্ট (এবং গেস্ট) থেকে সুরক্ষিত রাখে।
ডিভাইস বুট হওয়ার পর, মাইক্রোড্রয়েড ডকুমেন্টের ' বুট সিকোয়েন্স ' বিভাগে বর্ণিত ধাপগুলো অনুসারে মাইক্রোড্রয়েড বুট হয়।
pVM বুট
একটি pVM তৈরি করার সময়, crosvm (বা অন্য কোনো VMM)-কে অবশ্যই একটি যথেষ্ট বড় মেমস্লট তৈরি করতে হবে, যা হাইপারভাইজর দ্বারা pvmfw ইমেজ দ্বারা পূর্ণ করা হবে। VMM-টি সেইসব রেজিস্টারের তালিকাতেও সীমাবদ্ধ, যাদের প্রাথমিক মান এটি সেট করতে পারে (প্রাইমারি vCPU-এর জন্য x0-x14, সেকেন্ডারি vCPU-গুলোর জন্য কোনোটিই নয়)। অবশিষ্ট রেজিস্টারগুলো সংরক্ষিত এবং হাইপারভাইজর-pvmfw ABI-এর অংশ।
যখন pVM চালানো হয়, তখন হাইপারভাইজর প্রথমে প্রাইমারি vCPU-এর নিয়ন্ত্রণ pvmfw-এর কাছে হস্তান্তর করে। ফার্মওয়্যার আশা করে যে crosvm একটি AVB-স্বাক্ষরিত কার্নেল (যা একটি বুটলোডার বা অন্য কোনো ইমেজ হতে পারে) এবং একটি স্বাক্ষরবিহীন FDT মেমরির নির্দিষ্ট অফসেটে লোড করবে। pvmfw AVB স্বাক্ষরটি যাচাই করে এবং সফল হলে, প্রাপ্ত FDT থেকে একটি বিশ্বস্ত ডিভাইস ট্রি তৈরি করে, মেমরি থেকে এর গোপনীয় তথ্য মুছে ফেলে এবং পেলোডের এন্ট্রি পয়েন্টে ব্রাঞ্চ করে। যদি যাচাইকরণের কোনো একটি ধাপ ব্যর্থ হয়, তাহলে ফার্মওয়্যার একটি PSCI SYSTEM_RESET হাইপারকল জারি করে।
বুট হওয়ার মধ্যবর্তী সময়ে, pVM ইনস্ট্যান্স সম্পর্কিত তথ্য একটি পার্টিশনে (virtio-blk ডিভাইস) সংরক্ষণ করা হয় এবং pvmfw-এর সিক্রেট দিয়ে এনক্রিপ্ট করা থাকে, যাতে রিবুটের পরে সিক্রেটটি সঠিক ইনস্ট্যান্সে প্রোভিশন করা হয়।