All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT
@ 2014-04-06  9:49 Michael Tokarev
  2014-04-06 10:53 ` Michael S. Tsirkin
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Tokarev @ 2014-04-06  9:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Tokarev

When building RSDT table, pick OEM ID fields from uer-supplied SLIC
table instead of using hard-coded QEMU defaults.  This way, say,
OEM version of Windows7 can be run inside qemu using the same OEM
activation as on bare metal, by pointing at system firmware:

  -acpitable file=/sys/firmware/acpi/tables/SLIC

Windows7 requires that OEM ID in RSDT matches those in SLIC to
consider SLIC to be valid.

This is somewhat hackish approach, but it works fairy well in
practice.

I'm not asking to apply this directly, but instead am trying to
show what's needed to get win to work.  Maybe a new command-line
option for that will do, maybe something else.

Thanks,

/mjt

---
 hw/acpi/core.c       |    5 +++++
 hw/i386/acpi-build.c |    7 +++++++
 2 files changed, 12 insertions(+)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 79414b4..a8a3f26 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -53,6 +53,7 @@ static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
 
 char unsigned *acpi_tables;
 size_t acpi_tables_len;
+size_t slic_table_offset;
 
 static QemuOptsList qemu_acpi_opts = {
     .name = "acpi",
@@ -226,6 +227,10 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
     /* recalculate checksum */
     ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
                                       ACPI_TABLE_PFX_SIZE, acpi_payload_size);
+
+    if (memcmp(ext_hdr->sig, "SLIC", 4) == 0) {
+       slic_table_offset = acpi_tables_len - acpi_payload_size;
+    }
 }
 
 void acpi_table_add(const QemuOpts *opts, Error **errp)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a5d3fbf..9e0e16a 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -224,6 +224,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
 #define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
 #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
 
+extern size_t slic_table_offset;
+
 static void
 build_header(GArray *linker, GArray *table_data,
              AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
@@ -237,6 +239,11 @@ build_header(GArray *linker, GArray *table_data,
     h->oem_revision = cpu_to_le32(1);
     memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
     h->asl_compiler_revision = cpu_to_le32(1);
+    if (memcmp(sig, "RSDT", 4) == 0 && slic_table_offset) {
+      /* for win7: OEM info in RSDT and SLIC should be the same */
+      AcpiTableHeader *s = (AcpiTableHeader *)(acpi_tables + slic_table_offset);
+      memcpy(h->oem_id, s->oem_id, 6 + 4 + 4);
+    }
     h->checksum = 0;
     /* Checksum to be filled in by Guest linker */
     bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT
  2014-04-06  9:49 [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT Michael Tokarev
@ 2014-04-06 10:53 ` Michael S. Tsirkin
  2014-04-06 11:08   ` Michael Tokarev
  0 siblings, 1 reply; 7+ messages in thread
From: Michael S. Tsirkin @ 2014-04-06 10:53 UTC (permalink / raw)
  To: Michael Tokarev; +Cc: qemu-devel

On Sun, Apr 06, 2014 at 01:49:11PM +0400, Michael Tokarev wrote:
> When building RSDT table, pick OEM ID fields from uer-supplied SLIC
> table instead of using hard-coded QEMU defaults.  This way, say,
> OEM version of Windows7 can be run inside qemu using the same OEM
> activation as on bare metal, by pointing at system firmware:
> 
>   -acpitable file=/sys/firmware/acpi/tables/SLIC

Right, so this doesn't work in 1.7 either, right?
It's not a regression?

> Windows7 requires that OEM ID in RSDT matches those in SLIC to
> consider SLIC to be valid.

Which fields need to match which, exactly?

> This is somewhat hackish approach, but it works fairy well in
> practice.
> 
> I'm not asking to apply this directly, but instead am trying to
> show what's needed to get win to work.  Maybe a new command-line
> option for that will do, maybe something else.
> 
> Thanks,
> 
> /mjt

I think it's kind of reasonable - seems better than
adding more flags - but I'd like to avoid
poking at acpi_tables array in acpi-build.c

How about an API to set/query OEM ID?


> ---
>  hw/acpi/core.c       |    5 +++++
>  hw/i386/acpi-build.c |    7 +++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index 79414b4..a8a3f26 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -53,6 +53,7 @@ static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
>  
>  char unsigned *acpi_tables;
>  size_t acpi_tables_len;
> +size_t slic_table_offset;
>  
>  static QemuOptsList qemu_acpi_opts = {
>      .name = "acpi",
> @@ -226,6 +227,10 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
>      /* recalculate checksum */
>      ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
>                                        ACPI_TABLE_PFX_SIZE, acpi_payload_size);
> +
> +    if (memcmp(ext_hdr->sig, "SLIC", 4) == 0) {
> +       slic_table_offset = acpi_tables_len - acpi_payload_size;
> +    }
>  }
>  
>  void acpi_table_add(const QemuOpts *opts, Error **errp)
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index a5d3fbf..9e0e16a 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -224,6 +224,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
>  #define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
>  #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
>  
> +extern size_t slic_table_offset;
> +
>  static void
>  build_header(GArray *linker, GArray *table_data,
>               AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
> @@ -237,6 +239,11 @@ build_header(GArray *linker, GArray *table_data,
>      h->oem_revision = cpu_to_le32(1);
>      memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
>      h->asl_compiler_revision = cpu_to_le32(1);
> +    if (memcmp(sig, "RSDT", 4) == 0 && slic_table_offset) {
> +      /* for win7: OEM info in RSDT and SLIC should be the same */
> +      AcpiTableHeader *s = (AcpiTableHeader *)(acpi_tables + slic_table_offset);
> +      memcpy(h->oem_id, s->oem_id, 6 + 4 + 4);


what does 6 + 4 +4 mean?
I see:
    uint8_t  oem_id [6];             /* OEM identification */ \
    uint8_t  oem_table_id [8];       /* OEM table identification */ \
    uint32_t oem_revision;           /* OEM revision number */ \

Do table id have to match? It seems a bit wrong to have two tables
with the same id.

> +    }
>      h->checksum = 0;
>      /* Checksum to be filled in by Guest linker */
>      bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
> -- 
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT
  2014-04-06 10:53 ` Michael S. Tsirkin
@ 2014-04-06 11:08   ` Michael Tokarev
  2014-04-06 12:21     ` Laszlo Ersek
  2014-04-06 12:25     ` Michael S. Tsirkin
  0 siblings, 2 replies; 7+ messages in thread
From: Michael Tokarev @ 2014-04-06 11:08 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: qemu-devel

06.04.2014 14:53, Michael S. Tsirkin wrote:
> On Sun, Apr 06, 2014 at 01:49:11PM +0400, Michael Tokarev wrote:
>> When building RSDT table, pick OEM ID fields from uer-supplied SLIC
>> table instead of using hard-coded QEMU defaults.  This way, say,
>> OEM version of Windows7 can be run inside qemu using the same OEM
>> activation as on bare metal, by pointing at system firmware:
>>
>>   -acpitable file=/sys/firmware/acpi/tables/SLIC
> 
> Right, so this doesn't work in 1.7 either, right?
> It's not a regression?

It doesn't work in 1.7 too, but it is not a regression.
Before 1.7 I used a very similar approach patching seabios,
for several years.  Here's one of the first versions of this
approach -- http://lists.gnu.org/archive/html/qemu-devel/2011-03/msg03080.html

I used this approach since that time locally.
For 1.7 I used seabios without acpi table loading interface, so
old approach worked fine for me.  Here's the current seabios patch:

--- a/src/fw/acpi.c     2013-11-24 00:03:36.000000000 +0400
+++ b/src/fw/acpi.c     2013-11-24 00:03:48.053886298 +0400
@@ -20,6 +20,8 @@

 u32 acpi_pm1a_cnt VARFSEG;

+static const struct acpi_table_header *slic;
+
 static void
 build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
 {
@@ -32,6 +34,9 @@ build_header(struct acpi_table_header *h
     h->oem_revision = cpu_to_le32(1);
     memcpy(h->asl_compiler_id, BUILD_APPNAME4, 4);
     h->asl_compiler_revision = cpu_to_le32(1);
+    if (slic && sig == RSDT_SIGNATURE)
+        /* for win7/vista, RSDT oem should match SLIC, min 14 bytes */
+        memcpy(h->oem_id, slic->oem_id, 6 + 4 + 4);
     h->checksum -= checksum(h, len);
 }

@@ -642,6 +647,8 @@ acpi_setup(void)
             }
         } else {
             ACPI_INIT_TABLE(table);
+            if (table->signature == 0x43494c53/*SLIC*/)
+                slic = table;
         }
         if (tbl_idx == MAX_ACPI_TABLES) {
             warn_noalloc();

>> Windows7 requires that OEM ID in RSDT matches those in SLIC to
>> consider SLIC to be valid.
> 
> Which fields need to match which, exactly?

As can be seen in the patch itself, that's 2 fields - oem_id [4]
and oem_table_id[8], in SLIC and RSDT.  This is enough for win7
at least.

>> This is somewhat hackish approach, but it works fairy well in
>> practice.
>>
>> I'm not asking to apply this directly, but instead am trying to
>> show what's needed to get win to work.  Maybe a new command-line
>> option for that will do, maybe something else.
> 
> I think it's kind of reasonable - seems better than
> adding more flags - but I'd like to avoid
> poking at acpi_tables array in acpi-build.c
> 
> How about an API to set/query OEM ID?

Such an api might be useful, and it actually _is_ useful to keep
compatibility with older guests, which is a slightly different
but very important topic (for example, my win8 guest which were
activated in qemu-1.1 does not work anymore in qemu-1.2, exactly
because of changed OEM ID, -- it is the commit which updated
qemu version number which breaks win8 activation here).

But this api wont help when we already have whole SLIC table as
in the example above.


Overall, the more I think about it, the less I consider it useful.
Because it looks like windows vista and 7 era is finished (yes, the
same thing applies to vista as well), now it is win8+ which does
not use this OEM activation mechanism anymore.  Instead, it uses
hw-based activation, for which we need to keep OEM ID in ACPI too.

Maybe back in 2010 when I faced this problem for the first time it
was a good idea to have slic-based adoption for rsdt in qemu, now
it isn't that important anymore.

Thanks,

/mjt

>>  hw/acpi/core.c       |    5 +++++
>>  hw/i386/acpi-build.c |    7 +++++++
>>  2 files changed, 12 insertions(+)
>>
>> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
>> index 79414b4..a8a3f26 100644
>> --- a/hw/acpi/core.c
>> +++ b/hw/acpi/core.c
>> @@ -53,6 +53,7 @@ static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
>>  
>>  char unsigned *acpi_tables;
>>  size_t acpi_tables_len;
>> +size_t slic_table_offset;
>>  
>>  static QemuOptsList qemu_acpi_opts = {
>>      .name = "acpi",
>> @@ -226,6 +227,10 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
>>      /* recalculate checksum */
>>      ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
>>                                        ACPI_TABLE_PFX_SIZE, acpi_payload_size);
>> +
>> +    if (memcmp(ext_hdr->sig, "SLIC", 4) == 0) {
>> +       slic_table_offset = acpi_tables_len - acpi_payload_size;
>> +    }
>>  }
>>  
>>  void acpi_table_add(const QemuOpts *opts, Error **errp)
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index a5d3fbf..9e0e16a 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -224,6 +224,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
>>  #define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
>>  #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
>>  
>> +extern size_t slic_table_offset;
>> +
>>  static void
>>  build_header(GArray *linker, GArray *table_data,
>>               AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
>> @@ -237,6 +239,11 @@ build_header(GArray *linker, GArray *table_data,
>>      h->oem_revision = cpu_to_le32(1);
>>      memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
>>      h->asl_compiler_revision = cpu_to_le32(1);
>> +    if (memcmp(sig, "RSDT", 4) == 0 && slic_table_offset) {
>> +      /* for win7: OEM info in RSDT and SLIC should be the same */
>> +      AcpiTableHeader *s = (AcpiTableHeader *)(acpi_tables + slic_table_offset);
>> +      memcpy(h->oem_id, s->oem_id, 6 + 4 + 4);
> 
> 
> what does 6 + 4 +4 mean?
> I see:
>     uint8_t  oem_id [6];             /* OEM identification */ \
>     uint8_t  oem_table_id [8];       /* OEM table identification */ \
>     uint32_t oem_revision;           /* OEM revision number */ \
> 
> Do table id have to match? It seems a bit wrong to have two tables
> with the same id.
> 
>> +    }
>>      h->checksum = 0;
>>      /* Checksum to be filled in by Guest linker */
>>      bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
>> -- 
>> 1.7.10.4
>>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT
  2014-04-06 11:08   ` Michael Tokarev
@ 2014-04-06 12:21     ` Laszlo Ersek
  2014-04-07 15:38       ` Chris Evich
  2014-04-06 12:25     ` Michael S. Tsirkin
  1 sibling, 1 reply; 7+ messages in thread
From: Laszlo Ersek @ 2014-04-06 12:21 UTC (permalink / raw)
  To: Michael Tokarev, Michael S. Tsirkin; +Cc: qemu-devel, Christopher Evich

On 04/06/14 13:08, Michael Tokarev wrote:
> 06.04.2014 14:53, Michael S. Tsirkin wrote:
>> On Sun, Apr 06, 2014 at 01:49:11PM +0400, Michael Tokarev wrote:
>>> When building RSDT table, pick OEM ID fields from uer-supplied SLIC
>>> table instead of using hard-coded QEMU defaults.  This way, say,
>>> OEM version of Windows7 can be run inside qemu using the same OEM
>>> activation as on bare metal, by pointing at system firmware:
>>>
>>>   -acpitable file=/sys/firmware/acpi/tables/SLIC
>>
>> Right, so this doesn't work in 1.7 either, right?
>> It's not a regression?
> 
> It doesn't work in 1.7 too, but it is not a regression.
> Before 1.7 I used a very similar approach patching seabios,
> for several years.  Here's one of the first versions of this
> approach -- http://lists.gnu.org/archive/html/qemu-devel/2011-03/msg03080.html
> 
> I used this approach since that time locally.
> For 1.7 I used seabios without acpi table loading interface, so
> old approach worked fine for me.  Here's the current seabios patch:
> 
> --- a/src/fw/acpi.c     2013-11-24 00:03:36.000000000 +0400
> +++ b/src/fw/acpi.c     2013-11-24 00:03:48.053886298 +0400
> @@ -20,6 +20,8 @@
> 
>  u32 acpi_pm1a_cnt VARFSEG;
> 
> +static const struct acpi_table_header *slic;
> +
>  static void
>  build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
>  {
> @@ -32,6 +34,9 @@ build_header(struct acpi_table_header *h
>      h->oem_revision = cpu_to_le32(1);
>      memcpy(h->asl_compiler_id, BUILD_APPNAME4, 4);
>      h->asl_compiler_revision = cpu_to_le32(1);
> +    if (slic && sig == RSDT_SIGNATURE)
> +        /* for win7/vista, RSDT oem should match SLIC, min 14 bytes */
> +        memcpy(h->oem_id, slic->oem_id, 6 + 4 + 4);
>      h->checksum -= checksum(h, len);
>  }
> 
> @@ -642,6 +647,8 @@ acpi_setup(void)
>              }
>          } else {
>              ACPI_INIT_TABLE(table);
> +            if (table->signature == 0x43494c53/*SLIC*/)
> +                slic = table;
>          }
>          if (tbl_idx == MAX_ACPI_TABLES) {
>              warn_noalloc();
> 
>>> Windows7 requires that OEM ID in RSDT matches those in SLIC to
>>> consider SLIC to be valid.
>>
>> Which fields need to match which, exactly?
> 
> As can be seen in the patch itself, that's 2 fields - oem_id [4]
> and oem_table_id[8], in SLIC and RSDT.  This is enough for win7
> at least.
> 
>>> This is somewhat hackish approach, but it works fairy well in
>>> practice.
>>>
>>> I'm not asking to apply this directly, but instead am trying to
>>> show what's needed to get win to work.  Maybe a new command-line
>>> option for that will do, maybe something else.
>>
>> I think it's kind of reasonable - seems better than
>> adding more flags - but I'd like to avoid
>> poking at acpi_tables array in acpi-build.c
>>
>> How about an API to set/query OEM ID?
> 
> Such an api might be useful, and it actually _is_ useful to keep
> compatibility with older guests, which is a slightly different
> but very important topic (for example, my win8 guest which were
> activated in qemu-1.1 does not work anymore in qemu-1.2, exactly
> because of changed OEM ID, -- it is the commit which updated
> qemu version number which breaks win8 activation here).
> 
> But this api wont help when we already have whole SLIC table as
> in the example above.
> 
> 
> Overall, the more I think about it, the less I consider it useful.
> Because it looks like windows vista and 7 era is finished (yes, the
> same thing applies to vista as well), now it is win8+ which does
> not use this OEM activation mechanism anymore.  Instead, it uses
> hw-based activation, for which we need to keep OEM ID in ACPI too.
> 
> Maybe back in 2010 when I faced this problem for the first time it
> was a good idea to have slic-based adoption for rsdt in qemu, now
> it isn't that important anymore.

I'd like to add two points (purely FYI, ie. in no way to contradict
anything you said -- actually, my 2nd point even seems to confirm what
you said):

(1) In the OVMF ACPI download patch, we skip qemu's RSDT and XSDT on
purpose:

https://github.com/tianocore/edk2/commit/96bbdbc856930abf38d0cc289536ebd11043f80f#diff-7e7e6f95dd6acdc67fcfdc854aa5f46eR603

That's because the EFI_ACPI_TABLE_PROTOCOL, which
- is specified in UEFI-2.4A, Chapter 19,
- has an edk2 reference implementation in
MdeModulePkg/Universal/Acpi/AcpiTableDxe/,
- OVMF uses to install ACPI tables

handles RSDT/XSDT automatically, outside of OVMF's jurisdiction.

In particular, the edk2 reference implementation of
EFI_ACPI_TABLE_PROTOCOL sets the RSDT's OemId and OemTableId fields from
the same in FADT (which qemu does provide, signature "FACP"):

https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c#L695

(2) I recently found this forum post from Chris Evich (CC'd):

  Libvirt + Fedora 20 + Windows 8.1 OEM + UEFI = Oh My!
  http://forums.fedoraforum.org/showthread.php?p=1694052

(scroll up to the start of the thread).

It's real-life evidence that handling the SLIC manually (plus some other
stuff), without adapting the OemId & OemTableId fields in RSDT/XSDT to
SLIC, is sufficient to keep the Windows 8.1 OEM guest happy.

(I found the forum post because I regularly google last week's OVMF
references, to see what's up. (As a side note, it's nice to see that
users have put OVMF's PlatformDxe to use (for setting the GOP
resolution) in less than ten days after that series was committed (SVN
r15375).))

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT
  2014-04-06 11:08   ` Michael Tokarev
  2014-04-06 12:21     ` Laszlo Ersek
@ 2014-04-06 12:25     ` Michael S. Tsirkin
  2014-04-06 13:58       ` Michael Tokarev
  1 sibling, 1 reply; 7+ messages in thread
From: Michael S. Tsirkin @ 2014-04-06 12:25 UTC (permalink / raw)
  To: Michael Tokarev; +Cc: qemu-devel

On Sun, Apr 06, 2014 at 03:08:46PM +0400, Michael Tokarev wrote:
> 06.04.2014 14:53, Michael S. Tsirkin wrote:
> > On Sun, Apr 06, 2014 at 01:49:11PM +0400, Michael Tokarev wrote:
> >> When building RSDT table, pick OEM ID fields from uer-supplied SLIC
> >> table instead of using hard-coded QEMU defaults.  This way, say,
> >> OEM version of Windows7 can be run inside qemu using the same OEM
> >> activation as on bare metal, by pointing at system firmware:
> >>
> >>   -acpitable file=/sys/firmware/acpi/tables/SLIC
> > 
> > Right, so this doesn't work in 1.7 either, right?
> > It's not a regression?
> 
> It doesn't work in 1.7 too, but it is not a regression.
> Before 1.7 I used a very similar approach patching seabios,
> for several years.  Here's one of the first versions of this
> approach -- http://lists.gnu.org/archive/html/qemu-devel/2011-03/msg03080.html
> 
> I used this approach since that time locally.
> For 1.7 I used seabios without acpi table loading interface, so
> old approach worked fine for me.  Here's the current seabios patch:
> 
> --- a/src/fw/acpi.c     2013-11-24 00:03:36.000000000 +0400
> +++ b/src/fw/acpi.c     2013-11-24 00:03:48.053886298 +0400
> @@ -20,6 +20,8 @@
> 
>  u32 acpi_pm1a_cnt VARFSEG;
> 
> +static const struct acpi_table_header *slic;
> +
>  static void
>  build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
>  {
> @@ -32,6 +34,9 @@ build_header(struct acpi_table_header *h
>      h->oem_revision = cpu_to_le32(1);
>      memcpy(h->asl_compiler_id, BUILD_APPNAME4, 4);
>      h->asl_compiler_revision = cpu_to_le32(1);
> +    if (slic && sig == RSDT_SIGNATURE)
> +        /* for win7/vista, RSDT oem should match SLIC, min 14 bytes */
> +        memcpy(h->oem_id, slic->oem_id, 6 + 4 + 4);
>      h->checksum -= checksum(h, len);
>  }
> 
> @@ -642,6 +647,8 @@ acpi_setup(void)
>              }
>          } else {
>              ACPI_INIT_TABLE(table);
> +            if (table->signature == 0x43494c53/*SLIC*/)
> +                slic = table;
>          }
>          if (tbl_idx == MAX_ACPI_TABLES) {
>              warn_noalloc();
> 
> >> Windows7 requires that OEM ID in RSDT matches those in SLIC to
> >> consider SLIC to be valid.
> > 
> > Which fields need to match which, exactly?
> 
> As can be seen in the patch itself, that's 2 fields - oem_id [4]

Surely oem_id[6]?

> and oem_table_id[8], in SLIC and RSDT.  This is enough for win7
> at least.
> 
> >> This is somewhat hackish approach, but it works fairy well in
> >> practice.
> >>
> >> I'm not asking to apply this directly, but instead am trying to
> >> show what's needed to get win to work.  Maybe a new command-line
> >> option for that will do, maybe something else.
> > 
> > I think it's kind of reasonable - seems better than
> > adding more flags - but I'd like to avoid
> > poking at acpi_tables array in acpi-build.c
> > 
> > How about an API to set/query OEM ID?
> 
> Such an api might be useful, and it actually _is_ useful to keep
> compatibility with older guests, which is a slightly different
> but very important topic (for example, my win8 guest which were
> activated in qemu-1.1 does not work anymore in qemu-1.2, exactly
> because of changed OEM ID, -- it is the commit which updated
> qemu version number which breaks win8 activation here).

I'm guessing 1.1 compatibility isn't perfect, but
this shouldn't happen with recent versions like 1.6 and 2.0 at least:
2.0 should not need re-activation if you run
with -M option compatible with 1.6.

> But this api wont help when we already have whole SLIC table as
> in the example above.

I think I wasn't clear. I merely meant an internal API,
have acpi_table_install call it internally instead of
exposing the offset field.


> 
> Overall, the more I think about it, the less I consider it useful.
> Because it looks like windows vista and 7 era is finished (yes, the
> same thing applies to vista as well),

windows  7 is still in mainstream support.  Extended support is until
2020.  Seems worth supporting.

> now it is win8+ which does
> not use this OEM activation mechanism anymore.  Instead, it uses
> hw-based activation, for which we need to keep OEM ID in ACPI too.

Yes, if this patch is not in 2.0, we need to be careful and
only change ID with new -M flag.

> Maybe back in 2010 when I faced this problem for the first time it
> was a good idea to have slic-based adoption for rsdt in qemu, now
> it isn't that important anymore.
> 
> Thanks,
> 
> /mjt
> 
> >>  hw/acpi/core.c       |    5 +++++
> >>  hw/i386/acpi-build.c |    7 +++++++
> >>  2 files changed, 12 insertions(+)
> >>
> >> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> >> index 79414b4..a8a3f26 100644
> >> --- a/hw/acpi/core.c
> >> +++ b/hw/acpi/core.c
> >> @@ -53,6 +53,7 @@ static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
> >>  
> >>  char unsigned *acpi_tables;
> >>  size_t acpi_tables_len;
> >> +size_t slic_table_offset;
> >>  
> >>  static QemuOptsList qemu_acpi_opts = {
> >>      .name = "acpi",
> >> @@ -226,6 +227,10 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
> >>      /* recalculate checksum */
> >>      ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
> >>                                        ACPI_TABLE_PFX_SIZE, acpi_payload_size);
> >> +
> >> +    if (memcmp(ext_hdr->sig, "SLIC", 4) == 0) {
> >> +       slic_table_offset = acpi_tables_len - acpi_payload_size;
> >> +    }
> >>  }
> >>  
> >>  void acpi_table_add(const QemuOpts *opts, Error **errp)
> >> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> >> index a5d3fbf..9e0e16a 100644
> >> --- a/hw/i386/acpi-build.c
> >> +++ b/hw/i386/acpi-build.c
> >> @@ -224,6 +224,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
> >>  #define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
> >>  #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
> >>  
> >> +extern size_t slic_table_offset;
> >> +
> >>  static void
> >>  build_header(GArray *linker, GArray *table_data,
> >>               AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
> >> @@ -237,6 +239,11 @@ build_header(GArray *linker, GArray *table_data,
> >>      h->oem_revision = cpu_to_le32(1);
> >>      memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
> >>      h->asl_compiler_revision = cpu_to_le32(1);
> >> +    if (memcmp(sig, "RSDT", 4) == 0 && slic_table_offset) {
> >> +      /* for win7: OEM info in RSDT and SLIC should be the same */
> >> +      AcpiTableHeader *s = (AcpiTableHeader *)(acpi_tables + slic_table_offset);
> >> +      memcpy(h->oem_id, s->oem_id, 6 + 4 + 4);
> > 
> > 
> > what does 6 + 4 +4 mean?
> > I see:
> >     uint8_t  oem_id [6];             /* OEM identification */ \
> >     uint8_t  oem_table_id [8];       /* OEM table identification */ \
> >     uint32_t oem_revision;           /* OEM revision number */ \
> > 
> > Do table id have to match? It seems a bit wrong to have two tables
> > with the same id.
> > 
> >> +    }
> >>      h->checksum = 0;
> >>      /* Checksum to be filled in by Guest linker */
> >>      bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
> >> -- 
> >> 1.7.10.4
> >>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT
  2014-04-06 12:25     ` Michael S. Tsirkin
@ 2014-04-06 13:58       ` Michael Tokarev
  0 siblings, 0 replies; 7+ messages in thread
From: Michael Tokarev @ 2014-04-06 13:58 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: qemu-devel

06.04.2014 16:25, Michael S. Tsirkin wrote:
[]
>>>> Windows7 requires that OEM ID in RSDT matches those in SLIC to
>>>> consider SLIC to be valid.
>>>
>>> Which fields need to match which, exactly?
>>
>> As can be seen in the patch itself, that's 2 fields - oem_id [4]
> 
> Surely oem_id[6]?

Yes you're right.

>> and oem_table_id[8], in SLIC and RSDT.  This is enough for win7
>> at least.

All 14 bytes in this place are needed.  Omitting any of those 3
(actually that's 3 not 2) fields -- oem_id[6], oem_table_id[4]
and oem_table_sig[4] makes windows 7 activation void.

I'm sorry I missed this question initially:

>>>> +    if (memcmp(sig, "RSDT", 4) == 0 && slic_table_offset) {
>>>> +      /* for win7: OEM info in RSDT and SLIC should be the same */
>>>> +      AcpiTableHeader *s = (AcpiTableHeader *)(acpi_tables + slic_table_offset);
>>>> +      memcpy(h->oem_id, s->oem_id, 6 + 4 + 4);
>>>
>>>
>>> what does 6 + 4 +4 mean?
>>> I see:
>>>     uint8_t  oem_id [6];             /* OEM identification */ \
>>>     uint8_t  oem_table_id [8];       /* OEM table identification */ \
>>>     uint32_t oem_revision;           /* OEM revision number */ \

In some specs I found oem_table_id[8] is represented by 2 4-byte fields.

>>> Do table id have to match? It seems a bit wrong to have two tables
>>> with the same id.

Yes it should match, whole oem_table_id[8] plus oem_id[6] itself.
I don't know what exactly those identifications mean, but without
any of those 14 bytes windows activation does not work.
oem_revision can be anything, it is not part of the equation.

It is easy to verify by playing with the memcpy() above -- this is
actually how I found the minimal amount of bytes which should match
initially.

Thanks,

/mjt

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT
  2014-04-06 12:21     ` Laszlo Ersek
@ 2014-04-07 15:38       ` Chris Evich
  0 siblings, 0 replies; 7+ messages in thread
From: Chris Evich @ 2014-04-07 15:38 UTC (permalink / raw)
  To: Laszlo Ersek, Michael Tokarev, Michael S. Tsirkin; +Cc: qemu-devel

On 04/06/2014 08:21 AM, Laszlo Ersek wrote:
> (2) I recently found this forum post from Chris Evich (CC'd):
> 
>   Libvirt + Fedora 20 + Windows 8.1 OEM + UEFI = Oh My!
>   http://forums.fedoraforum.org/showthread.php?p=1694052
> 
> (scroll up to the start of the thread).

FWIW: "Works" in my instance was defined as "Windows 8.1 installed as a
VM and successfully passed M$ activation".  As I understand it, there is
some "slop" on the M$ side to account for a degree of hardware variation
between OEM pre-activation and the consumer "phone-home" phase.  My aim
was to do everything I could think of to match as closely as possible
and get it working.  I __did_not_go_deeper_than_that__, meaning
verifying ACPI tables and such inside the guest.

I did note the installer asked me to manually enter the license key,
which I read it's suppose to automatically read out of the MSDS table.
Maybe I needed to pull in stuff from RSDT/XSDT or none of the
table-copying business was working/necessary.  In any case, presumably
if I didn't match enough of the hardware uniqueness (uuid, mac
addresses, etc) it would have been outside the "slop".  Then again, I
suppose they could change the degree of slop at some point, so maybe the
tables will be important.

Anyway, if anyone wants more details, I'm happy to help.

-- 
Chris Evich, RHCA, RHCE, RHCDS, RHCSS
Quality Assurance Engineer
e-mail: cevich + `@' + redhat.com o: 1-888-RED-HAT1 x44214

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-04-07 15:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-06  9:49 [Qemu-devel] [RFC] copy OEM ACPI parameters from SLIC table to RSDT Michael Tokarev
2014-04-06 10:53 ` Michael S. Tsirkin
2014-04-06 11:08   ` Michael Tokarev
2014-04-06 12:21     ` Laszlo Ersek
2014-04-07 15:38       ` Chris Evich
2014-04-06 12:25     ` Michael S. Tsirkin
2014-04-06 13:58       ` Michael Tokarev

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.