• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::cell::RefCell;
6 use std::collections::BTreeMap;
7 use std::fs::File;
8 use std::fs::OpenOptions;
9 use std::os::unix::fs::FileExt;
10 use std::rc::Rc;
11 
12 use anyhow::Context;
13 use arch::MsrAction;
14 use arch::MsrConfig;
15 use arch::MsrExitHandlerError;
16 use arch::MsrFilter;
17 use arch::MsrRWType;
18 use arch::MsrValueFrom;
19 use base::debug;
20 use base::error;
21 use remain::sorted;
22 use thiserror::Error as ThisError;
23 
24 #[sorted]
25 #[derive(ThisError, Debug)]
26 pub enum Error {
27     #[error("Unable to open host msr file: {0}")]
28     HostMsrGetError(anyhow::Error),
29     #[error("Unable to get metadata of dev file for msr: {0}")]
30     HostMsrGetMetadataError(std::io::Error),
31     #[error("Unable to read host msr: {0}")]
32     HostMsrReadError(std::io::Error),
33     #[error("Unable to set permissions of dev file for msr: {0}")]
34     HostMsrSetPermsError(std::io::Error),
35     #[error("Unable to write host msr: {0}")]
36     HostMsrWriteError(std::io::Error),
37     #[error("Not set msr action parameter")]
38     InvalidAction,
39 }
40 
41 pub type Result<T> = std::result::Result<T, Error>;
42 
43 /// Wrap for userspace MSR file descriptor (/dev/cpu/*/msr).
44 pub struct MsrDevFile {
45     dev_msr: File,
46 }
47 
48 impl MsrDevFile {
49     /// Create a new MSR file descriptor.
50     ///
51     /// "Passthrough" handler will create file descriptor with both read and write
52     /// permissions. MsrHandlers controls read/write with MsrRWType. This avoids
53     /// the corner case that some MSRs are read-only while other MSRs need write
54     /// permission.
55     /// "Emulate" handler will create read-only file descriptor. This read-only
56     /// descriptor will only be used once to initialize MSR value and "Emulate"
57     /// handler won't store its descriptor at MsrHandlers level.
new(cpu_id: usize, read_only: bool) -> Result<Self>58     fn new(cpu_id: usize, read_only: bool) -> Result<Self> {
59         let filename = format!("/dev/cpu/{}/msr", cpu_id);
60         let dev_msr = OpenOptions::new()
61             .read(true)
62             .write(!read_only)
63             .open(&filename)
64             .context(format!("Cannot open {}, are you root?", filename))
65             .map_err(Error::HostMsrGetError)?;
66         Ok(MsrDevFile { dev_msr })
67     }
68 
read(&self, index: u32) -> Result<u64>69     fn read(&self, index: u32) -> Result<u64> {
70         let mut data = [0; 8];
71         self.dev_msr
72             .read_exact_at(&mut data, index.into())
73             .map_err(Error::HostMsrReadError)?;
74         Ok(u64::from_ne_bytes(data))
75     }
76 
77     // In fact, only "passthrough" will write into MSR file.
write(&self, index: u32, data: u64) -> Result<()>78     fn write(&self, index: u32, data: u64) -> Result<()> {
79         self.dev_msr
80             .write_all_at(&data.to_ne_bytes(), index.into())
81             .map_err(Error::HostMsrWriteError)?;
82         Ok(())
83     }
84 }
85 
86 /// Wrap for general RDMSR/WRMSR handling.
87 ///
88 /// Each specific handler needs to implement this trait.
89 pub trait MsrHandling {
read(&self) -> Result<u64>90     fn read(&self) -> Result<u64>;
91     // For "emulate" handler, it need to update MSR value which is stored in
92     // `msr_data` of MsrEmulate. So declare `self` as mutable.
write(&mut self, data: u64) -> Result<()>93     fn write(&mut self, data: u64) -> Result<()>;
94 }
95 
96 type MsrFileType = Rc<RefCell<BTreeMap<usize /* vcpu */, Rc<MsrDevFile>>>>;
97 
98 /// MsrPassthroughHandler - passthrough handler that will handle RDMSR/WRMSR
99 ///                         by reading/writing MSR file directly.
100 /// For RDMSR, this handler will give Guest the current MSR value on Host.
101 /// For WRMSR, this handler will directly pass the change desired by the Guest
102 /// to the host, and expect the change to take effect on the MSR of the host.
103 struct MsrPassthroughHandler {
104     /// MSR index.
105     index: u32,
106     /// MSR source CPU, CPU 0 or running CPU.
107     from: MsrValueFrom,
108     /// Reference of MSR file descriptors.
109     msr_file: MsrFileType,
110 }
111 
112 impl MsrPassthroughHandler {
new(index: u32, msr_config: &MsrConfig, msr_file: MsrFileType) -> Result<Self>113     fn new(index: u32, msr_config: &MsrConfig, msr_file: MsrFileType) -> Result<Self> {
114         let pass = MsrPassthroughHandler {
115             index,
116             from: msr_config.from,
117             msr_file,
118         };
119         pass.get_msr_dev()?;
120         Ok(pass)
121     }
122 
123     /// A helper interface to get MSR file descriptor.
get_msr_dev(&self) -> Result<Rc<MsrDevFile>>124     fn get_msr_dev(&self) -> Result<Rc<MsrDevFile>> {
125         let cpu_id = self.from.get_cpu_id();
126         // First, check if the descriptor is stored before.
127         if let Some(dev_msr) = self.msr_file.borrow().get(&cpu_id) {
128             return Ok(Rc::clone(dev_msr));
129         }
130 
131         // If descriptor isn't found, create new one.
132         let new_dev_msr = Rc::new(MsrDevFile::new(cpu_id, false)?);
133         // Note: For MsrValueFrom::RWFromRunningCPU case, just store
134         // the new descriptor and don't remove the previous.
135         // This is for convenience, since the most decriptor number is
136         // same as Host CPU count.
137         self.msr_file
138             .borrow_mut()
139             .insert(cpu_id, Rc::clone(&new_dev_msr));
140         Ok(new_dev_msr)
141     }
142 }
143 
144 impl MsrHandling for MsrPassthroughHandler {
read(&self) -> Result<u64>145     fn read(&self) -> Result<u64> {
146         let index = self.index;
147         self.get_msr_dev()?.read(index)
148     }
149 
write(&mut self, data: u64) -> Result<()>150     fn write(&mut self, data: u64) -> Result<()> {
151         let index = self.index;
152         self.get_msr_dev()?.write(index, data)
153     }
154 }
155 
156 /// MsrPassthroughHandler - emulate handler that will handle RDMSR/WRMSR
157 ///                         with a dummy MSR value other than access to real
158 ///                         MSR.
159 /// This Handler will initialize a value(`msr_data`) with the corresponding
160 /// Host MSR value, then handle the RDMSR/WRMSR based on this "value".
161 ///
162 /// For RDMSR, this handler will give Guest the stored `msr_data`.
163 /// For WRMSR, this handler will directly change `msr_data` without the
164 /// modification on real Host MSR. The change will not take effect on the
165 /// real MSR of Host.
166 ///
167 /// 'emulate' Handler is used in the case, that some driver need to control
168 /// MSR and user just wants to make WRMSR successful and doesn't care about
169 /// if WRMSR really works. This handlers make Guest's control of CPU not
170 /// affect the host
171 struct MsrEmulateHandler {
172     /// Only initialize msr_data with MSR source pCPU, and will not update
173     /// msr value changes on host cpu into msr_data.
174     msr_data: u64,
175 }
176 
177 impl MsrEmulateHandler {
new(index: u32, msr_config: &MsrConfig, msr_file: &MsrFileType) -> Result<Self>178     fn new(index: u32, msr_config: &MsrConfig, msr_file: &MsrFileType) -> Result<Self> {
179         let cpu_id = msr_config.from.get_cpu_id();
180         let msr_data: u64 = if let Some(dev_msr) = msr_file.borrow().get(&cpu_id) {
181             dev_msr.read(index)?
182         } else {
183             // Don't allow to write. Only read the value to initialize
184             // `msr_data` and won't store in MsrHandlers level.
185             MsrDevFile::new(cpu_id, true)?.read(index)?
186         };
187 
188         Ok(MsrEmulateHandler { msr_data })
189     }
190 }
191 
192 impl MsrHandling for MsrEmulateHandler {
read(&self) -> Result<u64>193     fn read(&self) -> Result<u64> {
194         Ok(self.msr_data)
195     }
196 
write(&mut self, data: u64) -> Result<()>197     fn write(&mut self, data: u64) -> Result<()> {
198         self.msr_data = data;
199         Ok(())
200     }
201 }
202 
203 /// MSR handler configuration. Per-cpu.
204 #[derive(Default)]
205 pub struct MsrHandlers {
206     /// Store read/write permissions to control read/write brfore calling
207     /// MsrHandling trait.
208     pub handler: BTreeMap<u32, (MsrRWType, Rc<RefCell<Box<dyn MsrHandling>>>)>,
209     /// Store file descriptor here to avoid cache duplicate descriptors
210     /// for each MSR.
211     /// Only collect descriptor of 'passthrough' handler, since 'emulate'
212     /// uses descriptor only once during initialization.
213     pub msr_file: MsrFileType,
214 }
215 
216 impl MsrHandlers {
new() -> Self217     pub fn new() -> Self {
218         MsrHandlers {
219             ..Default::default()
220         }
221     }
222 
read(&self, index: u32) -> Option<u64>223     pub fn read(&self, index: u32) -> Option<u64> {
224         if let Some((rw_type, handler)) = self.handler.get(&index) {
225             // It's not error. This means user does't want to handle
226             // RDMSR. Just log it.
227             if matches!(rw_type, MsrRWType::WriteOnly) {
228                 debug!("RDMSR is not allowed for msr: {:#x}", index);
229                 return None;
230             }
231 
232             match handler.borrow().read() {
233                 Ok(data) => Some(data),
234                 Err(e) => {
235                     error!("MSR host read failed {:#x} {:?}", index, e);
236                     None
237                 }
238             }
239         } else {
240             None
241         }
242     }
243 
write(&self, index: u32, data: u64) -> Option<()>244     pub fn write(&self, index: u32, data: u64) -> Option<()> {
245         if let Some((rw_type, handler)) = self.handler.get(&index) {
246             // It's not error. This means user does't want to handle
247             // WRMSR. Just log it.
248             if matches!(rw_type, MsrRWType::ReadOnly) {
249                 debug!("WRMSR is not allowed for msr: {:#x}", index);
250                 return None;
251             }
252 
253             match handler.borrow_mut().write(data) {
254                 Ok(_) => Some(()),
255                 Err(e) => {
256                     error!("MSR host write failed {:#x} {:?}", index, e);
257                     None
258                 }
259             }
260         } else {
261             None
262         }
263     }
264 
add_handler( &mut self, index: u32, msr_config: MsrConfig, cpu_id: usize, ) -> std::result::Result<(), MsrExitHandlerError>265     pub fn add_handler(
266         &mut self,
267         index: u32,
268         msr_config: MsrConfig,
269         cpu_id: usize,
270     ) -> std::result::Result<(), MsrExitHandlerError> {
271         match msr_config.action {
272             MsrAction::MsrPassthrough => {
273                 let msr_handler: Rc<RefCell<Box<dyn MsrHandling>>> =
274                     match MsrPassthroughHandler::new(index, &msr_config, Rc::clone(&self.msr_file))
275                     {
276                         Ok(r) => Rc::new(RefCell::new(Box::new(r))),
277                         Err(e) => {
278                             error!(
279                                 "failed to create MSR passthrough handler for vcpu {}: {:#}",
280                                 cpu_id, e
281                             );
282                             return Err(MsrExitHandlerError::HandlerCreateFailed);
283                         }
284                     };
285                 self.handler
286                     .insert(index, (msr_config.rw_type, msr_handler));
287             }
288             MsrAction::MsrEmulate => {
289                 let msr_handler: Rc<RefCell<Box<dyn MsrHandling>>> =
290                     match MsrEmulateHandler::new(index, &msr_config, &self.msr_file) {
291                         Ok(r) => Rc::new(RefCell::new(Box::new(r))),
292                         Err(e) => {
293                             error!(
294                                 "failed to create MSR emulate handler for vcpu {}: {:#}",
295                                 cpu_id, e
296                             );
297                             return Err(MsrExitHandlerError::HandlerCreateFailed);
298                         }
299                     };
300                 self.handler
301                     .insert(index, (msr_config.rw_type, msr_handler));
302             }
303         };
304         Ok(())
305     }
306 }
307 
308 /// get override msr list
get_override_msr_list( msr_list: &BTreeMap<u32, MsrConfig>, ) -> ( Vec<u32>, Vec<u32>, )309 pub fn get_override_msr_list(
310     msr_list: &BTreeMap<u32, MsrConfig>,
311 ) -> (
312     Vec<u32>, /* read override */
313     Vec<u32>, /* write override */
314 ) {
315     let mut rd_msrs: Vec<u32> = Vec::new();
316     let mut wr_msrs: Vec<u32> = Vec::new();
317 
318     for (index, config) in msr_list.iter() {
319         if config.filter == MsrFilter::Override {
320             match config.rw_type {
321                 MsrRWType::ReadOnly => {
322                     rd_msrs.push(*index);
323                 }
324                 MsrRWType::WriteOnly => {
325                     wr_msrs.push(*index);
326                 }
327                 MsrRWType::ReadWrite => {
328                     rd_msrs.push(*index);
329                     wr_msrs.push(*index);
330                 }
331             }
332         }
333     }
334     (rd_msrs, wr_msrs)
335 }
336