Monitoramento de ABI do kernel do Android

É possível usar as ferramentas de monitoramento da interface binária de aplicativo (ABI) disponíveis em Android 11 e versões mais recentes, para estabilizar o kernel ABI de kernels do Android. As ferramentas coletam e comparam as representações da ABI de binários do kernel existentes (vmlinux+ módulos GKI). Essas ABIs representações são os arquivos .stg e as listas de símbolos. A interface na que a representação oferece uma visualização é chamada de interface de módulo do kernel. (KMI). Você pode usar as ferramentas para acompanhar e mitigar mudanças no KMI.

As ferramentas de monitoramento de ABI desenvolvido em AOSP e usa STG (ou libabigail em Android 13 e versões anteriores) para gerar e comparar representações de vetor.

Esta página descreve as ferramentas, o processo de coleta e análise da ABI e o uso dessas representações para dar estabilidade a a ABI no kernel. Esta página também fornece informações para contribuir com mudanças aos kernels do Android.

Processo

A análise da ABI do kernel tem várias etapas, e a maioria delas pode ser automatizada:

  1. Crie o kernel e a representação de ABI dele.
  2. Analisar as diferenças de ABI entre o build e uma referência.
  3. Atualizar a representação ABI (se necessário).
  4. Trabalhar com listas de símbolos.

As instruções a seguir funcionam para qualquer kernel que você pode criar usando uma conjunto de ferramentas compatível (como o conjunto pré-criado do Clang). repo manifests estão disponíveis para todas as ramificações comuns do kernel do Android e para vários kernels específicos do dispositivo, eles garantem que o conjunto de ferramentas correto seja usado quando você criar uma distribuição de kernel para análise.

Listas de símbolos

O KMI não inclui todos os símbolos do kernel ou até mesmo todos os mais de 30.000 símbolos exportados. Em vez disso, os símbolos que podem ser usados pelos módulos do fornecedor são explicitamente listados em um conjunto de arquivos de lista de símbolos mantidos publicamente na raiz. da árvore de kernel. A união de todos os símbolos em todos os arquivos da lista de símbolos define o conjunto de símbolos KMI mantido como estável. Um exemplo de arquivo de lista de símbolos é abi_gki_aarch64_db845c e que declara os símbolos necessários para DragonBoard 845c (link em inglês).

Somente os símbolos listados em uma lista de símbolos e suas estruturas relacionadas e são consideradas parte do KMI. Você pode publicar alterações no seu lista de símbolos se os símbolos necessários não estiverem presentes. Depois que as novas interfaces estiverem no uma lista de símbolos e fazem parte da descrição do KMI, eles são mantidos como estáveis e não deve ser removido da lista de símbolos nem modificado depois que a ramificação congelados.

Cada ramificação do kernel KMI do Kernel comum do Android (ACK) tem seu próprio conjunto de símbolos listas. Nenhuma tentativa de fornecer estabilidade de ABI entre diferentes kernels KMI. galhos. Por exemplo, o KMI de android12-5.10 é completamente independente o KMI para android13-5.10.

As ferramentas ABI usam listas de símbolos KMI para limitar quais interfaces devem ser monitoradas a estabilidade. A lista de símbolos principais contém os símbolos exigidos pelos módulos do kernel de GKI. Os fornecedores são deve enviar e atualizar listas de símbolos adicionais para garantir que o interfaces nas quais dependem mantêm a compatibilidade com ABI. Por exemplo, para ver uma lista de listas de símbolos para o android13-5.15, consulte https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15/android

Uma lista de símbolos contém os símbolos relatados como necessários para o determinado fornecedor ou dispositivo. A lista completa usada pelas ferramentas é a união de todos os Arquivos da lista de símbolos KMI. As ferramentas ABI determinam os detalhes de cada símbolo, incluindo assinatura de funções e estruturas de dados aninhados.

Quando o KMI está congelado, não são permitidas alterações nas interfaces do KMI existentes. estejam estáveis. No entanto, os fornecedores podem adicionar símbolos ao KMI a qualquer momento Desde que as adições não afetem a estabilidade da ABI atual. Adicionados recentemente símbolos são mantidos tão estáveis assim que são citados por uma lista de símbolos KMI. Os símbolos não devem ser removidos de uma lista para um kernel, a menos que possam ser confirmados que nenhum dispositivo jamais foi enviado com uma dependência desse símbolo.

É possível gerar uma lista de símbolos KMI para um dispositivo usando as instruções da Como trabalhar com listas de símbolos. Muitos parceiros enviam uma lista de símbolos por ACK, mas esse não é um requisito fixo. Se ajudar na manutenção, você pode enviar várias listas de símbolos.

Estenda o KMI

Embora os símbolos KMI e as estruturas relacionadas sejam mantidos como estáveis (ou seja, alterações que interrompem interfaces estáveis em um kernel com KMI congelado não podem ser aceita), o kernel de GKI permanece aberto a extensões para que os dispositivos posteriormente no ano não precisam definir todas as dependências antes que o KMI seja congelados. Para estender o KMI, você pode adicionar novos símbolos a ele para novos funções do kernel exportadas, mesmo que o KMI esteja congelado. Novo kernel também poderão ser aceitos se não violarem o KMI.

Sobre falhas do KMI

Um kernel tem origens, e os binários são criados a partir delas. As ramificações de kernel monitoradas pela ABI incluem uma representação da ABI da GKI atual. ABI (na forma de um arquivo .stg). Após os binários (vmlinux, Image e módulos GKI) forem compilados, uma representação de ABI poderá ser extraída do binários. Qualquer alteração feita a um arquivo de origem do kernel pode afetar os binários e por sua vez também afetam o .stg extraído. O analisador AbiAnalyzer compara o commit do arquivo .stg por meio daquele extraído dos artefatos de compilação e define uma Rótulo Lint-1 na mudança no Gerrit se ele encontrar uma diferença semântica.

Lidar com falhas de ABI

Por exemplo, o patch a seguir introduz uma falha muito óbvia na ABI:

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 42786e6364ef..e15f1d0f137b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -657,6 +657,7 @@ struct mm_struct {
                ANDROID_KABI_RESERVE(1);
        } __randomize_layout;

+       int tickle_count;
        /*
         * The mm_cpumask needs to be at the end of mm_struct, because it
         * is dynamically sized based on nr_cpu_ids.

Quando você executa a ABI de build com esse patch aplicado, as ferramentas saem com um código de erro diferente de zero e informa uma diferença de ABI semelhante a esta:

function symbol 'struct block_device* I_BDEV(struct inode*)' changed
  CRC changed from 0x8d400dbd to 0xabfc92ad

function symbol 'void* PDE_DATA(const struct inode*)' changed
  CRC changed from 0xc3c38b5c to 0x7ad96c0d

function symbol 'void __ClearPageMovable(struct page*)' changed
  CRC changed from 0xf489e5e8 to 0x92bd005e

... 4492 omitted; 4495 symbols have only CRC changes

type 'struct mm_struct' changed
  byte size changed from 992 to 1000
  member 'int tickle_count' was added
  member 'unsigned long cpu_bitmap[0]' changed
    offset changed by 64

Diferenças de ABI detectadas em tempo de build

O motivo mais comum de erros é quando um motorista usa um novo símbolo da kernel que não está em nenhuma das listas de símbolos.

Se o símbolo não estiver incluído na lista (android/abi_gki_aarch64), verifique se ele foi exportado EXPORT_SYMBOL_GPL(symbol_name) e atualizar Representação XML da ABI e lista de símbolos. Por exemplo, as alterações a seguir adicionam o novo recurso de FS incremental para a ramificação android-12-5.10, que inclui a atualização da lista de símbolos e da representação XML da ABI.

  • O exemplo de mudança de atributo está em aosp/1345659 (link em inglês).
  • O exemplo de lista de símbolos está em aosp/1346742 (link em inglês).
  • O exemplo de mudança do XML da ABI está em aosp/1349377 (link em inglês).

Se o símbolo for exportado (por você ou anteriormente), mas não outro driver o estiver usando, poderá ocorrer um erro de build semelhante ao seguinte.

Comparing the KMI and the symbol lists:
+ build/abi/compare_to_symbol_list out/$BRANCH/common/Module.symvers out/$BRANCH/common/abi_symbollist.raw
ERROR: Differences between ksymtab and symbol list detected!
Symbols missing from ksymtab:
Symbols missing from symbol list:
 - simple_strtoull

Para resolver, atualize a lista de símbolos KMI no kernel e no ACK (consulte Atualize a representação ABI. Para obter um exemplo de atualizar o XML da ABI e a lista de símbolos na ACK, consulte (AOSP/1367601).

Resolver falhas de ABI do kernel

É possível lidar com falhas de ABI do kernel refatorando o código para não alterar o ABI ou atualização da representação ABI. Use o seguinte gráfico para determinar a melhor abordagem para sua situação.

Fluxograma de interrupção da ABI

Figura 1. Resolução de falha da ABI

Refatorar o código para evitar mudanças na ABI

Faça o possível para evitar a modificação da ABI existente. Em muitos casos, é possível refatore o código para remover as mudanças que afetam a ABI.

  • Como refatorar as mudanças no campo de struct. Se uma mudança modificar a ABI para uma depuração adicione um #ifdef ao redor dos campos (nos structs e na origem referências) e se o CONFIG usado para o #ifdef está desativado para o defconfig de produção e gki_defconfig. Para um exemplo de como uma função de depuração config possa ser adicionado a um struct sem prejudicar a ABI. Consulte este patchset.

  • Recursos de refatoração para não alterar o kernel principal. Se os novos recursos precisarem seja adicionado ao ACK para oferecer suporte aos módulos do parceiro, tente refatorar a ABI parte da mudança para evitar a modificação da ABI do kernel. Para um exemplo de uso a ABI do kernel atual para adicionar recursos sem alterar a a ABI do kernel, consulte aosp/1312213 (link em inglês).

Corrigir uma ABI corrompida no Android Gerrit

Se você não quebrou intencionalmente a ABI do kernel, precisará investigar, usando as orientações das ferramentas de monitoramento da ABI. As mais comuns causas de falhas são alterações nas estruturas de dados e o símbolo associado CRC ou devido a mudanças nas opções de configuração que levam a qualquer uma das opções acima. Comece resolvendo os problemas encontrados pela ferramenta.

É possível reproduzir as descobertas de ABI localmente, consulte Crie o kernel e a representação de ABI dele.

Sobre os identificadores do Lint-1

Se você fizer o upload de alterações para uma ramificação que contenha um KMI congelado ou finalizado, as mudanças precisam transmitir AbiAnalyzer para garantir que elas não afetem a propriedade estável. ABI de maneira incompatível. Durante esse processo, o AbiAnalyzer procura as O relatório da ABI criado durante o build (um build estendido que executa a build normal e algumas etapas de extração e comparação da ABI.

Se o AbiAnalyzer encontrar um relatório não vazio, ele definirá o rótulo do Lint-1 e a o envio de mudanças está bloqueado até ser resolvido; até que o patchset receba uma Rótulo Lint+1.

Atualizar a ABI do kernel

Se a modificação da ABI for inevitável, você precisará aplicar as alterações de código, a representação ABI e a lista de símbolos à ACK. Para que o lint remover o -1 e não interromper a compatibilidade de GKI, siga estas etapas:

  1. Faça upload das alterações de código na ACK.

  2. Aguarde até receber uma revisão de código +2 para o patchset.

  3. Atualize a representação ABI de referência.

  4. Mescle as mudanças de código e a atualização da ABI.

.

Fazer upload de alterações do código ABI para o código ACK

A atualização da ABI ACK depende do tipo de alteração feita.

  • Se uma mudança na ABI estiver relacionada a um recurso que afeta testes CTS ou VTS, a alteração geralmente pode ser escolhida a dedo para o ACK no estado em que se encontra. Por exemplo:

  • Se uma alteração na ABI for para um recurso que pode ser compartilhado com o ACK, alteração pode ser escolhida a dedo para o ACK no estado em que se encontra. Por exemplo, as alterações a seguir não são necessários para o teste CTS ou VTS, mas podem ser compartilhados com ACK:

    • (osp/1250412, link em inglês) é uma mudança de recurso térmico.
    • (aosp/1288857). é uma mudança EXPORT_SYMBOL_GPL.
  • Se uma mudança na ABI introduz um novo recurso que não precisa ser incluído no é possível introduzir a ACK usando um stub, conforme descrito seção a seguir.

Usar stubs para ACK

Os stubs precisam ser necessários somente para alterações do kernel que não beneficiam o ACK, como mudanças de desempenho e energia. Os exemplos de detalhes da lista a seguir de stubs e seleções parciais em ACK para GKI.

  • Stub de recurso isolado (osp/1284493, link em inglês). Os recursos de ACK não são necessários, mas os símbolos precisam estar presentes em ACK para que os módulos usem esses símbolos.

  • Símbolo de marcador para o módulo do fornecedor (osp/1288860, links em inglês).

  • Escolha a seguir somente para ABI do recurso de acompanhamento de eventos mm por processo (osp/1288454). O patch original foi selecionado a dedo para ACK e, em seguida, cortado para incluir apenas as mudanças necessárias para resolver a diferença da ABI para task_struct e mm_event_count. Esse patch também atualiza o tipo enumerado mm_event_type para conter os membros finais.

  • Seleção parcial de mudanças na ABI da estrutura térmica que exigiam mais do que apenas adicionando os novos campos da ABI.

    • Adesivo (osp/1255544). foram resolvidas as diferenças de ABI entre o kernel do parceiro e a ACK.

    • Adesivo (osp/1291018). corrigimos os problemas funcionais encontrados durante os testes de GKI do patch anterior. A correção incluiu a inicialização do struct do parâmetro do sensor para registrar várias zonas térmicas para um único sensor.

  • CONFIG_NL80211_TESTMODE mudança de ABI (osp/1344321, link em inglês). Esse patch adicionou as alterações necessárias ao struct para a ABI e garantiu que o campos adicionais não causaram diferenças funcionais, permitindo que os parceiros incluir CONFIG_NL80211_TESTMODE nos kernels de produção e ainda manter a conformidade com a GKI.

.

Aplicar o KMI durante a execução

Os kernels de GKI usam as opções de configuração TRIM_UNUSED_KSYMS=y e UNUSED_KSYMS_WHITELIST=<union of all symbol lists>, que limitam os símbolos exportados (como símbolos exportados usando EXPORT_SYMBOL_GPL()) para aqueles listados em uma lista de símbolos. Todos os outros símbolos não são exportados e carregam um módulo que requer uma símbolo não exportado for negado. Essa restrição é aplicada no tempo de build e entradas ausentes são sinalizadas.

Para fins de desenvolvimento, é possível usar um build do kernel de GKI que não inclua corte de símbolo (ou seja, todos os símbolos geralmente exportados podem ser usados). Para localizar esses builds, procure os builds kernel_debug_aarch64 em ci.android.com (link em inglês).

Aplicar o KMI usando o controle de versões de módulos

Os kernels de imagem genérica do kernel (GKI, na sigla em inglês) usam o controle de versões de módulos (CONFIG_MODVERSIONS) como medida adicional para garantir a conformidade com o KMI em no ambiente de execução. O controle de versões do módulo pode causar incompatibilidade na verificação de redundância cíclica (CRC) no tempo de carregamento do módulo se o KMI esperado de um módulo não corresponder ao vmlinux km. Por exemplo, a falha a seguir é uma falha típica que ocorre tempo de carregamento do módulo devido a uma incompatibilidade de CRC para o símbolo module_layout():

init: Loading module /lib/modules/kernel/.../XXX.ko with args ""
XXX: disagrees about version of symbol module_layout
init: Failed to insmod '/lib/modules/kernel/.../XXX.ko' with args ''

Usos do controle de versão de módulo

O controle de versões do módulo é útil pelos seguintes motivos:

  • O controle de versões do módulo detecta mudanças na visibilidade da estrutura de dados. Se os módulos alterar estruturas de dados opacas, ou seja, estruturas de dados que não fazem parte da KMI, eles se quebram após futuras mudanças na estrutura.

    Por exemplo, considere o fwnode no struct device. Este campo PRECISA ser opaco aos módulos para que eles não possam fazer alterações. campos de device->fw_node ou suposições sobre o tamanho dele.

    No entanto, se um módulo incluir <linux/fwnode.h> (direta ou indiretamente): o campo fwnode no struct device não será mais opaco para ele. A poderá fazer mudanças em device->fwnode->dev ou device->fwnode->ops. Esse cenário é problemático por vários motivos, declarado da seguinte maneira:

    • Ele pode quebrar as suposições do código do kernel principal sobre os componentes estruturas de dados.

    • Se uma futura atualização do kernel mudar o struct fwnode_handle (os dados tipo de fwnode), o módulo não funcionará mais com o novo kernel. Além disso, stgdiff não mostrará nenhuma diferença porque o módulo está corrompendo o KMI manipulando diretamente as estruturas de dados internas de maneira impossível apenas com a inspeção da representação binária.

  • Um módulo atual é considerado incompatível com o KMI quando carregado em uma data posterior por um novo kernel incompatível. O controle de versões do módulo adiciona uma verificação no ambiente de execução ao evitar o carregamento acidental de um módulo que não seja compatível com o KMI com o kernel. Essa verificação evita problemas de execução difíceis de depurar e falhas do kernel que podem resultantes de uma incompatibilidade não detectada no KMI.

Ativar o controle de versões do módulo evita todos esses problemas.

Verifique se há incompatibilidades de CRC sem inicializar o dispositivo

O stgdiff compara e relata incompatibilidades de CRC entre kernels com outros Diferenças de ABI.

Além disso, um build completo do kernel com CONFIG_MODVERSIONS ativado gera um Module.symvers como parte do processo de build normal. Este arquivo tem um linha para cada símbolo exportado pelo kernel (vmlinux) e pelos módulos. Cada consiste no valor do CRC, no nome do símbolo, no namespace do símbolo, nos atributos vmlinux ou o nome do módulo que está exportando o símbolo e o tipo de exportação (por exemplo, EXPORT_SYMBOL versus EXPORT_SYMBOL_GPL).

Você pode comparar os arquivos Module.symvers entre o build GKI e seu build para verificar diferenças de CRC nos símbolos exportados pelo vmlinux. Se houver é uma diferença de valor de CRC em qualquer símbolo exportado por vmlinux e que for usado por um dos módulos carregados no seu dispositivo, o módulo não carregar.

Se você não tem todos os artefatos de build, mas tem os arquivos vmlinux o kernel de GKI e o seu kernel, é possível comparar os valores de CRC para um determinado executando o seguinte comando nos dois kernels e comparando os saída:

nm <path to vmlinux>/vmlinux | grep __crc_<symbol name>

Por exemplo, o comando a seguir verifica o valor do CRC para o objeto module_layout. símbolo:

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

Resolver incompatibilidades de CRC

Use as etapas a seguir para resolver uma incompatibilidade de CRC ao carregar um módulo:

  1. Criar o kernel de GKI e o kernel do dispositivo usando o --kbuild_symtypes como mostrado no comando a seguir:

    tools/bazel run --kbuild_symtypes //common:kernel_aarch64_dist
    

    Esse comando gera um arquivo .symtypes para cada arquivo .o. Consulte KBUILD_SYMTYPES no Kleaf para mais detalhes.

    Para o Android 13 e versões anteriores, crie o kernel de GKI e o kernel do dispositivo adicionando KBUILD_SYMTYPES=1 ao comando que você use para criar o kernel, conforme mostrado no comando a seguir:

    KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
    

    Ao usar build_abi.sh,, a sinalização KBUILD_SYMTYPES=1 é definida implicitamente já.

  2. Encontre o arquivo .c em que o símbolo com incompatibilidade de CRC é exportado usando o seguinte comando:

    cd common && git grep EXPORT_SYMBOL.*module_layout
    kernel/module.c:EXPORT_SYMBOL(module_layout);
    
  3. O arquivo .c tem um arquivo .symtypes correspondente na GKI, e seu artefatos de build do kernel do dispositivo. Localize o arquivo .c usando o código abaixo. comandos:

    cd out/$BRANCH/common && ls -1 kernel/module.*
    kernel/module.o
    kernel/module.o.symversions
    kernel/module.symtypes
    

    Confira a seguir as características do arquivo .c:

    • O formato do arquivo .c é uma linha (possivelmente muito longa) por símbolo.

    • [s|u|e|etc]# no início da linha significa que o símbolo é do tipo de dados [struct|union|enum|etc]. Exemplo:

      t#bool typedef _Bool bool
      
    • Um prefixo # ausente no início da linha indica que o símbolo é uma função. Exemplo:

      find_module s#module * find_module ( const char * )
      
  4. Compare os dois arquivos e corrija todas as diferenças.

.

Caso 1: diferenças devido à visibilidade do tipo de dados

Se um kernel mantém um símbolo ou tipo de dados opaco aos módulos e o outro kernel não aparecer, essa diferença aparecerá entre os arquivos .symtypes dos dois kernels. O arquivo .symtypes de um dos kernels tem UNKNOWN de um símbolo, e o arquivo .symtypes do outro kernel tiver uma visualização expandida do símbolo ou tipo de dados.

Por exemplo, adicionar a seguinte linha ao include/linux/device.h no kernel causa incompatibilidades de CRC, e uma delas é para module_layout():

 #include <linux/fwnode.h>

Comparar o module.symtypes desse símbolo expõe o seguinte diferenças:

 $ diff -u <GKI>/kernel/module.symtypes <your kernel>/kernel/module.symtypes
  --- <GKI>/kernel/module.symtypes
  +++ <your kernel>/kernel/module.symtypes
  @@ -334,12 +334,15 @@
  ...
  -s#fwnode_handle struct fwnode_handle { UNKNOWN }
  +s#fwnode_reference_args struct fwnode_reference_args { s#fwnode_handle * fwnode ; unsigned int nargs ; t#u64 args [ 8 ] ; }
  ...

Se o kernel tiver um valor UNKNOWN e o kernel de GKI tiver a visualização expandida do símbolo (muito improvável), depois mesclar o kernel comum mais recente do Android nos seu kernel para que você esteja usando a base de kernel de GKI mais recente.

Na maioria dos casos, o kernel de GKI tem um valor UNKNOWN, mas ele tem o detalhes internos do símbolo devido a alterações feitas em seu kernel. Isso é porque um dos arquivos no kernel adicionou um #include que não está presente na kernel de GKI.

Muitas vezes, a correção apenas oculta o novo #include do genksyms.

#ifndef __GENKSYMS__
#include <linux/fwnode.h>
#endif

Caso contrário, para identificar o #include que causa a diferença, siga estas etapas:

  1. Abra o arquivo principal que define o símbolo ou tipo de dados que tem este diferença. Por exemplo, edite include/linux/fwnode.h para a struct fwnode_handle.

  2. Adicione o seguinte código na parte superior do arquivo principal:

    #ifdef CRC_CATCH
    #error "Included from here"
    #endif
    
  3. No arquivo .c do módulo que tem uma incompatibilidade de CRC, adicione o seguindo como a primeira linha antes de qualquer uma das linhas #include.

    #define CRC_CATCH 1
    
  4. Compile seu módulo. O erro de tempo de build resultante mostra a cadeia de arquivo principal #include que causou essa incompatibilidade de CRC. Exemplo:

    In file included from .../drivers/clk/XXX.c:16:`
    In file included from .../include/linux/of_device.h:5:
    In file included from .../include/linux/cpu.h:17:
    In file included from .../include/linux/node.h:18:
    .../include/linux/device.h:16:2: error: "Included from here"
    #error "Included from here"
    

    Um dos links nesta cadeia de #include se deve a uma alteração nas suas que está faltando no kernel de GKI.

  5. Identifique a mudança, reverta-a no kernel ou fazer o upload para a ACK e mescla-lo.

Caso 2: diferenças devido a alterações no tipo de dados

Se a incompatibilidade de CRC para um símbolo ou tipo de dados não se deve a uma diferença no visibilidade, ela será devido a alterações reais (adições, remoções ou alterações) o tipo de dados em si.

Por exemplo, fazer a seguinte alteração no seu kernel causa diversos erros de porque muitos símbolos são indiretamente afetados por esse tipo de alteração:

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
  --- a/include/linux/iommu.h
  +++ b/include/linux/iommu.h
  @@ -259,7 +259,7 @@ struct iommu_ops {
     void (*iotlb_sync)(struct iommu_domain *domain);
     phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
     phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain,
  -        dma_addr_t iova);
  +        dma_addr_t iova, unsigned long trans_flag);
     int (*add_device)(struct device *dev);
     void (*remove_device)(struct device *dev);
     struct iommu_group *(*device_group)(struct device *dev);

Uma incompatibilidade de CRC é para devm_of_platform_populate().

Se você comparar os arquivos .symtypes desse símbolo, ele poderá ficar assim:

 $ diff -u <GKI>/drivers/of/platform.symtypes <your kernel>/drivers/of/platform.symtypes
  --- <GKI>/drivers/of/platform.symtypes
  +++ <your kernel>/drivers/of/platform.symtypes
  @@ -399,7 +399,7 @@
  ...
  -s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t ) ; int
    ( * add_device ) ( s#device * ) ; ...
  +s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t , unsigned long ) ; int ( * add_device ) ( s#device * ) ; ...

Para identificar o tipo alterado, siga estas etapas:

  1. Encontre a definição do símbolo no código-fonte, geralmente em arquivos .h.

    • Para diferenças de símbolos entre o kernel e o kernel de GKI, faça o seguinte: Para encontrar a confirmação, execute o seguinte comando:
    git blame
    
    • Para símbolos excluídos (em que um símbolo é excluído de uma árvore e você também quiser excluí-lo na outra árvore), precisa encontrar a mudança que excluiu a linha. Use o seguinte comando na árvore em que a linha foi excluído:
    .
    git log -S "copy paste of deleted line/word" -- <file where it was deleted>
    
  2. Revise a lista de commits retornada para localizar a mudança ou exclusão. A a primeira confirmação é provavelmente a que você está procurando. Se não estiver, acesse pela lista até encontrar o commit.

  3. Depois de identificar a mudança, reverta-a no kernel ou fazer o upload no ACK e obtê-lo mesclado.