[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.3] EFI: allow to suppress the use of runtime services



commit 151786a987757a00c378dee280d5b857b31ad16e
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Nov 13 09:56:07 2014 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Nov 13 09:56:07 2014 +0100

    EFI: allow to suppress the use of runtime services
    
    On certain systems some of the memory map entries designated for use by
    runtime services cannot be mapped (frequently due to firmware bugs). On
    others, some of the memory map entries aren't even marked for runtime
    services use, yet are being used by them. For both cases give people a
    way to suppress use of runtime services altogether.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    master commit: 5680244040d26234a43c7f884ecf98fa4928d0da
    master date: 2014-10-27 16:43:52 +0100
---
 docs/misc/xen-command-line.markdown |    7 +++
 xen/arch/x86/efi/boot.c             |   12 +++++-
 xen/arch/x86/efi/runtime.c          |   86 +++++++++++++++++++++++++---------
 3 files changed, 81 insertions(+), 24 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown 
b/docs/misc/xen-command-line.markdown
index 6e50f0a..757e46f 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -488,6 +488,13 @@ Either force retrieval of monitor EDID information via 
VESA DDC, or
 disable it (edid=no). This option should not normally be required
 except for debugging purposes.
 
+### efi-rs
+> `= <boolean>`
+
+> Default: `true`
+
+Force or disable use of EFI runtime services.
+
 ### extra\_guest\_irqs
 > `= <number>`
 
diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c
index 7eabcea..2cdf1be 100644
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -1497,6 +1497,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
*SystemTable)
     for( ; ; ); /* not reached */
 }
 
+
+static bool_t __initdata efi_rs_enable = 1;
+boolean_param("efi-rs", efi_rs_enable);
+
 #ifndef USE_SET_VIRTUAL_ADDRESS_MAP
 static __init void copy_mapping(unsigned long mfn, unsigned long end,
                                 bool_t (*is_valid)(unsigned long smfn,
@@ -1570,7 +1574,7 @@ void __init efi_init_memory(void)
                desc->PhysicalStart, desc->PhysicalStart + len - 1,
                desc->Type, desc->Attribute);
 
-        if ( !(desc->Attribute & EFI_MEMORY_RUNTIME) )
+        if ( !efi_rs_enable || !(desc->Attribute & EFI_MEMORY_RUNTIME) )
             continue;
 
         desc->VirtualStart = INVALID_VIRTUAL_ADDRESS;
@@ -1634,6 +1638,12 @@ void __init efi_init_memory(void)
         }
     }
 
+    if ( !efi_rs_enable )
+    {
+        efi_fw_vendor = NULL;
+        return;
+    }
+
 #ifdef USE_SET_VIRTUAL_ADDRESS_MAP
     efi_rs->SetVirtualAddressMap(efi_memmap_size, efi_mdesc_size,
                                  mdesc_ver, efi_memmap);
diff --git a/xen/arch/x86/efi/runtime.c b/xen/arch/x86/efi/runtime.c
index ec1b227..7787f51 100644
--- a/xen/arch/x86/efi/runtime.c
+++ b/xen/arch/x86/efi/runtime.c
@@ -51,6 +51,9 @@ unsigned long efi_rs_enter(void)
     static const u32 mxcsr = MXCSR_DEFAULT;
     unsigned long cr3 = read_cr3();
 
+    if ( !efi_l4_pgtable )
+        return 0;
+
     save_fpu_enable();
     asm volatile ( "fldcw %0" :: "m" (fcw) );
     asm volatile ( "ldmxcsr %0" :: "m" (mxcsr) );
@@ -78,6 +81,8 @@ unsigned long efi_rs_enter(void)
 
 void efi_rs_leave(unsigned long cr3)
 {
+    if ( !cr3 )
+        return;
     write_cr3(cr3);
     if ( !is_hvm_vcpu(current) && !is_idle_vcpu(current) )
     {
@@ -95,7 +100,7 @@ void efi_rs_leave(unsigned long cr3)
 
 paddr_t efi_rs_page_table(void)
 {
-    return virt_to_maddr(efi_l4_pgtable);
+    return efi_l4_pgtable ? virt_to_maddr(efi_l4_pgtable) : 0;
 }
 
 unsigned long efi_get_time(void)
@@ -104,6 +109,8 @@ unsigned long efi_get_time(void)
     EFI_STATUS status;
     unsigned long cr3 = efi_rs_enter(), flags;
 
+    if ( !cr3 )
+        return 0;
     spin_lock_irqsave(&rtc_lock, flags);
     status = efi_rs->GetTime(&time, NULL);
     spin_unlock_irqrestore(&rtc_lock, flags);
@@ -121,6 +128,8 @@ void efi_halt_system(void)
     EFI_STATUS status;
     unsigned long cr3 = efi_rs_enter();
 
+    if ( !cr3 )
+        return;
     status = efi_rs->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
     efi_rs_leave(cr3);
 
@@ -132,6 +141,8 @@ void efi_reset_system(bool_t warm)
     EFI_STATUS status;
     unsigned long cr3 = efi_rs_enter();
 
+    if ( !cr3 )
+        return;
     status = efi_rs->ResetSystem(warm ? EfiResetWarm : EfiResetCold,
                                  EFI_SUCCESS, 0, NULL);
     efi_rs_leave(cr3);
@@ -154,6 +165,8 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
     {
         unsigned long cr3 = efi_rs_enter();
 
+        if ( !cr3 )
+            return -EOPNOTSUPP;
         info->version = efi_rs->Hdr.Revision;
         efi_rs_leave(cr3);
         break;
@@ -163,6 +176,8 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
         info->cfg.nent = efi_num_ct;
         break;
     case XEN_FW_EFI_VENDOR:
+        if ( !efi_fw_vendor )
+            return -EOPNOTSUPP;
         info->vendor.revision = efi_fw_revision;
         n = info->vendor.bufsz / sizeof(*efi_fw_vendor);
         if ( !guest_handle_okay(guest_handle_cast(info->vendor.name,
@@ -285,6 +300,8 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
             return -EINVAL;
 
         cr3 = efi_rs_enter();
+        if ( !cr3 )
+            return -EOPNOTSUPP;
         spin_lock_irqsave(&rtc_lock, flags);
         status = efi_rs->GetTime(cast_time(&op->u.get_time.time), &caps);
         spin_unlock_irqrestore(&rtc_lock, flags);
@@ -305,6 +322,8 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
             return -EINVAL;
 
         cr3 = efi_rs_enter();
+        if ( !cr3 )
+            return -EOPNOTSUPP;
         spin_lock_irqsave(&rtc_lock, flags);
         status = efi_rs->SetTime(cast_time(&op->u.set_time));
         spin_unlock_irqrestore(&rtc_lock, flags);
@@ -319,6 +338,8 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
             return -EINVAL;
 
         cr3 = efi_rs_enter();
+        if ( !cr3 )
+            return -EOPNOTSUPP;
         spin_lock_irqsave(&rtc_lock, flags);
         status = efi_rs->GetWakeupTime(&enabled, &pending,
                                        cast_time(&op->u.get_wakeup_time));
@@ -341,6 +362,8 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
             return -EINVAL;
 
         cr3 = efi_rs_enter();
+        if ( !cr3 )
+            return -EOPNOTSUPP;
         spin_lock_irqsave(&rtc_lock, flags);
         status = efi_rs->SetWakeupTime(!!(op->misc &
                                           XEN_EFI_SET_WAKEUP_TIME_ENABLE),
@@ -359,7 +382,10 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
             return -EINVAL;
 
         cr3 = efi_rs_enter();
-        status = efi_rs->GetNextHighMonotonicCount(&op->misc);
+        if ( cr3 )
+            status = efi_rs->GetNextHighMonotonicCount(&op->misc);
+        else
+            rc = -EOPNOTSUPP;
         efi_rs_leave(cr3);
         break;
 
@@ -395,15 +421,20 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
             data = NULL;
 
         cr3 = efi_rs_enter();
-        status = efi_rs->GetVariable(
-            name, cast_guid(&op->u.get_variable.vendor_guid),
-            &op->misc, &size, data);
-        efi_rs_leave(cr3);
+        if ( cr3 )
+        {
+            status = efi_rs->GetVariable(
+                name, cast_guid(&op->u.get_variable.vendor_guid),
+                &op->misc, &size, data);
+            efi_rs_leave(cr3);
 
-        if ( !EFI_ERROR(status) &&
-             copy_to_guest(op->u.get_variable.data, data, size) )
-            rc = -EFAULT;
-        op->u.get_variable.size = size;
+            if ( !EFI_ERROR(status) &&
+                 copy_to_guest(op->u.get_variable.data, data, size) )
+                rc = -EFAULT;
+            op->u.get_variable.size = size;
+        }
+        else
+            rc = -EOPNOTSUPP;
 
         xfree(data);
         xfree(name);
@@ -433,9 +464,12 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
         else
         {
             cr3 = efi_rs_enter();
-            status = efi_rs->SetVariable(
-                name, cast_guid(&op->u.set_variable.vendor_guid),
-                op->misc, op->u.set_variable.size, data);
+            if ( cr3 )
+                status = efi_rs->SetVariable(
+                    name, cast_guid(&op->u.set_variable.vendor_guid),
+                    op->misc, op->u.set_variable.size, data);
+            else
+                rc = -EOPNOTSUPP;
             efi_rs_leave(cr3);
         }
 
@@ -467,15 +501,21 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
         }
 
         cr3 = efi_rs_enter();
-        status = efi_rs->GetNextVariableName(
-            &size, name.str,
-            cast_guid(&op->u.get_next_variable_name.vendor_guid));
-        efi_rs_leave(cr3);
+        if ( cr3 )
+        {
+            status = efi_rs->GetNextVariableName(
+                &size, name.str,
+                cast_guid(&op->u.get_next_variable_name.vendor_guid));
+            efi_rs_leave(cr3);
 
-        if ( !EFI_ERROR(status) &&
-             copy_to_guest(op->u.get_next_variable_name.name, name.raw, size) )
-            rc = -EFAULT;
-        op->u.get_next_variable_name.size = size;
+            if ( !EFI_ERROR(status) &&
+                 copy_to_guest(op->u.get_next_variable_name.name,
+                               name.raw, size) )
+                rc = -EFAULT;
+            op->u.get_next_variable_name.size = size;
+        }
+        else
+            rc = -EOPNOTSUPP;
 
         xfree(name.raw);
     }
@@ -512,7 +552,7 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
         }
 
         cr3 = efi_rs_enter();
-        if ( (efi_rs->Hdr.Revision >> 16) < 2 )
+        if ( !cr3 || (efi_rs->Hdr.Revision >> 16) < 2 )
         {
             efi_rs_leave(cr3);
             return -EOPNOTSUPP;
@@ -531,7 +571,7 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
             return -EINVAL;
 
         cr3 = efi_rs_enter();
-        if ( (efi_rs->Hdr.Revision >> 16) < 2 )
+        if ( !cr3 || (efi_rs->Hdr.Revision >> 16) < 2 )
         {
             efi_rs_leave(cr3);
             return -EOPNOTSUPP;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.3

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.