mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
vtd: Reinstate ACPI DMAR on system shutdown or S3/S4/S5.
Signed-off-by: Keir Fraser <keir@xen.org>
This commit is contained in:
1 parent
00b8b6c5db
commit
6c298ecc1f
6 files changed
+42
-16
No files matched your search
@@ -12,7 +12,6 @@
|
||||
|
||||
#include <xen/config.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <xen/acpi.h>
|
||||
#include <xen/errno.h>
|
||||
#include <xen/iocap.h>
|
||||
@@ -140,6 +139,8 @@ static int enter_state(u32 state)
|
||||
|
||||
freeze_domains();
|
||||
|
||||
acpi_dmar_reinstate();
|
||||
|
||||
if ( (error = disable_nonboot_cpus()) )
|
||||
goto enable_cpu;
|
||||
|
||||
@@ -208,6 +209,7 @@ static int enter_state(u32 state)
|
||||
mtrr_aps_sync_begin();
|
||||
enable_nonboot_cpus();
|
||||
mtrr_aps_sync_end();
|
||||
acpi_dmar_zap();
|
||||
thaw_domains();
|
||||
spin_unlock(&pm_lock);
|
||||
return error;
|
||||
|
||||
@@ -309,6 +309,8 @@ void machine_restart(unsigned int delay_millisecs)
|
||||
console_start_sync();
|
||||
spin_debug_disable();
|
||||
|
||||
acpi_dmar_reinstate();
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
/* Ensure we are the boot CPU. */
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xen/sched.h>
|
||||
#include <xen/domain_page.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <xen/acpi.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/processor.h>
|
||||
@@ -475,13 +476,7 @@ int __init tboot_parse_dmar_table(acpi_table_handler dmar_handler)
|
||||
|
||||
/* acpi_parse_dmar() zaps APCI DMAR signature in TXT heap table */
|
||||
/* but dom0 will read real table, so must zap it there too */
|
||||
dmar_table = NULL;
|
||||
acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table);
|
||||
if ( dmar_table != NULL )
|
||||
{
|
||||
dmar_table->signature[0] = 'X';
|
||||
dmar_table->checksum -= 'X'-'D';
|
||||
}
|
||||
acpi_dmar_zap();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
+1
-8
@@ -203,20 +203,13 @@ crash_xen_info_t *kexec_crash_save_info(void)
|
||||
return out;
|
||||
}
|
||||
|
||||
static int acpi_dmar_reinstate(struct acpi_table_header *table)
|
||||
{
|
||||
table->signature[0] = 'D';
|
||||
table->checksum += 'X'-'D';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kexec_common_shutdown(void)
|
||||
{
|
||||
watchdog_disable();
|
||||
console_start_sync();
|
||||
spin_debug_disable();
|
||||
one_cpu_only();
|
||||
acpi_table_parse(ACPI_SIG_DMAR, acpi_dmar_reinstate);
|
||||
acpi_dmar_reinstate();
|
||||
}
|
||||
|
||||
void kexec_crash(void)
|
||||
|
||||
@@ -771,3 +771,34 @@ int __init acpi_dmar_init(void)
|
||||
{
|
||||
return parse_dmar_table(acpi_parse_dmar);
|
||||
}
|
||||
|
||||
static struct acpi_table_header *get_dmar(void)
|
||||
{
|
||||
struct acpi_table_header *dmar_table = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
/* Disabling IRQs avoids cross-CPU TLB flush in map_pages_to_xen(). */
|
||||
local_irq_save(flags);
|
||||
acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table);
|
||||
local_irq_restore(flags);
|
||||
|
||||
return dmar_table;
|
||||
}
|
||||
|
||||
void acpi_dmar_reinstate(void)
|
||||
{
|
||||
struct acpi_table_header *dmar_table = get_dmar();
|
||||
if ( dmar_table == NULL )
|
||||
return;
|
||||
dmar_table->signature[0] = 'D';
|
||||
dmar_table->checksum += 'X'-'D';
|
||||
}
|
||||
|
||||
void acpi_dmar_zap(void)
|
||||
{
|
||||
struct acpi_table_header *dmar_table = get_dmar();
|
||||
if ( dmar_table == NULL )
|
||||
return;
|
||||
dmar_table->signature[0] = 'X';
|
||||
dmar_table->checksum -= 'X'-'D';
|
||||
}
|
||||
@@ -444,4 +444,7 @@ extern int pnpacpi_disabled;
|
||||
|
||||
void acpi_reboot(void);
|
||||
|
||||
void acpi_dmar_zap(void);
|
||||
void acpi_dmar_reinstate(void);
|
||||
|
||||
#endif /*_LINUX_ACPI_H*/
|
||||