39
39
#include "qemu/config-file.h"
40
40
#include "qemu/cutils.h"
41
41
#include "qapi/error.h"
42
+ #include "hw/acpi/aml-build.h"
42
43
43
44
#define FW_CFG_FILE_SLOTS_DFLT 0x20
44
45
@@ -610,6 +611,55 @@ bool fw_cfg_dma_enabled(void *opaque)
610
611
return s -> dma_enabled ;
611
612
}
612
613
614
+ static bool fw_cfg_acpi_mr_restore (void * opaque )
615
+ {
616
+ FWCfgState * s = opaque ;
617
+ bool mr_aligned ;
618
+
619
+ mr_aligned = QEMU_IS_ALIGNED (s -> table_mr_size , qemu_real_host_page_size ) &&
620
+ QEMU_IS_ALIGNED (s -> linker_mr_size , qemu_real_host_page_size ) &&
621
+ QEMU_IS_ALIGNED (s -> rsdp_mr_size , qemu_real_host_page_size );
622
+ return s -> acpi_mr_restore && !mr_aligned ;
623
+ }
624
+
625
+ static void fw_cfg_update_mr (FWCfgState * s , uint16_t key , size_t size )
626
+ {
627
+ MemoryRegion * mr ;
628
+ ram_addr_t offset ;
629
+ int arch = !!(key & FW_CFG_ARCH_LOCAL );
630
+ void * ptr ;
631
+
632
+ key &= FW_CFG_ENTRY_MASK ;
633
+ assert (key < fw_cfg_max_entry (s ));
634
+
635
+ ptr = s -> entries [arch ][key ].data ;
636
+ mr = memory_region_from_host (ptr , & offset );
637
+
638
+ memory_region_ram_resize (mr , size , & error_abort );
639
+ }
640
+
641
+ static int fw_cfg_acpi_mr_restore_post_load (void * opaque , int version_id )
642
+ {
643
+ FWCfgState * s = opaque ;
644
+ int i , index ;
645
+
646
+ assert (s -> files );
647
+
648
+ index = be32_to_cpu (s -> files -> count );
649
+
650
+ for (i = 0 ; i < index ; i ++ ) {
651
+ if (!strcmp (s -> files -> f [i ].name , ACPI_BUILD_TABLE_FILE )) {
652
+ fw_cfg_update_mr (s , FW_CFG_FILE_FIRST + i , s -> table_mr_size );
653
+ } else if (!strcmp (s -> files -> f [i ].name , ACPI_BUILD_LOADER_FILE )) {
654
+ fw_cfg_update_mr (s , FW_CFG_FILE_FIRST + i , s -> linker_mr_size );
655
+ } else if (!strcmp (s -> files -> f [i ].name , ACPI_BUILD_RSDP_FILE )) {
656
+ fw_cfg_update_mr (s , FW_CFG_FILE_FIRST + i , s -> rsdp_mr_size );
657
+ }
658
+ }
659
+
660
+ return 0 ;
661
+ }
662
+
613
663
static const VMStateDescription vmstate_fw_cfg_dma = {
614
664
.name = "fw_cfg/dma" ,
615
665
.needed = fw_cfg_dma_enabled ,
@@ -619,6 +669,20 @@ static const VMStateDescription vmstate_fw_cfg_dma = {
619
669
},
620
670
};
621
671
672
+ static const VMStateDescription vmstate_fw_cfg_acpi_mr = {
673
+ .name = "fw_cfg/acpi_mr" ,
674
+ .version_id = 1 ,
675
+ .minimum_version_id = 1 ,
676
+ .needed = fw_cfg_acpi_mr_restore ,
677
+ .post_load = fw_cfg_acpi_mr_restore_post_load ,
678
+ .fields = (VMStateField []) {
679
+ VMSTATE_UINT64 (table_mr_size , FWCfgState ),
680
+ VMSTATE_UINT64 (linker_mr_size , FWCfgState ),
681
+ VMSTATE_UINT64 (rsdp_mr_size , FWCfgState ),
682
+ VMSTATE_END_OF_LIST ()
683
+ },
684
+ };
685
+
622
686
static const VMStateDescription vmstate_fw_cfg = {
623
687
.name = "fw_cfg" ,
624
688
.version_id = 2 ,
@@ -631,6 +695,7 @@ static const VMStateDescription vmstate_fw_cfg = {
631
695
},
632
696
.subsections = (const VMStateDescription * []) {
633
697
& vmstate_fw_cfg_dma ,
698
+ & vmstate_fw_cfg_acpi_mr ,
634
699
NULL ,
635
700
}
636
701
};
@@ -815,6 +880,23 @@ static struct {
815
880
#define FW_CFG_ORDER_OVERRIDE_LAST 200
816
881
};
817
882
883
+ /*
884
+ * Any sub-page size update to these table MRs will be lost during migration,
885
+ * as we use aligned size in ram_load_precopy() -> qemu_ram_resize() path.
886
+ * In order to avoid the inconsistency in sizes save them seperately and
887
+ * migrate over in vmstate post_load().
888
+ */
889
+ static void fw_cfg_acpi_mr_save (FWCfgState * s , const char * filename , size_t len )
890
+ {
891
+ if (!strcmp (filename , ACPI_BUILD_TABLE_FILE )) {
892
+ s -> table_mr_size = len ;
893
+ } else if (!strcmp (filename , ACPI_BUILD_LOADER_FILE )) {
894
+ s -> linker_mr_size = len ;
895
+ } else if (!strcmp (filename , ACPI_BUILD_RSDP_FILE )) {
896
+ s -> rsdp_mr_size = len ;
897
+ }
898
+ }
899
+
818
900
static int get_fw_cfg_order (FWCfgState * s , const char * name )
819
901
{
820
902
int i ;
@@ -914,6 +996,7 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
914
996
trace_fw_cfg_add_file (s , index , s -> files -> f [index ].name , len );
915
997
916
998
s -> files -> count = cpu_to_be32 (count + 1 );
999
+ fw_cfg_acpi_mr_save (s , filename , len );
917
1000
}
918
1001
919
1002
void fw_cfg_add_file (FWCfgState * s , const char * filename ,
@@ -937,6 +1020,7 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
937
1020
ptr = fw_cfg_modify_bytes_read (s , FW_CFG_FILE_FIRST + i ,
938
1021
data , len );
939
1022
s -> files -> f [i ].size = cpu_to_be32 (len );
1023
+ fw_cfg_acpi_mr_save (s , filename , len );
940
1024
return ptr ;
941
1025
}
942
1026
}
@@ -973,7 +1057,10 @@ static void fw_cfg_machine_ready(struct Notifier *n, void *data)
973
1057
qemu_register_reset (fw_cfg_machine_reset , s );
974
1058
}
975
1059
976
-
1060
+ static Property fw_cfg_properties [] = {
1061
+ DEFINE_PROP_BOOL ("acpi-mr-restore" , FWCfgState , acpi_mr_restore , true),
1062
+ DEFINE_PROP_END_OF_LIST (),
1063
+ };
977
1064
978
1065
static void fw_cfg_common_realize (DeviceState * dev , Error * * errp )
979
1066
{
@@ -1097,6 +1184,8 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data)
1097
1184
1098
1185
dc -> reset = fw_cfg_reset ;
1099
1186
dc -> vmsd = & vmstate_fw_cfg ;
1187
+
1188
+ device_class_set_props (dc , fw_cfg_properties );
1100
1189
}
1101
1190
1102
1191
static const TypeInfo fw_cfg_info = {
0 commit comments