Message ID | 1423490395-22054-3-git-send-email-imammedo@redhat.com |
---|---|
State | New |
Headers | show |
On 02/09/2015 03:59 PM, Igor Mammedov wrote: > Linker table is build only once, so if later during > tables rebuild sizes of other ACPI tables change > pointers will be patched incorrectly due to wrong > offsets in linker. Resulting in guest not being able > to find ACPI tables. > Fix it by updating 'linker' table with the rest of > tables when firmware reads it. > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > --- > hw/i386/acpi-build.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c > index 5b2b017..21ea3db 100644 > --- a/hw/i386/acpi-build.c > +++ b/hw/i386/acpi-build.c > @@ -1527,6 +1527,8 @@ struct AcpiBuildState { > uint8_t patched; > PcGuestInfo *guest_info; > void *rsdp; > + ram_addr_t linker_ram; > + uint32_t linker_size; > } AcpiBuildState; > > static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) > @@ -1733,6 +1735,8 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) > memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data, > build_state->table_size); > memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp)); > + memcpy(qemu_get_ram_ptr(build_state->linker_ram), tables.linker->data, > + build_state->linker_size); > > cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram, > build_state->table_size); > @@ -1799,7 +1803,9 @@ void acpi_setup(PcGuestInfo *guest_info) > assert(build_state->table_ram != RAM_ADDR_MAX); > build_state->table_size = acpi_data_len(tables.table_data); > > - acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader", 0); > + build_state->linker_ram = > + acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); > + build_state->linker_size = acpi_data_len(tables.linker); > > fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, > tables.tcpalog->data, acpi_data_len(tables.tcpalog)); > Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
On Mon, Feb 09, 2015 at 01:59:54PM +0000, Igor Mammedov wrote: > Linker table is build only once, so if later during > tables rebuild sizes of other ACPI tables change > pointers will be patched incorrectly due to wrong > offsets in linker. Resulting in guest not being able > to find ACPI tables. > Fix it by updating 'linker' table with the rest of > tables when firmware reads it. > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > --- > hw/i386/acpi-build.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c > index 5b2b017..21ea3db 100644 > --- a/hw/i386/acpi-build.c > +++ b/hw/i386/acpi-build.c > @@ -1527,6 +1527,8 @@ struct AcpiBuildState { > uint8_t patched; > PcGuestInfo *guest_info; > void *rsdp; > + ram_addr_t linker_ram; > + uint32_t linker_size; > } AcpiBuildState; > > static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) > @@ -1733,6 +1735,8 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) > memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data, > build_state->table_size); > memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp)); > + memcpy(qemu_get_ram_ptr(build_state->linker_ram), tables.linker->data, > + build_state->linker_size); > > cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram, > build_state->table_size); OK, but it looks like linker data needs to be marked dirty as well. I'll send a patch to do this. > @@ -1799,7 +1803,9 @@ void acpi_setup(PcGuestInfo *guest_info) > assert(build_state->table_ram != RAM_ADDR_MAX); > build_state->table_size = acpi_data_len(tables.table_data); > > - acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader", 0); > + build_state->linker_ram = > + acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); > + build_state->linker_size = acpi_data_len(tables.linker); > > fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, > tables.tcpalog->data, acpi_data_len(tables.tcpalog)); > -- > 1.8.3.1
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 5b2b017..21ea3db 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1527,6 +1527,8 @@ struct AcpiBuildState { uint8_t patched; PcGuestInfo *guest_info; void *rsdp; + ram_addr_t linker_ram; + uint32_t linker_size; } AcpiBuildState; static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) @@ -1733,6 +1735,8 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data, build_state->table_size); memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp)); + memcpy(qemu_get_ram_ptr(build_state->linker_ram), tables.linker->data, + build_state->linker_size); cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram, build_state->table_size); @@ -1799,7 +1803,9 @@ void acpi_setup(PcGuestInfo *guest_info) assert(build_state->table_ram != RAM_ADDR_MAX); build_state->table_size = acpi_data_len(tables.table_data); - acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader", 0); + build_state->linker_ram = + acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); + build_state->linker_size = acpi_data_len(tables.linker); fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog));
Linker table is build only once, so if later during tables rebuild sizes of other ACPI tables change pointers will be patched incorrectly due to wrong offsets in linker. Resulting in guest not being able to find ACPI tables. Fix it by updating 'linker' table with the rest of tables when firmware reads it. Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- hw/i386/acpi-build.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)