1 // Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 use std::io::{Read, Seek, SeekFrom};
6 use std::os::fd::AsFd;
7 use std::result;
8
9 use thiserror::Error;
10 use vm_memory::{GuestAddress, GuestMemory};
11
12 /// Errors thrown while loading UEFI binary
13 #[derive(Debug, Error)]
14 pub enum Error {
15 /// Unable to seek to UEFI image start.
16 #[error("Unable to seek to UEFI image start")]
17 SeekUefiStart,
18 /// Unable to seek to UEFI image end.
19 #[error("Unable to seek to UEFI image end")]
20 SeekUefiEnd,
21 /// UEFI image too big.
22 #[error("UEFI image too big")]
23 UefiTooBig,
24 /// Unable to read UEFI image
25 #[error("Unable to read UEFI image")]
26 ReadUefiImage,
27 }
28 type Result<T> = result::Result<T, Error>;
29
load_uefi<F, M: GuestMemory>( guest_mem: &M, guest_addr: GuestAddress, uefi_image: &mut F, ) -> Result<()> where F: Read + Seek + AsFd,30 pub fn load_uefi<F, M: GuestMemory>(
31 guest_mem: &M,
32 guest_addr: GuestAddress,
33 uefi_image: &mut F,
34 ) -> Result<()>
35 where
36 F: Read + Seek + AsFd,
37 {
38 let uefi_size = uefi_image
39 .seek(SeekFrom::End(0))
40 .map_err(|_| Error::SeekUefiEnd)? as usize;
41
42 // edk2 image on virtual platform is smaller than 3M
43 if uefi_size > 0x300000 {
44 return Err(Error::UefiTooBig);
45 }
46 uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?;
47 guest_mem
48 .read_exact_volatile_from(guest_addr, &mut uefi_image.as_fd(), uefi_size)
49 .map_err(|_| Error::ReadUefiImage)
50 }
51