acpi: Prevent GPL-only code from seeping into non-GPL binaries

Some code (specifically, introduced by commit 801d469ad ("[HVM] ACPI
support patch 3 of 4: ACPI _PRT table.")) has only been licensed under
GPLv2. We want to prevent this code from showing up in non-GPL
binaries which might become possible after we make ACPI builder code
available to users other than hvmloader.

There are two pieces that we need to be careful about:
(1) A small chunk of code in dsdt.asl that implements _PIC method
(2) A chunk of ASL generator in mk_dsdt.c that describes with PCI
    interrupt routing.

This code will now be generated by a GPL-only script which will be
invoked only when ACPI builder's Makefile is called with GPL variable
set.

We also strip license header from generated ASL files to prevent
inadverent use of those files with incorrect license.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Boris Ostrovsky authored and Wei Liu committed 2016-09-28 14:31:49 +01:00
1 parent e8c4e3af73
commit c3397311a6
5 files changed
+132 -84

No files matched your search

+3
View File
@@ -65,6 +65,9 @@ ROMBIOS_ROM := $(ROMBIOS_DIR)/BIOS-bochs-latest
ROMS += $(ROMBIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) $(ETHERBOOT_ROMS)
endif
# Certain parts of ACPI builder are GPL-only
export GPL := y
.PHONY: all
all: subdirs-all
$(MAKE) hvmloader
+11 -3
View File
@@ -17,7 +17,8 @@
XEN_ROOT = $(CURDIR)/../../../..
include $(XEN_ROOT)/tools/firmware/Rules.mk
C_SRC = build.c dsdt_anycpu.c dsdt_15cpu.c static_tables.c dsdt_anycpu_qemu_xen.c
C_SRC-$(GPL) = build.c dsdt_anycpu.c dsdt_15cpu.c dsdt_anycpu_qemu_xen.c
C_SRC = build.c static_tables.c $(C_SRC-y)
OBJS = $(patsubst %.c,%.o,$(C_SRC))
CFLAGS += $(CFLAGS_xeninclude)
@@ -36,18 +37,25 @@ ssdt_s3.h ssdt_s4.h ssdt_pm.h ssdt_tpm.h: %.h: %.asl iasl
mk_dsdt: mk_dsdt.c
$(HOSTCC) $(HOSTCFLAGS) $(CFLAGS_xeninclude) -o $@ mk_dsdt.c
dsdt_anycpu_qemu_xen.asl: dsdt.asl dsdt_acpi_info.asl mk_dsdt
ifeq ($(GPL),y)
dsdt_anycpu_qemu_xen.asl: dsdt.asl dsdt_acpi_info.asl gpl/mk_dsdt_gpl.sh mk_dsdt
awk 'NR > 1 {print s} {s=$$0}' $< > $@.$(TMP_SUFFIX)
# Strip license comment
sed -i '1,/\*\//{/\/\*/,/\*\//d}' $@.$(TMP_SUFFIX)
$(SHELL) gpl/mk_dsdt_gpl.sh >> $@.$(TMP_SUFFIX)
cat dsdt_acpi_info.asl >> $@.$(TMP_SUFFIX)
./mk_dsdt --debug=$(debug) --dm-version qemu-xen >> $@.$(TMP_SUFFIX)
mv -f $@.$(TMP_SUFFIX) $@
# NB. awk invocation is a portable alternative to 'head -n -1'
dsdt_%cpu.asl: dsdt.asl dsdt_acpi_info.asl mk_dsdt
dsdt_%cpu.asl: dsdt.asl dsdt_acpi_info.asl gpl/mk_dsdt_gpl.sh mk_dsdt
awk 'NR > 1 {print s} {s=$$0}' $< > $@.$(TMP_SUFFIX)
sed -i '1,/\*\//{/\/\*/,/\*\//d}' $@.$(TMP_SUFFIX)
$(SHELL) gpl/mk_dsdt_gpl.sh >> $@.$(TMP_SUFFIX)
cat dsdt_acpi_info.asl >> $@.$(TMP_SUFFIX)
./mk_dsdt --debug=$(debug) --maxcpu $* >> $@.$(TMP_SUFFIX)
mv -f $@.$(TMP_SUFFIX) $@
endif
$(filter dsdt_%.c,$(C_SRC)): %.c: iasl %.asl
iasl -vs -p $* -tc $*.asl
-14
View File
@@ -26,20 +26,6 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0)
Name (\APCL, 0x00010000)
Name (\PUID, 0x00)
/* _S3 and _S4 are in separate SSDTs */
Name (\_S5, Package (0x04)
{
0x00, /* PM1a_CNT.SLP_TYP */
0x00, /* PM1b_CNT.SLP_TYP */
0x00, /* reserved */
0x00 /* reserved */
})
Name(PICD, 0)
Method(_PIC, 1)
{
Store(Arg0, PICD)
}
Scope (\_SB)
{
+117
View File
@@ -0,0 +1,117 @@
#!/bin/sh
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; If not, see <http://www.gnu.org/licenses/>.
#
cat <<'EndOfASL'
/* Beginning of GPL-only code */
/* _S3 and _S4 are in separate SSDTs */
Name (\_S5, Package (0x04) {
0x00, /* PM1a_CNT.SLP_TYP */
0x00, /* PM1b_CNT.SLP_TYP */
0x00, /* reserved */
0x00 /* reserved */
})
Name(PICD, 0)
Method(_PIC, 1) {
Store(Arg0, PICD)
}
EndOfASL
# PCI-ISA link definitions
# BUFA: List of ISA IRQs available for linking to PCI INTx.
# BUFB: IRQ descriptor for returning from link-device _CRS methods.
cat <<'EndOfASL'
Scope ( \_SB.PCI0 ) {
Name ( BUFA, ResourceTemplate() { IRQ(Level, ActiveLow, Shared) { 5, 10, 11 } } )
Name ( BUFB, Buffer() { 0x23, 0x00, 0x00, 0x18, 0x79, 0 } )
CreateWordField ( BUFB, 0x01, IRQV )
EndOfASL
for i in $(seq 1 4)
do
link=`echo "A B C D" | cut -d" " -f $i`
cat <<EndOfASL
Device ( LNK$link ) {
Name ( _HID, EISAID("PNP0C0F") )
Name ( _UID, $i)
Method ( _STA, 0) {
If ( And(PIR$link, 0x80) ) {
Return ( 0x09 )
} Else {
Return ( 0x0B )
}
}
Method ( _PRS ) {
Return ( BUFA )
}
Method ( _DIS ) {
Or ( PIR$link, 0x80, PIR$link )
}
Method ( _CRS ) {
And ( PIR$link, 0x0f, Local0 )
ShiftLeft ( 0x1, Local0, IRQV )
Return ( BUFB )
}
Method ( _SRS, 1 ) {
CreateWordField ( ARG0, 0x01, IRQ1 )
FindSetRightBit ( IRQ1, Local0 )
Decrement ( Local0 )
Store ( Local0, PIR$link )
}
}
EndOfASL
done
# PCI interrupt routing definitions
# _PRT: Method to return routing table.
cat <<'EndOfASL'
Method ( _PRT, 0 ) {
If ( PICD ) {
Return ( PRTA )
}
Return ( PRTP )
}
EndOfASL
# PRTP: PIC routing table (via ISA links).
echo " Name(PRTP, Package() {"
for dev in $(seq 1 31)
do
for intx in $(seq 0 3) # INTA-D
do
link_idx=$(( ((dev + intx) & 3) + 1 ))
link=`echo "A B C D" | cut -d" " -f $link_idx`
printf " Package(){0x%04xffff, %u, \\\\_SB.PCI0.LNK%c, 0},\n" \
$dev $intx $link
done
done
echo " })"
# PRTA: APIC routing table (via non-legacy IOAPIC GSIs).
echo " Name(PRTA, Package() {"
for dev in $(seq 1 31)
do
for intx in $(seq 0 3) # INTA-D
do
idx=$(( ((dev * 4 + dev/8 + intx) & 31) + 16 ))
printf " Package(){0x%04xffff, %u, 0, %u},\n" \
$dev $intx $idx
done
done
echo " })"
echo " }"
echo " /* End of GPL-only code */"
+1 -67
View File
@@ -91,7 +91,7 @@ static struct option options[] = {
int main(int argc, char **argv)
{
unsigned int slot, dev, intx, link, cpu, max_cpus = HVM_MAX_VCPUS;
unsigned int slot, cpu, max_cpus = HVM_MAX_VCPUS;
dm_version dm_version = QEMU_XEN_TRADITIONAL;
for ( ; ; )
@@ -273,72 +273,6 @@ int main(int argc, char **argv)
}
} pop_block();
/*** PCI-ISA link definitions ***/
/* BUFA: List of ISA IRQs available for linking to PCI INTx. */
stmt("Name", "BUFA, ResourceTemplate() { "
"IRQ(Level, ActiveLow, Shared) { 5, 10, 11 } }");
/* BUFB: IRQ descriptor for returning from link-device _CRS methods. */
stmt("Name", "BUFB, Buffer() { "
"0x23, 0x00, 0x00, 0x18, " /* IRQ descriptor */
"0x79, 0 }"); /* End tag, null checksum */
stmt("CreateWordField", "BUFB, 0x01, IRQV");
/* Create four PCI-ISA link devices: LNKA, LNKB, LNKC, LNKD. */
for ( link = 0; link < 4; link++ )
{
push_block("Device", "LNK%c", 'A'+link);
stmt("Name", "_HID, EISAID(\"PNP0C0F\")"); /* PCI interrupt link */
stmt("Name", "_UID, %u", link+1);
push_block("Method", "_STA, 0");
push_block("If", "And(PIR%c, 0x80)", 'A'+link);
stmt("Return", "0x09");
pop_block();
push_block("Else", NULL);
stmt("Return", "0x0B");
pop_block();
pop_block();
push_block("Method", "_PRS");
stmt("Return", "BUFA");
pop_block();
push_block("Method", "_DIS");
stmt("Or", "PIR%c, 0x80, PIR%c", 'A'+link, 'A'+link);
pop_block();
push_block("Method", "_CRS");
stmt("And", "PIR%c, 0x0f, Local0", 'A'+link);
stmt("ShiftLeft", "0x1, Local0, IRQV");
stmt("Return", "BUFB");
pop_block();
push_block("Method", "_SRS, 1");
stmt("CreateWordField", "ARG0, 0x01, IRQ1");
stmt("FindSetRightBit", "IRQ1, Local0");
stmt("Decrement", "Local0");
stmt("Store", "Local0, PIR%c", 'A'+link);
pop_block();
pop_block();
}
/*** PCI interrupt routing definitions***/
/* _PRT: Method to return routing table. */
push_block("Method", "_PRT, 0");
push_block("If", "PICD");
stmt("Return", "PRTA");
pop_block();
stmt("Return", "PRTP");
pop_block();
/* PRTP: PIC routing table (via ISA links). */
printf("Name(PRTP, Package() {\n");
for ( dev = 1; dev < 32; dev++ )
for ( intx = 0; intx < 4; intx++ ) /* INTA-D */
printf("Package(){0x%04xffff, %u, \\_SB.PCI0.LNK%c, 0},\n",
dev, intx, 'A'+((dev+intx)&3));
printf("})\n");
/* PRTA: APIC routing table (via non-legacy IOAPIC GSIs). */
printf("Name(PRTA, Package() {\n");
for ( dev = 1; dev < 32; dev++ )
for ( intx = 0; intx < 4; intx++ ) /* INTA-D */
printf("Package(){0x%04xffff, %u, 0, %u},\n",
dev, intx, ((dev*4+dev/8+intx)&31)+16);
printf("})\n");
/*
* Each PCI hotplug slot needs at least two methods to handle
* the ACPI event:
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.